Skip to content

fix: seal JavaCC SQL parser escape hatches — ANTLR is always used now#3756

Open
robfrank wants to merge 19 commits intomainfrom
fix/seal-javacc-escape-hatches
Open

fix: seal JavaCC SQL parser escape hatches — ANTLR is always used now#3756
robfrank wants to merge 19 commits intomainfrom
fix/seal-javacc-escape-hatches

Conversation

@robfrank
Copy link
Copy Markdown
Collaborator

Summary

  • Removes all live call sites of SqlParser (JavaCC) from production code and tests — grep -r "new SqlParser(" returns zero results
  • StatementCache now always calls SQLAntlrParser, parseWithJavaCC() removed
  • SQLScriptQueryEngine.parseScript() JavaCC branch removed
  • GlobalConfiguration.SQL_PARSER_IMPLEMENTATION marked deprecated (no effect — ANTLR is always used)
  • AbstractProperty.getDefaultValue() and SQLFunctionEval.execute() migrated to SQLAntlrParser
  • All 11 parser test files migrated from SqlParser to SQLAntlrParser (via AbstractParserTest refactor)
  • Multiple ANTLR grammar/AST gaps fixed that were previously hidden by JavaCC-based tests:
    • matchFilterItemKey restricted to valid keys only
    • Named parameter :from (reserved keyword) now supported
    • CREATE INDEX grammar for named vs unnamed forms
    • UNWIND with multiple items, TIMEOUT with EXCEPTION/RETURN
    • Array selectors: range, IN, NOT IN
    • RID_STRING as base expression
    • UpdatePutItem, InCondition, Timeout, UpdateOperations, UpdateIncrementItem, CreateIndexStatement AST fixes

Test plan

  • grep -r "new SqlParser(" engine/src/main/java/ engine/src/test/java/ → zero results
  • mvn test -Dtest="*ParserTest*,*StatementTest*,*ScriptTest*" → 272 tests, 0 failures
  • Full engine test suite passes

🤖 Generated with Claude Code

@claude
Copy link
Copy Markdown

claude bot commented Mar 29, 2026

Code Review

This is a solid, well-scoped cleanup that resolves the concrete bug from #3738 (parser tests silently testing the wrong parser). The core migration is correct and the grammar/AST fixes are legitimate gap-fills. A few items worth discussing:


Issues to address before merging

1. Overly broad exception catch in AbstractProperty.getDefaultValue()

// Before (precise)
} catch (ParseException e) {
  // IGNORE IT

// After (too broad)
} catch (Exception e) {
  // IGNORE IT

catch (Exception e) swallows everything including NullPointerException, ClassCastException, etc. — bugs that should be visible. Consider catch (CommandSQLParsingException e) (what ANTLR throws) instead. If you want to also guard against unexpected runtime errors, at minimum log at DEBUG level.


2. UpdatePutItem access widening: protectedpublic

-  protected Identifier left;
-  protected Expression key;
-  protected Expression value;
+  public Identifier left;
+  public Expression key;
+  public Expression value;

Widening access modifiers is a red flag — it enlarges the public API surface. If the ANTLR AST builder needs to set these, a package-private accessor or a constructor that accepts the fields would be preferable. What's the motivation for making them public?


3. Duplicate createIndexBody grammar alternatives

| identifier (IF NOT EXISTS)? indexType
  (METADATA json)?
  (ENGINE identifier)?
| identifier (IF NOT EXISTS)? indexType
  (ENGINE identifier)?
  (METADATA json)?

These two alternatives exist only to allow ENGINE and METADATA in either order. ANTLR supports optional clauses in any combinator — consider something like:

| identifier (IF NOT EXISTS)? indexType
  ( (METADATA json) | (ENGINE identifier) )*

The duplicate alternatives will cause ambiguity warnings and are harder to maintain.


4. SQL_PARSER_IMPLEMENTATION silently ignored at runtime

Users who have arcadedb.sql.parserImplementation=javacc in their config will get no feedback that the setting has no effect. A one-time LogManager.instance().log(...) warning when a non-default value is detected (in GlobalConfiguration or StatementCache) would help operators discover the dead setting.


Minor observations

5. Plan files committed to docs/plans/

docs/plans/2026-03-28-seal-javacc-escape-hatches.md (624 lines) is an internal implementation plan — it even contains a local machine path (/Users/frank/projects/arcade/worktrees/...). The design document (-design.md) is fine as a record of the architectural decision, but the task-by-task execution plan is more of a working note than repository documentation worth preserving.

6. Unused import added to SQLASTBuilder.java

+import org.antlr.v4.runtime.ParserRuleContext;

This import was added but ParserRuleContext does not appear to be used in the shown diff. Confirm it's actually referenced, or remove it.


What's good

  • The InCondition.toString() fix (not ? " NOT IN " : " IN ") is a genuine serialization bug — good catch.
  • The checkRightSyntax roundtrip (parse → toString() → re-parse) in AbstractParserTest is a smart regression guard, and the SubqueryExpression/StatementExpression toString() overrides are necessary to make it work.
  • Restricting matchFilterItemKey to an explicit keyword list (removing the open identifier fallback) is the right call — the old rule accepted any identifier as a filter key, hiding typos silently.
  • The commitStatement grammar fix properly handles the ELSE-branch structure.
  • Removing throwParsingException(TokenMgrError, ...) is correct — TokenMgrError is JavaCC-specific dead code now.
  • SQLScriptQueryEngine.parseScript() simplification is clean.

Overall this is good work. The catch (Exception e) in AbstractProperty and the UpdatePutItem access widening are the two items I'd want resolved before merging.

🤖 Generated with Claude Code

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements the plan to "Seal JavaCC SQL Parser Escape Hatches" by removing the ability to invoke the legacy JavaCC parser. Key changes include deprecating the SQL_PARSER_IMPLEMENTATION configuration, migrating production code paths in AbstractProperty and SQLFunctionEval to SQLAntlrParser, and updating the ANTLR grammar and SQLASTBuilder to address syntax gaps. Additionally, numerous test files were refactored to extend AbstractParserTest. Feedback suggests adding the @deprecated tag to the configuration description for consistency and using protected fields with setters in UpdatePutItem to improve encapsulation.

SQL parser implementation to use. 'antlr' (default) uses the new ANTLR4-based parser with improved error messages. \
'javacc' uses the legacy JavaCC-based parser for backward compatibility.""",
String.class, "antlr", Set.of("antlr", "javacc")),
"Deprecated, has no effect. The ANTLR4-based SQL parser is always used.",
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.

medium

For consistency with Javadoc conventions and the implementation plan, the deprecation message should start with @Deprecated.

Suggested change
"Deprecated, has no effect. The ANTLR4-based SQL parser is always used.",
"@Deprecated, has no effect. The ANTLR4-based SQL parser is always used.",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The description string is a user-facing runtime value, not a Javadoc comment — adding @Deprecated as literal text in the string does nothing for Java's deprecation mechanism. The codebase already shows the correct pattern: GREMLIN_COMMAND_TIMEOUT uses the actual @Deprecated Java annotation on the enum constant. Adding @Deprecated as a text prefix here would be misleading and inconsistent.

Comment on lines +27 to +29
public Identifier left;
public Expression key;
public Expression value;
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.

medium

For better encapsulation and consistency with other AST nodes like UpdateIncrementItem, it's preferable to keep these fields protected and provide public fluent setters instead of making them public.

You could add setters like this to UpdatePutItem:

public UpdatePutItem setLeft(Identifier left) {
  this.left = left;
  return this;
}

public UpdatePutItem setKey(Expression key) {
  this.key = key;
  return this;
}

public UpdatePutItem setValue(Expression value) {
  this.value = value;
  return this;
}

Then, SQLASTBuilder.visitUpdatePutItem() can be updated to use these setters.

Suggested change
public Identifier left;
public Expression key;
public Expression value;
protected Identifier left;
protected Expression key;
protected Expression value;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed. Reverted fields to protected and added fluent setters matching the UpdateIncrementItem pattern. Updated SQLASTBuilder.visitUpdatePutItem() to use them.

robfrank and others added 15 commits March 29, 2026 14:48
…gaps

- AbstractParserTest now uses SQLAntlrParser instead of SqlParser
- SelectStatementTest.emptyCollection() migrated to use SQLAntlrParser directly
- Fix SQLParser.g4: matchFilterItemKey restricted to valid keys only (was accepting any identifier)
- Fix SQLParser.g4: named parameter :from now supported (FROM is a reserved keyword)
- Fix SQLParser.g4: CREATE INDEX grammar for named vs unnamed index forms
- Fix SQLParser.g4: UNWIND now supports multiple items separated by commas
- Fix SQLParser.g4: TIMEOUT clause now supports EXCEPTION/RETURN options
- Fix SQLParser.g4: array selectors improvements (range, IN, NOT IN)
- Fix SQLParser.g4: RID_STRING as base expression
- Fix SQLASTBuilder.java: UpdatePutItem, InCondition, Timeout, UpdateOperations,
  UpdateIncrementItem, CreateIndexStatement, StatementExpression, SubqueryExpression
- PatternTestParserTest updated to work with ANTLR semantics

This completes the JavaCC escape hatch sealing: grep for "new SqlParser" in
src/main/java and src/test/java returns zero call-site results.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- AbstractParserTest now uses SQLAntlrParser (the production parser)
  instead of the legacy JavaCC parser, which was silently hiding gaps
- SQLParser.g4: make EXPORT DATABASE url optional; add FORCE to DROP
  PROPERTY; add INTEGER_LITERAL to DROP/TRUNCATE BUCKET; fix TRUNCATE
  RECORD to require brackets for multiple RIDs; fix COMMIT RETRY ELSE
  block to require AND and non-empty body; add STAR to ALTER BUCKET;
  add legacy quoted-name syntax to CREATE INDEX; add OVERWRITE as
  allowed identifier for use in WITH clause settings
- SQLASTBuilder: fix ClassCastException in ALTER PROPERTY/BUCKET NAME
  handling; fix DROP/TRUNCATE BUCKET integer ID; fix CREATE INDEX
  legacy syntax visitor
- SubqueryExpression, StatementExpression: add toString(Map,StringBuilder)
  override so LET subquery round-trips correctly
- ImportDatabaseStatement: fix settings key serialization in toString()
- ExportDatabaseStatementTestParserTest: add WITH clause test cases

Closes #3738

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@robfrank robfrank force-pushed the fix/seal-javacc-escape-hatches branch from 62205ce to 29c3c5a Compare March 29, 2026 12:51
@codacy-production
Copy link
Copy Markdown

codacy-production bot commented Mar 29, 2026

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for c74969f1 86.62%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (c74969f) Report Missing Report Missing Report Missing
Head commit (84a1bc9) 146686 95523 65.12%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#3756) 157 136 86.62%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

- Remove FROM from identifier rule (was causing SELECT FROM to parse
  'from' as a projection field); allow FROM only in inputParameter for
  :from named params
- Fix createIndexBody ON-clause to accept NULL_STRATEGY/METADATA/ENGINE
  in any order matching toString() output order; fix positional visitor
  to check NULL_STRATEGY before ENGINE
- Fix createVertexBody to accept BUCKET_IDENTIFIER/BUCKET_NUMBER_IDENTIFIER
  tokens (bucket:name syntax without a type name); fix visitCreateVertexStmt
  to handle both forms
- Make DECR GT and ARROW_LEFT MINUS require matchProperties in matchMethod
  and nestedMatchMethod, preventing consecutive arrows without node filter
- Add bucket value validation in visitMatchFilterItem to reject float
  literals (only integer ID or identifier name allowed)
- Fix tryExtractIntegerLiteral to throw on FloatingPoint/PNumber values,
  rejecting foo[1....5] range selectors with float endpoints
- Fix PInteger construction in BUCKET_NUMBER_IDENTIFIER handling (was
  passing value as node id; use setValue() instead)
- Add PARALLEL keyword to lexer and selectStatement as optional trailing
  hint for legacy OrientDB compatibility

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@claude
Copy link
Copy Markdown

claude bot commented Mar 29, 2026

PR Review: Seal JavaCC SQL Parser Escape Hatches

Good overall goal — removing the JavaCC escape hatches is an important correctness fix after #3738. The core migration in StatementCache, SQLScriptQueryEngine, AbstractProperty, and SQLFunctionEval is clean and correct. The grammar bug-fixes bundled here are a nice bonus.

That said, I have several concerns worth addressing before merge.


🔴 Potential Breaking Change: matchProperties now required on --> / <--

File: SQLParser.g4, lines ~248–264

- | DECR GT matchProperties?    // -->{as:x} anonymous outgoing
+ | DECR GT matchProperties     // -->{as:x} anonymous outgoing (properties required)
- | ARROW_LEFT MINUS matchProperties?  // <--{as:x}
+ | ARROW_LEFT MINUS matchProperties  // <--{as:x}

The grammar for matchMethod and nestedMatchMethod now requires a matchProperties block after --> and <--. Since matchNode and matchProperties have the same structure (LBRACE matchFilter? RBRACE), this creates a risk: ANTLR4 will now greedily consume the next {...} block as the edge's matchProperties rather than the next node's matchNode.

For example, MATCH {as:a}-->{as:b} — previously ANTLR resolved {as:b} as the next matchNode; now it may be consumed as matchProperties, leaving matchPath without the required trailing matchNode. This is a potential regression for all MATCH queries using bare -->.

Please add an explicit test covering MATCH {as:a}-->{as:b} and MATCH {as:a}<--{as:b} to the MatchStatementTest. If these are indeed broken, the optional ? should be restored.


🔴 fromIdentifier alias removed silently

File: SQLParser.g4, line ~1036; SQLASTBuilder.java

-    | identifier (modifier)* (AS? identifier)?    # fromIdentifier
+    | identifier (modifier)*                       # fromIdentifier
- // Handle alias (second identifier after AS)
- if (ctx.identifier().size() > 1) {
-   fromItem.alias = (Identifier) visit(ctx.identifier(1));
- }

This removes alias support from the bare-identifier form of FROM. Was this intentional? Queries like SELECT FROM Person AS p WHERE p.name = 'x' could be affected. If the alias in fromSubquery (the LPAREN statement RPAREN ... (AS? identifier)? alternative) covers the needed cases, please add a comment explaining why the fromIdentifier alias is intentionally dropped — and a regression test.


🟡 UpdatePutItem visibility widened to public without justification

File: UpdatePutItem.java

-  protected Identifier left;
-  protected Expression key;
-  protected Expression value;
+  public Identifier left;
+  public Expression key;
+  public Expression value;

Changing protectedpublic widens the API surface unnecessarily. The visitUpdatePutItem handler in SQLASTBuilder could use setters or just set the fields directly (it's in the same package hierarchy). Please either revert to protected or add proper setters like the pattern used for UpdateIncrementItem.


🟡 AbstractProperty.getDefaultValue() swallows all exceptions

File: AbstractProperty.java

- } catch (ParseException e) {
+ } catch (Exception e) {
    // IGNORE IT

Catching bare Exception silently suppresses NullPointerException, ClassCastException, OutOfMemoryError (via RuntimeException), etc. This can hide real bugs. Please narrow to CommandSQLParsingException (what ANTLR throws) or at worst RuntimeException.


🟡 UNWIND AS-alias handling dropped from visitor

File: SQLASTBuilder.java (visitUnwind)

The grammar retains UNWIND expression (AS? identifier)? but the new visitor completely ignores ctx.identifier() — any AS alias is silently discarded. Either:

  • Remove the AS? identifier alternative from the grammar (if UNWIND aliases aren't supported), or
  • Restore the alias-handling code in the visitor

As-is, this is a quiet behaviour difference between old and new parser.


🟡 commitStatement grammar now requires AND before FAIL/CONTINUE

File: SQLParser.g4

- : COMMIT (RETRY INTEGER_LITERAL (ELSE (LBRACE (scriptStatement SEMICOLON?)* RBRACE)? (AND? (FAIL | CONTINUE))?)?)?
+ : COMMIT (RETRY INTEGER_LITERAL (ELSE (LBRACE (scriptStatement SEMICOLON?)+ RBRACE AND (FAIL | CONTINUE) | (FAIL | CONTINUE)))?)?

AND is now mandatory between the brace block and FAIL/CONTINUE (previously AND?). Also *+ means the brace block must be non-empty. Please confirm that COMMIT RETRY 3 ELSE FAIL and COMMIT RETRY 3 ELSE { stmt1; } FAIL (without AND) are still tested and pass.


🟢 Minor: Plan documents in docs/plans/ contain machine-local paths

Files: docs/plans/2026-03-28-seal-javacc-escape-hatches.md, docs/plans/2026-03-28-seal-javacc-escape-hatches-design.md

These AI-generated planning documents reference an absolute local path (/Users/frank/projects/arcade/worktrees/worktrees/seal-javacc) and are not useful reference documentation for other contributors. They're fine as ephemeral design notes but probably don't belong committed to main. Consider removing them or moving to a CONTRIBUTING-style internal wiki.


✅ What looks good

  • StatementCache.parse() and SQLScriptQueryEngine.parseScript() simplifications are clean
  • SQLFunctionEval.execute() migration is correct — removing the ByteArrayInputStream wrapper is a nice cleanup
  • GlobalConfiguration.SQL_PARSER_IMPLEMENTATION deprecation is handled correctly (no more validation set, description updated)
  • InCondition.toString() — correctly emits NOT IN when not == true
  • matchFilterItemKey restricted to the documented valid keys (removes the open-ended identifier fallback that hid the parser divergence)
  • StatementExpression and SubqueryExpression now implement toString() — good fix
  • visitInputParameter now handles :from (reserved keyword as named param) correctly
  • NearOperator/WithinOperator added to mapComparisonOperator — good fix

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 29, 2026

Codecov Report

❌ Patch coverage is 69.42675% with 48 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.84%. Comparing base (9cd49e9) to head (84a1bc9).
⚠️ Report is 28 commits behind head on main.

Files with missing lines Patch % Lines
...va/com/arcadedb/query/sql/antlr/SQLASTBuilder.java 69.56% 16 Missing and 26 partials ⚠️
...om/arcadedb/function/sql/math/SQLFunctionEval.java 25.00% 3 Missing ⚠️
.../arcadedb/query/sql/antlr/StatementExpression.java 66.66% 1 Missing and 1 partial ⚠️
...ain/java/com/arcadedb/schema/AbstractProperty.java 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3756      +/-   ##
==========================================
+ Coverage   64.09%   64.84%   +0.75%     
==========================================
  Files        1580     1580              
  Lines      115475   115571      +96     
  Branches    24445    24472      +27     
==========================================
+ Hits        74010    74946     +936     
+ Misses      31348    30464     -884     
- Partials    10117    10161      +44     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

robfrank and others added 2 commits March 30, 2026 01:19
- Add RID_STRING token for quoted "@Rid" form in lexer
- Allow RID_STRING in stringLiteral expression alternative
- Fix COMMIT RETRY ELSE block to not require trailing AND FAIL/CONTINUE

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Restore (AS? identifier)? in fromIdentifier grammar rule
- Fix visitFromIdentifier to use identifier(0) for the type name
- Update SelectStatementTest: bare aliases without AS are valid SQL

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@claude
Copy link
Copy Markdown

claude bot commented Mar 30, 2026

Code Review (supplemental)

Good cleanup overall — the core goal of sealing JavaCC escape hatches is achieved cleanly. These are additional items not covered in the prior review.


Issues to address before merging

1. truncateRecordBody grammar change is a breaking API change

The comma-separated form TRUNCATE RECORD #1:1, #2:2 is gone — replaced by TRUNCATE RECORD [#1:1, #2:2]. This is a backwards-incompatible change with no mention in the PR description. Either restore the old form as a parallel alternative, or document this as a deliberate breaking change.


2. matchMethod/nestedMatchMethod: making --> and <-- require matchProperties breaks existing MATCH queries

- | DECR GT matchProperties?   // -->{as:x} anonymous outgoing
+ | DECR GT matchProperties    // -->{as:x} anonymous outgoing (properties required)

Any MATCH query using bare --> or <-- without {...} will now fail to parse. For example:

MATCH {class:Person, as:a} --> {class:Address, as:b} RETURN a, b

The --> here has no {...} block of its own — the {class:Address, as:b} is the destination node's properties, not the edge's. The bidirectional -- form kept ?, making the asymmetry surprising. If there is a parser ambiguity reason for this change, it needs a comment and a regression test. If unintentional, revert to matchProperties?.


3. PARALLEL keyword added to grammar but not handled in the AST builder or SelectStatement.toString()

SQLParser.g4 now accepts PARALLEL at the end of selectStatement and a new PARALLEL token is in the lexer. But there is no corresponding visitor in SQLASTBuilder.java and SelectStatement.toString() does not emit PARALLEL. The round-trip check in AbstractParserTest.checkRightSyntax() (parse -> toString -> re-parse) will silently drop PARALLEL from any query. Either wire it through to the AST and add a round-trip test, or remove it from this PR.


4. GlobalConfiguration.SQL_PARSER_IMPLEMENTATION is missing the Java @Deprecated annotation

The description text says "Deprecated" but there is no @Deprecated annotation on the enum constant. Without it, IDEs and tools will not flag usages at compile time. Add @Deprecated to the constant itself.


5. DROP PROPERTY ... FORCE added to grammar but needs AST handling

dropPropertyBody now accepts FORCE?, but there is no corresponding field, visitor update, or toString() change visible in this diff. If FORCE is not wired through to execution, it will be silently ignored. Please confirm this is handled (or add a tracking TODO).


Minor

6. select from Foo bar (alias) silently dropped

The tests flip select from Foo bar from wrong-syntax to right-syntax, and the comment in visitFromIdentifier says the alias "is ignored in execution". This means SELECT a.name FROM Person p WHERE p.age > 18 parses without error but the alias binding has no effect at runtime. At minimum, add a comment in the grammar so users are not surprised.


What looks good

  • StatementCache/SQLScriptQueryEngine simplifications are clean and correct
  • SQLFunctionEval migration is correct — removing the ByteArrayInputStream wrapper is a nice cleanup
  • InCondition.toString() correctly emits NOT IN when not == true (genuine bug fix)
  • StatementExpression/SubqueryExpression now implement toString() — good fix
  • matchFilterItemKey restricted to documented valid keys only — correct fix for the divergence that hid test failures
  • visitInputParameter now handles :from (reserved keyword as named param) correctly
  • AbstractParserTest refactor cleanly removes 40+ lines of duplicated boilerplate across 11 test files

Follow the same encapsulation pattern as UpdateIncrementItem: keep fields
protected and expose public fluent setters. Update SQLASTBuilder to use
the new setters instead of direct field assignment.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@robfrank
Copy link
Copy Markdown
Collaborator Author

Review response

Comment 1 (rejected) — @Deprecated prefix in description string
The description is a user-facing runtime string, not a Javadoc comment. Adding @Deprecated as text in a string has no effect on Java's deprecation mechanism. The codebase already shows the correct pattern: GREMLIN_COMMAND_TIMEOUT uses the actual @Deprecated Java annotation on the enum constant. The description string text "Deprecated, has no effect..." is sufficient.

Comment 2 (implemented) — protected fields + fluent setters in UpdatePutItem
Valid. Reverted fields to protected and added setLeft(), setKey(), setValue() fluent setters matching the UpdateIncrementItem pattern. Updated SQLASTBuilder.visitUpdatePutItem() to use the setters.

@claude
Copy link
Copy Markdown

claude bot commented Mar 30, 2026

Review Summary (follow-up): Three prior reviews have covered this PR thoroughly. Summarizing unresolved items after the author response.

ADDRESSED: UpdatePutItem setters added (confirmed). The @deprecated annotation should also be placed on the enum constant, not just the description string.

STILL UNRESOLVED:

  1. catch (Exception e) in AbstractProperty.getDefaultValue() - silently swallows NullPointerException, ClassCastException, etc. Please narrow to catch (CommandSQLParsingException e).

  2. matchProperties now required after --> and <-- - this is a breaking grammar change. MATCH {class:Person, as:a} --> {class:Address, as:b} may now fail because ANTLR will consume {class:Address, as:b} as the edge properties instead of the next node. Please add a MatchStatementTest covering this exact pattern.

  3. PARALLEL keyword not wired to AST - PARALLEL was added to grammar/lexer but there is no visitor in SQLASTBuilder and SelectStatement.toString() does not emit it. Wire it through or remove from this PR.

  4. TRUNCATE RECORD comma-separated form removed - replacing TRUNCATE RECORD rid1, rid2 with TRUNCATE RECORD [rid1, rid2] is an undocumented breaking change.

The core parser migration (JavaCC to ANTLR everywhere) is correct and well-executed. Items 2 and 3 need explicit confirmation before merge.

Generated with Claude Code

Copy link
Copy Markdown
Member

@lvca lvca left a comment

Choose a reason for hiding this comment

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

Not sure if all the keywords added are not used, like PARALLEL in the query or FORCE in the drop statements.

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.

fix: SQL parser tests were silently using legacy JavaCC parser, hiding grammar gaps

2 participants