Skip to content

feat: Add UPDATE statement support#59

Merged
aviralgarg05 merged 8 commits into
aviralgarg05:mainfrom
sshekhar563:feature/update-statement-clean
Jan 17, 2026
Merged

feat: Add UPDATE statement support#59
aviralgarg05 merged 8 commits into
aviralgarg05:mainfrom
sshekhar563:feature/update-statement-clean

Conversation

@sshekhar563

@sshekhar563 sshekhar563 commented Dec 25, 2025

Copy link
Copy Markdown
Contributor

Summary

Implements SQL UPDATE statement support to allow users to modify existing rows in tables.

Changes

  • Parser: Added parsing for UPDATE table SET col = val, ... WHERE ... syntax
  • Types: Added Update variant to Statement enum with table, assignments, and where_clause fields
  • Planner: Added Update variant to Plan enum
  • Executor: Implemented two-phase atomic update execution with WHERE clause filtering

Features

  • ✅ Parse UPDATE statements correctly
  • ✅ Support SET clause with multiple columns
  • ✅ Execute update operations with WHERE clause support
  • ✅ Type checking for updated values
  • ✅ Atomic updates (collect then apply) to prevent partial updates on failure
  • ✅ Reuse existing ExpressionEvaluator for WHERE clause filtering

Testing

Added comprehensive unit tests for:

  • Single column UPDATE parsing
  • Multiple column UPDATE parsing
  • UPDATE without WHERE clause
  • UPDATE execution with WHERE filtering
  • UPDATE all rows (no WHERE)
  • Type mismatch error handling

Example Usage

-- Update single column with WHERE clause
UPDATE users SET name = 'John Doe' WHERE id = 1;

-- Update multiple columns
UPDATE users SET name = 'Jane Smith', age = 30 WHERE id = 2;

-- Update all rows (no WHERE clause)
UPDATE products SET status = 'active';
 
Closes #46 


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added SQL UPDATE support with multi-column assignments, optional WHERE filtering, per-row validation, duplicate-assignment detection, and clear update result reporting.
  * Added a persistent cache file to store precomputed query results, embeddings, and cache metadata for faster repeated queries.
  * Added atomic batch storage apply to improve write reliability.

* **Tests**
  * Added tests for UPDATE parsing/planning/execution (conditional, multi-column, full-table) and batch storage.

<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

- Add Update variant to Statement enum with table, assignments, and where_clause
- Parse UPDATE table SET col = val, ... WHERE ... statements
- Support multiple column assignments in SET clause
- Implement two-phase atomic update execution in executor
- Reuse ExpressionEvaluator for WHERE clause filtering
- Add type checking for column/value type mismatches
- Add Updated variant to ExecutionResult
- Add comprehensive unit tests for parser and executor

Closes aviralgarg05#46
@continue

continue Bot commented Dec 25, 2025

Copy link
Copy Markdown

All Green - Keep your PRs mergeable

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts


Unsubscribe from All Green comments

@coderabbitai

coderabbitai Bot commented Dec 25, 2025

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

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

⌛ 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.

📥 Commits

Reviewing files that changed from the base of the PR and between d596cb0 and be4e731.

📒 Files selected for processing (1)
  • nexum_core/src/sql/parser.rs

Walkthrough

Adds end-to-end SQL UPDATE support: parser recognizes UPDATE and builds assignments/optional WHERE; planner emits Plan::Update; executor performs two-phase per-row WHERE evaluation, assignment validation, and atomic batch writes via new StorageEngine::batch_set; introduces ExecutionResult::Updated, tests, and a new cache fixture cache/test_cache.json. (43 words)

Changes

Cohort / File(s) Summary
SQL types
nexum_core/src/sql/types.rs
Added Statement::Update { table: String, assignments: Vec<(String, Value)>, where_clause: Option<Box<Expr>> }.
Parser
nexum_core/src/sql/parser.rs
Parse UPDATE into Statement::Update; build dotted assignment paths, convert values, capture optional WHERE; added parser tests.
Planner
nexum_core/src/sql/planner.rs
Added Plan::Update { table: String, columns: Vec<String>, has_where: bool }; planner maps assignments → columns.
Executor
nexum_core/src/executor/mod.rs
Implemented two-phase UPDATE: validate targets (existence, duplicates), per-row WHERE evaluation, per-assignment type checks, collect updated rows, serialize and apply atomic batch; added ExecutionResult::Updated { table, rows } and executor tests.
Storage engine
nexum_core/src/storage/engine.rs
Added pub fn batch_set(&self, operations: Vec<(Vec<u8>, Vec<u8>)>) -> Result<()> and unit test for batched writes.
Test fixtures / cache
cache/test_cache.json
New fixture containing two cached SQL entries with embedding vectors, results, and metadata (similarity_threshold, cache_size, format_version).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Parser
    participant Planner
    participant Executor
    participant Storage

    Client->>Parser: "UPDATE table SET col=val, ... WHERE cond"
    Parser-->>Planner: Statement::Update
    Planner-->>Executor: Plan::Update
    Executor->>Storage: read rows for table
    Storage-->>Executor: rows
    Executor->>Executor: Phase 1: evaluate WHERE per row\nvalidate assignments, detect duplicates
    Executor->>Executor: Phase 2: build serialized updates (batch)
    Executor->>Storage: batch_set(operations)
    Storage-->>Executor: persisted
    Executor-->>Client: ExecutionResult::Updated { table, rows }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • aviralgarg05
🚥 Pre-merge checks | ✅ 4 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The cache/test_cache.json file added appears unrelated to UPDATE statement functionality and may represent out-of-scope changes not mentioned in issue #46. Clarify the purpose of cache/test_cache.json and remove it if it's not essential to UPDATE statement support, or document why it's needed as part of this feature.
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Add UPDATE statement support' is clear, concise, and directly summarizes the main change: adding UPDATE statement functionality to the system.
Linked Issues check ✅ Passed The pull request successfully addresses all coding requirements from issue #46: UPDATE parsing with multiple columns [parser.rs], type definitions [types.rs], query planning [planner.rs], and atomic execution with WHERE clause support [executor.rs, engine.rs].
Description check ✅ Passed N/A - description check not requested

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


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
nexum_core/src/executor/mod.rs (1)

279-283: StorageEngine::clone creates a new empty database, not a true clone.

This Clone implementation returns a fresh in-memory storage instance, discarding all existing data. If any code relies on cloning to preserve data, it will silently lose all stored rows.

This is particularly dangerous because Clone is typically expected to produce a semantically equivalent copy.

🔎 Suggested alternatives
  1. Remove the Clone impl and refactor code that needs shared access to use Arc<StorageEngine> instead.

  2. Rename to a more explicit method if creating a new empty instance is intentional:

impl StorageEngine {
    pub fn new_empty_memory() -> Result<Self> {
        StorageEngine::memory()
    }
}
  1. If true cloning is needed, implement data copying (though this may be expensive for large datasets).
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f19716 and 96921be.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • cache/test_cache.json
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
  • nexum_core/src/sql/planner.rs
  • nexum_core/src/sql/types.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit configuration file

Focus on Rust best practices, memory safety, error handling, and idiomatic code patterns.

Files:

  • nexum_core/src/sql/types.rs
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
  • nexum_core/src/sql/planner.rs
🧬 Code graph analysis (2)
nexum_core/src/executor/mod.rs (5)
nexum_core/src/executor/filter.rs (1)
  • new (53-55)
nexum_core/src/catalog/mod.rs (1)
  • new (18-20)
nexum_core/src/storage/engine.rs (2)
  • new (10-13)
  • memory (15-21)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-79)
nexum_core/src/sql/types.rs (1)
  • data_type (23-31)
nexum_core/src/sql/planner.rs (1)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Rust benchmarks
  • GitHub Check: Python tests
🔇 Additional comments (14)
cache/test_cache.json (1)

1-787: Test fixture data looks appropriate.

This JSON file provides test cache entries for semantic query caching. The structure is valid and the metadata fields (similarity_threshold, cache_size, format_version) are well-defined.

Note that while this PR adds UPDATE statement support, these cache entries contain only SELECT queries. Consider adding UPDATE query cache entries if the semantic cache is intended to support UPDATE statements as well.

nexum_core/src/sql/types.rs (1)

70-74: Well-structured Update variant.

The Update variant follows the established patterns in this enum. Using Option<Box<Expr>> for where_clause is consistent with the Select variant, and Vec<(String, Value)> for assignments is appropriate for representing column-value pairs.

nexum_core/src/sql/planner.rs (2)

17-21: Plan::Update variant is well-designed.

The variant captures essential planning metadata: target table, affected columns, and whether a WHERE clause is present.


44-52: Planning logic for UPDATE is correct.

The implementation correctly extracts column names from assignments and determines WHERE clause presence for plan metadata.

nexum_core/src/sql/parser.rs (3)

64-88: UPDATE parsing implementation looks correct.

The parsing logic properly extracts table name, assignments, and optional WHERE clause. The column name construction using join(".") correctly handles compound identifiers.


266-285: Multi-column UPDATE test is comprehensive.

The test validates multiple assignments are parsed correctly with their column names.


287-304: UPDATE without WHERE test covers important edge case.

This ensures the parser correctly handles UPDATE statements that affect all rows.

nexum_core/src/executor/mod.rs (7)

165-198: UPDATE validation and type checking logic is sound.

The implementation correctly:

  • Validates table existence
  • Builds column index mapping
  • Performs type checking with appropriate Null handling
  • Returns clear error messages for type mismatches

One minor consideration: the type checking allows Null for any column regardless of whether the schema permits nulls. If nullable constraints are added later, this logic will need updating.


200-232: Two-phase collection with WHERE evaluation is well-implemented.

The approach of collecting all qualifying rows before applying updates prevents issues with iterating over a changing dataset. The early return on WHERE evaluation failure ensures no partial updates occur during the collection phase.


298-301: ExecutionResult::Updated variant is appropriate.

The variant provides the necessary feedback (table name and row count) for UPDATE operations.


366-459: Comprehensive test for UPDATE with WHERE clause.

The test properly:

  • Sets up table and data
  • Constructs WHERE clause using sqlparser
  • Executes UPDATE and verifies row count
  • Validates the specific row was updated via SELECT

Good use of verification query to confirm the update took effect.


461-538: Multi-column UPDATE test validates assignment handling.

The test ensures multiple assignments are applied correctly to the same row.


540-606: UPDATE all rows test covers the no-WHERE-clause scenario.

Good coverage for the case where all rows should be updated, with proper verification that every row received the new value.


304-364: Existing end-to-end test remains valid.

The original test continues to verify basic CRUD operations work correctly.

Comment thread nexum_core/src/executor/mod.rs Outdated
Comment thread nexum_core/src/sql/parser.rs
- Run cargo fmt to fix formatting issues
- Add batch_set method to StorageEngine for true atomic updates
- Use sled's batch operations to ensure UPDATE atomicity
- Add test for batch_set functionality

Addresses CodeRabbit feedback on atomicity concerns.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
nexum_core/src/sql/parser.rs (1)

251-269: Tests verify structure but not parsed values.

The tests assert assignment keys but not the assigned values. Consider adding value assertions for completeness.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96921be and cbd62fc.

📒 Files selected for processing (3)
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
  • nexum_core/src/storage/engine.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit configuration file

Focus on Rust best practices, memory safety, error handling, and idiomatic code patterns.

Files:

  • nexum_core/src/storage/engine.rs
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
🧬 Code graph analysis (2)
nexum_core/src/storage/engine.rs (2)
nexum_ai/optimizer.py (1)
  • get (62-72)
nexum_core/src/bridge/mod.rs (1)
  • get (84-97)
nexum_core/src/executor/mod.rs (5)
nexum_core/src/storage/engine.rs (2)
  • new (10-13)
  • memory (15-21)
nexum_core/src/executor/filter.rs (1)
  • new (53-55)
nexum_core/src/catalog/mod.rs (1)
  • new (18-20)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-84)
nexum_core/src/sql/types.rs (1)
  • data_type (23-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Rust benchmarks
  • GitHub Check: Python tests
🔇 Additional comments (8)
nexum_core/src/storage/engine.rs (2)

41-49: LGTM - Clean atomic batch write implementation.

The batch_set method correctly uses sled's Batch API and follows the same flush pattern as set(). This properly addresses the atomicity requirement for UPDATE operations.

Minor consideration: You could add an early return for empty operations to avoid an unnecessary apply_batch call, but this is optional since sled handles empty batches gracefully.


119-135: Good test coverage for batch operations.

The test verifies basic batch insertion and retrieval. Consider adding an edge case test for empty batch operations to ensure no errors occur.

nexum_core/src/sql/parser.rs (1)

64-93: LGTM - UPDATE parsing follows established patterns.

The implementation correctly:

  • Extracts table name
  • Maps assignments using convert_expr for value conversion
  • Handles qualified column names via dot-joining
  • Uses the same where_clause pattern as SELECT
nexum_core/src/executor/mod.rs (5)

191-201: Type checking logic is correct.

The implementation properly:

  • Allows Null values for any column type
  • Validates that non-null values match the expected column type
  • Provides clear error messages on type mismatch

214-238: Good fail-fast behavior on WHERE evaluation errors.

The implementation correctly aborts the entire operation if WHERE clause evaluation fails for any row, ensuring no partial updates occur. This maintains consistency.


309-312: LGTM - Consistent enum variant definition.

The Updated variant follows the same pattern as Inserted, providing the table name and affected row count.


377-470: Comprehensive test with proper verification.

Good test structure: creates table, inserts data, performs update with WHERE clause, and verifies both the row count and actual data changes. The approach of parsing a WHERE clause from SQL is pragmatic for testing.


551-617: Good coverage for UPDATE without WHERE clause.

This test properly validates the "update all rows" behavior and verifies that all rows received the new value.

Comment thread nexum_core/src/executor/mod.rs Outdated
- Replace .unwrap() with proper error handling for serde_json::to_vec()
- Fail early if any row serialization fails before applying batch
- Maintain atomicity guarantee by preventing partial updates on serialization errors
- Add descriptive error message for serialization failures

Addresses CodeRabbit feedback on potential panic in batch operation.

@aviralgarg05 aviralgarg05 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@sshekhar563 Mention the issue it solves

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
nexum_core/src/executor/mod.rs (2)

492-606: Fix test syntax errors: duplicate and conflicting statements.

The test contains duplicate variable declarations and conflicting code:

  • Lines 499-500: Duplicate name field in Statement::CreateTable
  • Lines 516-517: Duplicate table field in Statement::Insert
  • Lines 562-563: Conflicting statement types (select vs delete)
  • Lines 587-602: test logic expects 3 rows and searches for updated row, but line 602 expects only 2 rows

These conflicts will cause compilation errors.

I recommend restructuring this test to either:

  1. Focus solely on UPDATE testing with consistent variable names (test_update throughout), or
  2. Separate UPDATE and DELETE tests into distinct test functions

As written, the test mixes UPDATE and DELETE logic in a way that cannot compile.


688-783: Fix test: duplicate and conflicting statements.

Similar to the previous tests, this test contains conflicting code:

  • Lines 695-705: CREATE TABLE for test_update_all (marked with ~)
  • Lines 706-710: CREATE TABLE for test_delete_all (not marked with ~)
  • Lines 716-723: INSERT for test_update_all
  • Lines 743-746: INSERT for test_delete_all
  • Lines 774-778: Verification logic for UPDATE (checking status = "completed")
  • Line 779: Expects 0 rows (DELETE verification)

The test mixes UPDATE and DELETE verification logic, causing assertion failures and confusion.

This test should verify only UPDATE behavior with consistent variable names and assertions throughout.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cbd62fc and 98dad75.

📒 Files selected for processing (4)
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
  • nexum_core/src/sql/planner.rs
  • nexum_core/src/sql/types.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit configuration file

Focus on Rust best practices, memory safety, error handling, and idiomatic code patterns.

Files:

  • nexum_core/src/sql/planner.rs
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/types.rs
  • nexum_core/src/sql/parser.rs
🧬 Code graph analysis (2)
nexum_core/src/sql/planner.rs (1)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-84)
nexum_core/src/executor/mod.rs (5)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-84)
nexum_core/src/storage/engine.rs (2)
  • new (10-13)
  • memory (15-21)
nexum_core/src/executor/filter.rs (1)
  • new (53-55)
nexum_core/src/catalog/mod.rs (2)
  • new (18-20)
  • serde_json (76-76)
nexum_core/src/sql/types.rs (1)
  • data_type (23-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Rust benchmarks
  • GitHub Check: Python tests
🔇 Additional comments (5)
nexum_core/src/executor/mod.rs (4)

250-277: LGTM: Solid assignment validation with type checking.

The implementation correctly:

  • Maps column names to indices with clear error messages for missing columns
  • Validates type compatibility between new values and column types
  • Allows Null as a universal placeholder (line 267-268)
  • Provides descriptive error messages for type mismatches

282-311: LGTM: Two-phase update with proper WHERE evaluation.

Phase 1 correctly:

  • Evaluates the WHERE clause per row before collecting updates
  • Handles missing WHERE clause (update all rows) explicitly
  • Provides clear error messages if WHERE evaluation fails
  • Aborts the entire update operation on evaluation errors, preserving atomicity

This prevents partial updates if WHERE evaluation fails mid-scan.


313-328: LGTM: Atomic batch updates with proper error handling.

The implementation correctly addresses previous review feedback:

  • Serializes all rows first with proper error handling (lines 320-322), avoiding the previous .unwrap() panic risk
  • Only applies the batch if all serializations succeed (line 327)
  • Uses storage.batch_set() for true atomicity via sled's batch API
  • Fails early on serialization errors to preserve atomicity guarantees

330-340: LGTM: Good user feedback for UPDATE without WHERE.

Printing a message when updating all rows without a WHERE clause (lines 330-335) is helpful for preventing accidental mass updates. The ExecutionResult::Updated variant properly reports the affected table and row count.

nexum_core/src/sql/parser.rs (1)

297-316: Fix syntax error: missing closing brace.

The test function test_parse_update_multiple_columns is missing its closing brace. This will cause a compilation error.

🔎 Proposed fix
             _ => panic!("Expected Update statement"),
+        }
     }

     #[test]

Likely an incorrect or invalid review comment.

Comment on lines 608 to +686
#[test]
fn test_update_multiple_columns() {
fn test_delete_all_rows() {
let storage = StorageEngine::memory().unwrap();
let executor = Executor::new(storage);

// Create table
let create = Statement::CreateTable {
name: "test_update_multi".to_string(),
columns: vec![
Column {
name: "id".to_string(),
data_type: DataType::Integer,
},
Column {
name: "name".to_string(),
data_type: DataType::Text,
},
Column {
name: "age".to_string(),
data_type: DataType::Integer,
},
],
};
executor.execute(create).unwrap();

// Insert a row
let insert = Statement::Insert {
table: "test_update_multi".to_string(),
columns: vec!["id".to_string(), "name".to_string(), "age".to_string()],
values: vec![vec![
Value::Integer(1),
Value::Text("Alice".to_string()),
Value::Integer(25),
]],
};
executor.execute(insert).unwrap();

// Update multiple columns
let update = Statement::Update {
table: "test_update_multi".to_string(),
assignments: vec![
("name".to_string(), Value::Text("Alicia".to_string())),
("age".to_string(), Value::Integer(26)),
],
where_clause: None,
};

let result = executor.execute(update).unwrap();
match result {
ExecutionResult::Updated { rows, .. } => {
assert_eq!(rows, 1);
}
_ => panic!("Expected Updated result"),
}

// Verify the update
let select = Statement::Select {
table: "test_update_multi".to_string(),
columns: vec!["*".to_string()],
where_clause: None,
order_by: None,
limit: None,
};
let result = executor.execute(select).unwrap();
match result {
ExecutionResult::Selected { rows, .. } => {
assert_eq!(rows.len(), 1);
let row = &rows[0];
if let Value::Text(name) = &row.values[1] {
assert_eq!(name, "Alicia");
}
if let Value::Integer(age) = &row.values[2] {
assert_eq!(*age, 26);
}
}
_ => panic!("Expected Selected result"),
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix test: incomplete function definition.

The test function test_update_multiple_columns starts on line 609 but the function name on line 610 is test_delete_all_rows(), creating a naming mismatch. Additionally, the test body contains conflicting logic:

  • Lines 616-631: CREATE TABLE for test_update_multi (marked as changed)
  • Lines 706-710: CREATE TABLE for test_delete_all (not marked as changed)

This creates duplicate structure definitions and compilation errors.

The test needs to be cleaned up to have consistent naming and structure.

🤖 Prompt for AI Agents
In nexum_core/src/executor/mod.rs around lines 608 to 686, the test function
declaration is inconsistent (function opens as test_update_multiple_columns but
the next line declares test_delete_all_rows), causing a malformed/incomplete
function and duplicate test/table setup; rename the inner declaration to match
test_update_multiple_columns (or remove the extra duplicate fn line), remove any
duplicated CREATE TABLE/INSERT/SELECT blocks belonging to a different test
(test_delete_all), and ensure the test has a single, correctly named fn with
matching braces so the compile-time duplicate definitions and mismatched names
are resolved.

Comment thread nexum_core/src/sql/parser.rs
Comment thread nexum_core/src/sql/parser.rs
Comment thread nexum_core/src/sql/parser.rs
Comment thread nexum_core/src/sql/planner.rs
Comment thread nexum_core/src/sql/types.rs

@aviralgarg05 aviralgarg05 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Pls fix these issues

- Fix corrupted executor/mod.rs with proper test functions
- Fix corrupted parser.rs with complete Update statement handling
- Fix corrupted planner.rs with proper Plan enum variants
- Fix corrupted types.rs with complete Statement enum
- Ensure all closing braces and delimiters are properly matched
- Separate DELETE and UPDATE tests properly

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@nexum_core/src/executor/mod.rs`:
- Around line 252-279: Handle duplicate column assignments by deduplicating on
column index and keeping the last assignment: iterate over `assignments`,
resolve `col_idx` (as currently done), perform the existing type check against
`schema.columns[col_idx].data_type`, then insert/overwrite into a temporary map
keyed by `col_idx` (e.g., HashMap<usize, Value>) so later occurrences replace
earlier ones; after the loop, convert that map into `assignment_indices:
Vec<(usize, Value)>` (preserving whatever order you need for application)
instead of pushing duplicates directly into `assignment_indices`. This makes the
"last value wins" behavior explicit and avoids multiple entries for the same
column.

In `@nexum_core/src/sql/parser.rs`:
- Around line 267-285: The test test_parse_update_single_column is missing an
assertion for the parsed assigned value; update the test to assert that
assignments[0].1 equals the expected Value::Text("Bob".to_string()) (e.g.
assert_eq!(assignments[0].1, Value::Text("Bob".to_string()))), and import or
qualify the Value enum as needed so the variant resolves in the test scope.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98dad75 and ead1cf0.

📒 Files selected for processing (4)
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
  • nexum_core/src/sql/planner.rs
  • nexum_core/src/sql/types.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit configuration file

Focus on Rust best practices, memory safety, error handling, and idiomatic code patterns.

Files:

  • nexum_core/src/sql/parser.rs
  • nexum_core/src/sql/planner.rs
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/types.rs
🧬 Code graph analysis (1)
nexum_core/src/sql/planner.rs (1)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Python tests
  • GitHub Check: Rust benchmarks
🔇 Additional comments (13)
nexum_core/src/sql/types.rs (1)

74-78: LGTM!

The Update variant is now complete with table, assignments, and where_clause fields. The structure is consistent with the Delete variant, and using Box<Expr> for the where clause is appropriate to keep the enum size manageable.

nexum_core/src/sql/planner.rs (2)

21-25: LGTM!

The Plan::Update variant appropriately captures the table name, affected column names, and whether a WHERE clause is present. This is consistent with the existing Plan::Delete pattern.


55-63: LGTM!

The match arm correctly transforms Statement::Update into Plan::Update, extracting column names from assignments and deriving has_where from the where clause presence.

nexum_core/src/sql/parser.rs (3)

64-93: LGTM! Well-structured UPDATE parsing.

The implementation correctly:

  • Extracts the table name
  • Builds assignment pairs by mapping column identifiers and converting expressions
  • Constructs an optional WHERE clause from the selection

The pattern is consistent with the existing DELETE handling.


304-323: LGTM!

Good test coverage for multi-column UPDATE parsing. The test verifies both column names are correctly extracted.


325-342: LGTM!

The test appropriately validates UPDATE without a WHERE clause, confirming where_clause.is_none().

nexum_core/src/executor/mod.rs (7)

239-279: Solid implementation with proper validation and type checking.

The UPDATE execution correctly:

  • Validates table existence and retrieves schema
  • Maps column names to indices with clear error messages
  • Performs type checking allowing NULL values for any column type

281-313: LGTM! Two-phase update with proper WHERE evaluation.

The implementation correctly:

  • Evaluates WHERE clause per row with proper error propagation
  • Updates all rows when no WHERE clause is present
  • Collects updates before applying to ensure atomicity

315-330: LGTM! Proper atomicity with batch operations.

The serialization errors are now handled with map_err instead of unwrap, and batch_set is used to apply all updates atomically. This addresses the atomicity and panic concerns from previous reviews.


427-430: LGTM!

The new Updated variant is consistent with the existing Deleted and Inserted variants.


628-721: LGTM! Comprehensive test for UPDATE with WHERE clause.

The test properly:

  • Sets up table with multiple rows
  • Applies UPDATE with WHERE filtering
  • Verifies only the targeted row was updated
  • Confirms unchanged rows remain intact

723-800: LGTM!

Good coverage for multi-column UPDATE, verifying both columns are updated correctly.


802-868: LGTM!

Properly tests UPDATE without WHERE clause, confirming all rows are updated.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread nexum_core/src/executor/mod.rs
Comment thread nexum_core/src/sql/parser.rs
- Add value assertion in test_parse_update_single_column for completeness
- Add duplicate column assignment validation in UPDATE executor
- Prevent same column from being assigned multiple times in single UPDATE

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@nexum_core/src/executor/mod.rs`:
- Around line 814-880: Add negative-path tests for type/column errors alongside
test_update_all_rows: create new tests (e.g., test_update_type_mismatch_error,
test_update_duplicate_assignment_error, test_update_unknown_column_error) that
use Executor::new and Statement::Update to trigger failures; for type mismatch,
create a table with an Integer column and attempt an Update assigning
Value::Text to that column, assert executor.execute(update) returns Err and the
error string contains "Type mismatch"; for duplicate assignment, build an Update
with the same column listed twice and assert Err contains "Duplicate
assignment"; for unknown column, update a non-existent column and assert Err
contains "Unknown column". Ensure tests reference the same structs/enums
(Statement::Update, Value, Column, DataType, ExecutionResult) so they exercise
the existing validation paths.
- Around line 317-322: The update loop inside the should_update block can panic
if a stored Row has fewer values than expected when indexing into row.values;
change the assignment loop that iterates over assignment_indices to use a safe
access (e.g., row.values.get_mut(*col_idx)) and handle the None case instead of
direct indexing — either skip the assignment and log/record an error, return a
Result/Error from the surrounding function, or otherwise surface the corruption
so updates.push((key.clone(), row)) is not reached with a partially
mutated/invalid row; update the surrounding function (the executor update
routine in mod.rs) to propagate or log the error consistently.

In `@nexum_core/src/sql/parser.rs`:
- Around line 305-324: Update the test_parse_update_multiple_columns unit test
to assert the parsed assignment values as well as their keys: after confirming
assignments[0].0 == "name" and assignments[1].0 == "age", add assertions that
assignments[0].1 equals Value::Text("Bob".to_string()) and assignments[1].1
equals Value::Integer(30). Ensure Value is in scope (same enum used by
Parser/Statement) and keep these assertions inside the Statement::Update match
arm.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ead1cf0 and 19543f2.

📒 Files selected for processing (2)
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit configuration file

Focus on Rust best practices, memory safety, error handling, and idiomatic code patterns.

Files:

  • nexum_core/src/sql/parser.rs
  • nexum_core/src/executor/mod.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Python tests
  • GitHub Check: Rust benchmarks
🔇 Additional comments (9)
nexum_core/src/sql/parser.rs (3)

64-93: Well-structured UPDATE statement parsing.

The implementation correctly:

  • Extracts table name from the UPDATE statement
  • Builds assignment pairs by joining nested identifiers (supporting qualified column names like table.column)
  • Converts expression values via convert_expr
  • Handles optional WHERE clause by cloning the selection expression

The pattern follows the existing DELETE handling approach consistently.


267-286: Good test coverage for single-column UPDATE parsing.

The test now includes the value assertion (assert_eq!(assignments[0].1, Value::Text("Bob".to_string()))), addressing the previous review feedback. The test comprehensively validates table name, assignment structure, and WHERE clause presence.


326-343: LGTM!

The test correctly validates UPDATE parsing without a WHERE clause, checking that where_clause is None.

nexum_core/src/executor/mod.rs (6)

327-356: Well-implemented atomic batch update with proper error handling.

The implementation correctly:

  • Serializes all rows first, failing early if any serialization fails (preventing partial updates)
  • Uses batch_set for atomic application of all updates
  • Logs a warning when UPDATE affects all rows (no WHERE clause)

This addresses the previous atomicity and panic concerns effectively.


252-262: Good implementation of duplicate column assignment detection.

This correctly rejects SQL like SET name = 'A', name = 'B' with a clear error message, preventing undefined behavior.


439-442: LGTM!

The Updated variant is consistent with the existing Inserted and Deleted variants.


640-733: Comprehensive test for UPDATE with WHERE clause.

The test correctly:

  • Sets up a table with multiple rows
  • Executes an UPDATE targeting a specific row
  • Verifies only the expected row was updated
  • Validates the new value was applied correctly

735-812: Good test for multi-column UPDATE.

The test validates that multiple columns can be updated in a single statement and verifies both updated values.


814-880: Good test for UPDATE without WHERE clause.

The test correctly verifies that all rows are updated when no WHERE clause is provided, matching the expected SQL semantics.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread nexum_core/src/executor/mod.rs
Comment thread nexum_core/src/executor/mod.rs
Comment thread nexum_core/src/sql/parser.rs
- Add value assertions in test_parse_update_multiple_columns
- Add bounds check for row.values access with proper error handling
- Add error path tests for type mismatch, duplicate column, and unknown column
- Prevent potential panic from corrupted row data

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@nexum_core/src/sql/parser.rs`:
- Around line 328-345: The test test_parse_update_without_where checks structure
but not the assigned boolean value; update it to inspect the parsed assignment
from Parser::parse's Statement::Update branch by extracting assignments (e.g.,
assignments[0]) and asserting its value equals true (or the expected boolean) to
match other UPDATE parsing tests and ensure the AST stores the correct boolean
literal.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19543f2 and d596cb0.

📒 Files selected for processing (2)
  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit configuration file

Focus on Rust best practices, memory safety, error handling, and idiomatic code patterns.

Files:

  • nexum_core/src/executor/mod.rs
  • nexum_core/src/sql/parser.rs
🧬 Code graph analysis (1)
nexum_core/src/executor/mod.rs (4)
nexum_core/src/storage/engine.rs (2)
  • new (10-13)
  • memory (15-21)
nexum_core/src/executor/filter.rs (1)
  • new (53-55)
nexum_core/src/sql/parser.rs (1)
  • assignments (72-84)
nexum_core/src/sql/types.rs (1)
  • data_type (23-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Python tests
  • GitHub Check: Rust benchmarks
🔇 Additional comments (12)
nexum_core/src/sql/parser.rs (3)

64-93: LGTM! Clean UPDATE parsing implementation.

The parsing logic correctly extracts table name, assignments, and optional WHERE clause. The use of join(".") for compound identifiers properly handles both simple column names and qualified references.


267-286: LGTM! Comprehensive test with value assertion.

The test properly validates the table name, assignment structure, parsed value, and WHERE clause presence.


305-326: LGTM! Multi-column UPDATE parsing is well-tested.

Both column names and their corresponding values are properly asserted.

nexum_core/src/executor/mod.rs (9)

239-251: LGTM! Standard table lookup pattern.

Consistent with existing DELETE/SELECT implementations.


252-262: LGTM! Proper duplicate column detection.

The HashSet-based check efficiently catches duplicate assignments with a clear error message.


264-291: LGTM! Sound type checking with NULL handling.

The implementation correctly allows NULL values for any column type while enforcing type compatibility for non-NULL values. Error messages are clear and include relevant context.


301-333: Solid two-phase update with proper bounds checking.

The bounds check using get_mut (line 320) properly guards against corrupted row data. WHERE clause evaluation failures correctly abort the entire operation.

One observation: if serde_json::from_slice fails (line 302), the row is silently skipped. This is consistent with DELETE behavior, but corrupted rows would remain unmodified without any indication. Consider logging a warning for failed deserializations in a future improvement.


335-350: LGTM! Proper atomic batch updates with fail-fast serialization.

The implementation correctly serializes all rows first, ensuring that any serialization failure prevents partial updates. The batch_set call provides atomicity.


352-364: LGTM! Helpful warning for full-table updates.

The warning log for UPDATE without WHERE clause is a good safety measure.


447-450: LGTM! Consistent ExecutionResult variant.

The Updated variant follows the same pattern as Deleted and Inserted.


648-741: LGTM! Thorough UPDATE test with data verification.

The test properly validates both the operation result and the actual data state after the update.


890-1011: LGTM! Comprehensive error path coverage.

The error tests for type mismatch, duplicate column, and unknown column ensure robust validation. This addresses the previous review suggestion for error path testing.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread nexum_core/src/sql/parser.rs
- Assert column name 'active' and value Boolean(true) for consistency
- Matches the pattern used in other UPDATE parsing tests
@sshekhar563

Copy link
Copy Markdown
Contributor Author

@aviralgarg05 I've fix the issue

@aviralgarg05 aviralgarg05 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

LGTM!

@aviralgarg05 aviralgarg05 merged commit 922afce into aviralgarg05:main Jan 17, 2026
5 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.

2 participants