Skip to content

test: add query_executor unit tests#26

Merged
poyrazK merged 3 commits intomainfrom
test/query-executor-coverage
Apr 11, 2026
Merged

test: add query_executor unit tests#26
poyrazK merged 3 commits intomainfrom
test/query-executor-coverage

Conversation

@poyrazK
Copy link
Copy Markdown
Owner

@poyrazK poyrazK commented Apr 11, 2026

Summary

Add comprehensive unit tests for QueryExecutor covering the core query execution engine:

  • Constructor and setup methods - basic initialization
  • DDL - CREATE/DROP TABLE with various column types
  • DML - INSERT single/multiple rows, UPDATE, DELETE with conditions
  • SELECT - projections, WHERE filtering, ORDER BY, LIMIT/OFFSET
  • Aggregates - COUNT, SUM, GROUP BY
  • Transactions - BEGIN, COMMIT, ROLLBACK with proper isolation
  • Indexes - CREATE/DROP INDEX
  • JOINs - INNER and LEFT joins
  • Error handling - invalid SQL parsing

Test Plan

  • All 41 query_executor_tests pass
  • All 24 test suites pass via ctest
  • CI builds pass

Part of ongoing coverage improvement effort.

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for query execution including DDL operations, data manipulation, joins, and transaction handling.

Add comprehensive unit tests for QueryExecutor covering:
- Constructor and setup methods
- CREATE/DROP TABLE with various types
- INSERT single/multiple rows with column lists
- SELECT with projections, WHERE, ORDER BY, LIMIT/OFFSET
- Aggregates: COUNT, SUM, GROUP BY
- UPDATE and DELETE with conditions
- Transaction control: BEGIN, COMMIT, ROLLBACK
- Transaction isolation (MVCC)
- CREATE/DROP INDEX
- JOIN operations (inner, left)
- Invalid SQL handling

Part of ongoing coverage improvement effort.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

Warning

Rate limit exceeded

@poyrazK has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 0 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 19 minutes and 0 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 78bf7354-3509-4a0b-90ad-face773ed57b

📥 Commits

Reviewing files that changed from the base of the PR and between b6298bd and 20708a2.

📒 Files selected for processing (1)
  • tests/query_executor_tests.cpp
📝 Walkthrough

Walkthrough

A new comprehensive GoogleTest suite is added for QueryExecutor, exercising DDL, DML, queries, joins, and transactions end-to-end. The test file is registered in the CMake build system via the existing add_cloudsql_test macro.

Changes

Cohort / File(s) Summary
CMake Build Configuration
CMakeLists.txt
Registers new test executable query_executor_tests using add_cloudsql_test macro to run the newly created test file with CTest.
QueryExecutor Test Suite
tests/query_executor_tests.cpp
Comprehensive GoogleTest suite (466 lines) with TestEnvironment fixture wiring StorageManager, BufferPoolManager, Catalog, LockManager, TransactionManager, and QueryExecutor. Tests cover DDL (CREATE/DROP TABLE/INDEX), DML (INSERT/UPDATE/DELETE), SELECT operations (filtering, ordering, limits, aggregates, GROUP BY), joins (INNER/LEFT), transactions (BEGIN/COMMIT/ROLLBACK with isolation validation), and error handling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Possibly related PRs

Poem

🐰 A warren of tests now springs to life,
With SQL parsed and executors rife!
From DDL to transactions' dance,
Each query gets a thorough chance. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'test: add query_executor unit tests' directly and clearly summarizes the main change: adding unit tests for the QueryExecutor component. It is concise, specific, and accurately represents the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/query-executor-coverage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/query_executor_tests.cpp (1)

73-75: Remove or simplify unused test helper.

create_test_table (Line 73) does not use name and is currently unused in this suite. Consider removing it or trimming the signature.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/query_executor_tests.cpp` around lines 73 - 75, The helper
create_test_table currently ignores its name parameter and isn't used elsewhere;
either remove the function entirely or simplify its signature to only accept
what it uses (e.g., change create_test_table(QueryExecutor& exec, const char*
schema_sql) and update any callers to match) and, if kept, rename it to reflect
its behavior (e.g., execute_schema or apply_schema) so unused parameter warnings
are eliminated; search for create_test_table and execute_sql to locate and
adjust or delete the helper accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/query_executor_tests.cpp`:
- Around line 283-293: The test SelectNonExistentColumn in QueryExecutorTests
currently accepts both success and failure which masks regressions; update the
test to assert the engine's strict contract by replacing the conditional branch
that checks res.success() with a single expectation (use
EXPECT_FALSE(res.success())) so that selecting a non-existent column via
execute_sql(env.executor, "SELECT nonexistent FROM test_table") must fail;
remove the res.row_count() assertion and any alternate-success handling to make
the test deterministic.
- Around line 66-70: The helper execute_sql should guard against a null parse
result before dereferencing *stmt: after calling
Parser(std::move(lexer)).parse_statement(), check whether stmt is non-null and
handle the failure (e.g., return a QueryResult representing the parse error or
throw a descriptive exception) instead of dereferencing; update execute_sql
accordingly so it never calls exec.execute(*stmt) when stmt is null, referencing
the functions Lexer, Parser::parse_statement, and QueryExecutor::execute to
locate the change.
- Around line 456-463: The DivisionByZero test currently calls SUCCEED() and
doesn't assert any behavior; update TEST_F(QueryExecutorTests, DivisionByZero)
to assert the executor's actual contract using the previously captured res from
execute_sql: either assert an error (e.g., ASSERT_TRUE/res.isError() and check
error text) if division-by-zero should fail, or assert the returned value(s)
(e.g., inspect res.rows/res.columns and compare the scalar to the expected
sentinel like NULL/INF/SQL NULL) if the semantics define a value; remove
SUCCEED() and use execute_sql, res, and the test framework's ASSERT/EXPECT
helpers to make the intended outcome explicit.

---

Nitpick comments:
In `@tests/query_executor_tests.cpp`:
- Around line 73-75: The helper create_test_table currently ignores its name
parameter and isn't used elsewhere; either remove the function entirely or
simplify its signature to only accept what it uses (e.g., change
create_test_table(QueryExecutor& exec, const char* schema_sql) and update any
callers to match) and, if kept, rename it to reflect its behavior (e.g.,
execute_schema or apply_schema) so unused parameter warnings are eliminated;
search for create_test_table and execute_sql to locate and adjust or delete the
helper accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1367a13c-4fc8-4150-ad52-8082af6b363b

📥 Commits

Reviewing files that changed from the base of the PR and between 267a75a and b6298bd.

📒 Files selected for processing (2)
  • CMakeLists.txt
  • tests/query_executor_tests.cpp

Comment on lines +283 to +293
TEST_F(QueryExecutorTests, SelectNonExistentColumn) {
TestEnvironment env;
execute_sql(env.executor, "CREATE TABLE test_table (id INT)");
// Note: Some implementations may succeed even with non-existent column
// This test documents actual behavior
const auto res = execute_sql(env.executor, "SELECT nonexistent FROM test_table");
// Either success with empty/error is acceptable
if (res.success()) {
EXPECT_EQ(res.row_count(), 0U);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

This test currently masks regressions by accepting both outcomes.

Line 289 allows either success or failure, so a behavior change won’t fail CI. Please assert one expected contract for this engine (preferably EXPECT_FALSE(res.success()) for unknown columns) and keep it strict.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/query_executor_tests.cpp` around lines 283 - 293, The test
SelectNonExistentColumn in QueryExecutorTests currently accepts both success and
failure which masks regressions; update the test to assert the engine's strict
contract by replacing the conditional branch that checks res.success() with a
single expectation (use EXPECT_FALSE(res.success())) so that selecting a
non-existent column via execute_sql(env.executor, "SELECT nonexistent FROM
test_table") must fail; remove the res.row_count() assertion and any
alternate-success handling to make the test deterministic.

- execute_sql: Guard against null parse result to avoid dereferencing
- Remove unused create_test_table helper function
- SelectNonExistentColumn: Assert actual behavior (success with empty result)
- DivisionByZero: Assert success and row_count to verify query execution
@poyrazK poyrazK merged commit b7fb93d into main Apr 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant