Skip to content

Fix Opencypher tck tests#3362

Merged
lvca merged 11 commits intomainfrom
opencypher-tck
Feb 7, 2026
Merged

Fix Opencypher tck tests#3362
lvca merged 11 commits intomainfrom
opencypher-tck

Conversation

@lvca
Copy link
Contributor

@lvca lvca commented Feb 7, 2026

2nd pass, much better.

=======================================================
         OpenCypher TCK Compliance Report
=======================================================
Total scenarios:  3897
Passed:           1908 (48%)
Failed:           1939 (49%)
Skipped:          50 (1%)
-------------------------------------------------------
By category:
  clauses/call                               2/ 52 passed (3%)
  clauses/create                            64/ 78 passed (82%)
  clauses/delete                            24/ 41 passed (58%)
  clauses/match                            292/381 passed (76%)
  clauses/match-where                       25/ 34 passed (73%)
  clauses/merge                             47/ 75 passed (62%)
  clauses/remove                            29/ 33 passed (87%)
  clauses/return                            35/ 63 passed (55%)
  clauses/return-orderby                    23/ 35 passed (65%)
  clauses/return-skip-limit                 26/ 31 passed (83%)
  clauses/set                               30/ 53 passed (56%)
  clauses/union                              8/ 12 passed (66%)
  clauses/unwind                            10/ 14 passed (71%)
  clauses/with                              14/ 29 passed (48%)
  clauses/with-orderBy                     124/292 passed (42%)
  clauses/with-skip-limit                    7/  9 passed (77%)
  clauses/with-where                        10/ 19 passed (52%)
  expressions/aggregation                   23/ 35 passed (65%)
  expressions/boolean                      150/150 passed (100%)
  expressions/comparison                    36/ 72 passed (50%)
  expressions/conditional                   13/ 13 passed (100%)
  expressions/existentialSubqueries          4/ 10 passed (40%)
  expressions/graph                         32/ 61 passed (52%)
  expressions/list                         120/185 passed (64%)
  expressions/literals                     120/131 passed (91%)
  expressions/map                           28/ 44 passed (63%)
  expressions/mathematical                   3/  6 passed (50%)
  expressions/null                          44/ 44 passed (100%)
  expressions/path                           0/  7 passed (0%)
  expressions/pattern                       19/ 50 passed (38%)
  expressions/precedence                    20/121 passed (16%)
  expressions/quantifier                   478/604 passed (79%)
  expressions/string                        22/ 32 passed (68%)
  expressions/temporal                       0/1004 passed (0%)
  expressions/typeConversion                19/ 47 passed (40%)
  useCases/countingSubgraphMatches           6/ 11 passed (54%)
  useCases/triadicSelection                  1/ 19 passed (5%)
=======================================================

lvca added 11 commits February 6, 2026 10:24
Reached much better compliance with the latest changes:

```
=======================================================
         OpenCypher TCK Compliance Report
=======================================================
Total scenarios:  3897
Passed:           1908 (48%)
Failed:           1939 (49%)
Skipped:          50 (1%)
-------------------------------------------------------
By category:
  clauses/call                               2/ 52 passed (3%)
  clauses/create                            64/ 78 passed (82%)
  clauses/delete                            24/ 41 passed (58%)
  clauses/match                            292/381 passed (76%)
  clauses/match-where                       25/ 34 passed (73%)
  clauses/merge                             47/ 75 passed (62%)
  clauses/remove                            29/ 33 passed (87%)
  clauses/return                            35/ 63 passed (55%)
  clauses/return-orderby                    23/ 35 passed (65%)
  clauses/return-skip-limit                 26/ 31 passed (83%)
  clauses/set                               30/ 53 passed (56%)
  clauses/union                              8/ 12 passed (66%)
  clauses/unwind                            10/ 14 passed (71%)
  clauses/with                              14/ 29 passed (48%)
  clauses/with-orderBy                     124/292 passed (42%)
  clauses/with-skip-limit                    7/  9 passed (77%)
  clauses/with-where                        10/ 19 passed (52%)
  expressions/aggregation                   23/ 35 passed (65%)
  expressions/boolean                      150/150 passed (100%)
  expressions/comparison                    36/ 72 passed (50%)
  expressions/conditional                   13/ 13 passed (100%)
  expressions/existentialSubqueries          4/ 10 passed (40%)
  expressions/graph                         32/ 61 passed (52%)
  expressions/list                         120/185 passed (64%)
  expressions/literals                     120/131 passed (91%)
  expressions/map                           28/ 44 passed (63%)
  expressions/mathematical                   3/  6 passed (50%)
  expressions/null                          44/ 44 passed (100%)
  expressions/path                           0/  7 passed (0%)
  expressions/pattern                       19/ 50 passed (38%)
  expressions/precedence                    20/121 passed (16%)
  expressions/quantifier                   478/604 passed (79%)
  expressions/string                        22/ 32 passed (68%)
  expressions/temporal                       0/1004 passed (0%)
  expressions/typeConversion                19/ 47 passed (40%)
  useCases/countingSubgraphMatches           6/ 11 passed (54%)
  useCases/triadicSelection                  1/ 19 passed (5%)
=======================================================
```
@lvca lvca self-assigned this Feb 7, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @lvca, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the OpenCypher implementation by addressing numerous compliance issues identified through TCK tests. It introduces a new list slicing feature, refines the parsing and evaluation of various expressions, and improves the robustness of built-in functions. Additionally, it tightens semantic validation rules and standardizes result formatting, contributing to a more stable and compliant Cypher query engine.

Highlights

  • Enhanced Expression Parsing and Evaluation: Refactored the Cypher expression builder to correctly parse complex expressions, including top-level comparisons, arithmetic operations, and postfix expressions (like list slicing). The ArithmeticExpression now supports list concatenation and element appending/prepending using the + operator. Function calls are now dynamically resolved via the CommandContext, allowing for more flexible evaluation.
  • New Feature: List Slicing: Introduced ListSliceExpression to support list and string slicing (e.g., list[from..to]), including Python-style negative indices, enhancing Cypher's list manipulation capabilities.
  • Improved Functionality and Robustness: Added support for the coalesce() function. The keys() and properties() functions now correctly handle null inputs and Map objects, with properties() preserving insertion order. The size() function now returns null for null or invalid inputs, aligning with Cypher's null propagation. Literal parsing has been improved to handle various number formats (e.g., .1, hex, octal) and detect integer overflows.
  • Stricter Semantic Validation: Implemented new semantic validation rules for variable scope (especially for CALL with YIELD and SUBQUERY clauses) and for SKIP/LIMIT values, ensuring they are non-negative. Boolean operands are now strictly checked to prevent List or Map expressions from being used directly in boolean contexts.
  • Refined Result Formatting: Adjusted the FinalProjectionStep to ensure that when a single document element is returned, it is correctly identified as an element for backward compatibility while retaining its original projection name for wire protocols. This resolves inconsistencies in how single-element results were presented.
  • Traversal Logic Adjustment: Removed the IllegalArgumentException for minHops > maxHops in GraphTraverser, allowing such traversals to naturally yield empty results instead of throwing an error.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • engine/src/main/java/com/arcadedb/query/opencypher/ast/ArithmeticExpression.java
    • Added java.util.ArrayList and java.util.List imports.
    • Implemented support for list concatenation and element appending/prepending using the + operator.
  • engine/src/main/java/com/arcadedb/query/opencypher/ast/FunctionCallExpression.java
    • Added com.arcadedb.function.StatelessFunction and java.util.function.Function imports.
    • Introduced FUNCTION_RESOLVER_KEY constant for dynamic function resolution.
    • Modified evaluate method to resolve functions from CommandContext using the new resolver, allowing functions to be evaluated within compound expressions.
  • engine/src/main/java/com/arcadedb/query/opencypher/ast/ListSliceExpression.java
    • New file added to implement list slicing functionality.
    • Supports list[from..to] syntax with optional from/to and negative indices.
    • Handles both List and String types for slicing.
  • engine/src/main/java/com/arcadedb/query/opencypher/executor/CypherExecutionPlan.java
    • Added java.util.function.Function import.
    • Introduced setupFunctionResolver method to store a function resolver in the CommandContext.
    • Called setupFunctionResolver in execute(), executeWithSeedRow(), executeUnion(), and profile() methods to enable dynamic function evaluation.
  • engine/src/main/java/com/arcadedb/query/opencypher/executor/CypherFunctionFactory.java
    • Added coalesce to the list of Cypher-specific functions.
    • Implemented CoalesceFunction to return the first non-null argument.
    • Modified keys() function to handle null input and Map objects, returning null or ArrayList of keys respectively.
    • Modified properties() function to handle null input and Map objects, using LinkedHashMap for order preservation.
    • Modified size() function to return null for null input or non-list/non-string inputs.
    • Corrected DistinctFunction to use java.util.Arrays.asList for seenValues.add to ensure correct comparison of argument arrays.
  • engine/src/main/java/com/arcadedb/query/opencypher/executor/steps/FinalProjectionStep.java
    • Refactored filterResult method to correctly set the element property in ResultInternal when a single document is returned, ensuring backward compatibility while preserving projection metadata.
  • engine/src/main/java/com/arcadedb/query/opencypher/parser/CypherExpressionBuilder.java
    • Added com.arcadedb.exception.CommandParsingException import.
    • Refactored parseExpression to prioritize top-level parsing for comparisons, arithmetic, and postfix expressions using non-recursive spine walks (findTopLevelExpression7, findTopLevelExpression6, findTopLevelExpression2).
    • Implemented parsing for ListSliceExpression within parseExpression2WithPostfix.
    • Improved tryParseLiteral to handle floating-point numbers without integer parts, hexadecimal, and octal literals, and added specific error handling for invalid number formats and integer overflows.
  • engine/src/main/java/com/arcadedb/query/opencypher/parser/CypherSemanticValidator.java
    • Added validateVariableScope and validateSkipLimit to the main validation sequence.
    • Enhanced variable scope validation for CALL with YIELD and SUBQUERY clauses.
    • Added validation to reject ListExpression and MapExpression as direct boolean operands in checkOperandForBooleanContext.
    • Implemented validateSkipLimit to ensure SKIP and LIMIT values are non-negative in both main queries and WITH clauses.
  • engine/src/main/java/com/arcadedb/query/opencypher/traversal/GraphTraverser.java
    • Removed the IllegalArgumentException check for minHops > maxHops, allowing traversal to naturally return empty results in such scenarios.
  • engine/src/test/java/com/arcadedb/query/opencypher/CypherResultFormatTest.java
    • Updated tests (returnSingleNodeIsElement, returnSingleEdgeIsElement, returnNodeWithAlias, singleNodeHasProjectionNameMetadata) to assert on the presence of variable columns and their types, rather than relying on isElement() directly, reflecting the refined result formatting logic.
Activity
  • This pull request represents a '2nd pass' at fixing OpenCypher TCK tests, indicating previous iterations and refinements have already occurred.
  • The detailed TCK compliance report in the PR description suggests a thorough analysis of failing tests and targeted fixes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@lvca lvca marked this pull request as ready for review February 7, 2026 01:59
@lvca lvca merged commit a8a3f37 into main Feb 7, 2026
7 of 10 checks passed
@lvca lvca deleted the opencypher-tck branch February 7, 2026 01:59
@mergify
Copy link
Contributor

mergify bot commented Feb 7, 2026

🧪 CI Insights

Here's what we observed from your CI run for 25d73b7.

🟢 All jobs passed!

But CI Insights is watching 👀

@claude
Copy link

claude bot commented Feb 7, 2026

OpenCypher TCK Compliance Improvements - Code Review

Thank you for this significant improvement to OpenCypher TCK compliance (48% pass rate). This PR implements several critical features for Cypher expression handling. Here's my detailed review:


Strengths

1. List Slicing Implementation

The new ListSliceExpression class is well-designed:

  • Properly handles negative indices (Python-style)
  • Correctly clamps indices to valid ranges
  • Supports both List and String slicing
  • Returns appropriate empty values when from >= to
  • Good null handling throughout

2. List Concatenation

The arithmetic expression enhancements for list operations are solid:

  • Handles List + List (concatenation)
  • Handles List + element (append)
  • Handles element + List (prepend)
  • Preserves existing string concatenation behavior

3. Function Resolution Architecture

The function resolver mechanism is a good architectural solution:

  • Properly decouples function resolution from evaluation
  • Stores resolver in context for compound expressions
  • Allows function calls within AND/OR/CASE expressions

4. Semantic Validation Enhancements

Good additions:

  • SKIP/LIMIT negative value validation
  • Variable scope handling for CALL and SUBQUERY clauses
  • Boolean operand type validation for lists/maps

⚠️ Issues & Concerns

1. Inconsistent Null Handling (High Priority)

Location: CypherFunctionFactory.java:381-389

The size() function behavior changed:

  • Old: size(123)0L
  • New: size(123)null

Questions:

  1. Is this change intentional and required by TCK?
  2. Have you verified this doesn't break existing queries?
  3. Should there be a migration note for users?

2. Expression Parser Complexity (Medium Priority)

Location: CypherExpressionBuilder.java:469-495

The addition of "top-level spine walk" methods adds significant complexity:

  • These methods have similar structure with subtle differences
  • The parsing order dependencies are fragile (comments indicate "MUST be checked BEFORE...")
  • Hard to maintain and reason about

Recommendation: Consider extracting a common spine-walking utility method and add comprehensive unit tests specifically for expression parsing precedence.

3. Hex/Octal Number Parsing (Medium Priority)

Location: CypherExpressionBuilder.java:1767-1790

No handling for overflow in hex/octal parsing. Consider wrapping in try-catch:

try {
  final long val = Long.parseLong(hexPart, 16);
  return text.startsWith("-") ? -val : val;
} catch (NumberFormatException e) {
  throw new CommandParsingException("Invalid hex literal: " + text);
}

4. Exception Handling in Function Resolver (Low Priority)

Location: CypherExecutionPlan.java:271-278

Catching all exceptions and returning null silently swallows errors. Consider logging:

} catch (final Exception e) {
  context.getDatabase().getLogger().warn("Failed to resolve function: " + name, e);
  return null;
}

5. Code Style Consistency (Minor)

Location: CypherFunctionFactory.java:1398

Why change from List.of(args) to Arrays.asList(args)? Both create immutable lists, but List.of() is more modern.


🧪 Test Coverage

Recommend adding tests for:

  1. List slicing edge cases:

    • [1,2,3][-10..10] (indices beyond bounds)
    • [1,2,3][5..2] (from > to)
    • "hello"[1..3] (string slicing)
  2. List arithmetic:

    • [1,2] + [3,4] (concatenation)
    • [1,2] + 3 (append)
    • Chains: [1] + [2] + [3]
  3. Number literal parsing:

    • 0x7FFFFFFFFFFFFFFF (max hex)
    • 0x8000000000000000 (overflow)
    • .5, -.5, .5e-3 (floats without integer part)
  4. Negative SKIP/LIMIT validation:

    • RETURN 1 SKIP -1 (should fail)

📊 Performance

List concatenation creates new instances on every + operation. This is correct for immutability but consider documenting the copy-on-write semantics.


🔒 Security

No major security concerns identified. The changes handle null inputs safely and validate negative SKIP/LIMIT values appropriately.


Recommendations Summary

High Priority:

  1. Verify the size() null return change is intentional and document it
  2. Add exception logging in function resolver
  3. Add overflow handling for hex/octal parsing

Medium Priority:

  1. Add unit tests for list slicing, arithmetic, and number parsing
  2. Simplify expression parser spine-walking if possible

Low Priority:

  1. Explain the Arrays.asList() change
  2. Add JavaDoc for unchecked list casts

🎯 Overall Assessment

This is solid work that significantly improves OpenCypher TCK compliance. The code is generally well-structured and follows the project's coding standards. The main concerns are around:

  1. Breaking behavioral changes (size() returning null)
  2. Expression parser complexity
  3. Test coverage for edge cases

Approval Status:Approve with minor changes recommended

Great progress on TCK compliance! 🚀

Copy link
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 introduces a substantial set of fixes and enhancements to the OpenCypher implementation, significantly improving its compliance with the TCK. The changes are well-structured and address several key areas.

The most significant improvement is the refactoring of CypherExpressionBuilder to correctly handle operator precedence using a spine-walk approach, which is a robust solution for expression parsing. This, along with added support for more numeric literal formats (hex, octal, scientific notation) and list slicing, greatly enhances the expression evaluation capabilities.

Function handling has also been improved. The changes in FunctionCallExpression and CypherExecutionPlan to support function execution within complex expressions (like CASE or logical operators) is a critical fix for correctness. The addition of list concatenation with the + operator and the coalesce() function, as well as fixes to keys(), properties(), and size(), are also valuable additions.

The change in result formatting in FinalProjectionStep to align with standard Cypher behavior (where RETURN n yields a result with a column 'n') is a good step towards interoperability, even if it's a breaking change.

Finally, the added semantic validations for variable scopes, boolean operands, and negative SKIP/LIMIT values make the query engine more robust and user-friendly by catching errors early.

Overall, this is a high-quality contribution that makes major strides in the correctness and completeness of the OpenCypher implementation. The code is clean and the changes are well-reasoned.

@codacy-production
Copy link

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
-11.54% 50.70%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (44fdfa6) 78224 54547 69.73%
Head commit (25d73b7) 108047 (+29823) 62878 (+8331) 58.20% (-11.54%)

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 (#3362) 284 144 50.70%

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

@codecov
Copy link

codecov bot commented Feb 7, 2026

Codecov Report

❌ Patch coverage is 32.04225% with 193 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.21%. Comparing base (44fdfa6) to head (25d73b7).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ery/opencypher/parser/CypherExpressionBuilder.java 38.63% 43 Missing and 38 partials ⚠️
...dedb/query/opencypher/ast/ListSliceExpression.java 0.00% 51 Missing ⚠️
...ery/opencypher/executor/CypherFunctionFactory.java 4.76% 18 Missing and 2 partials ⚠️
...ery/opencypher/parser/CypherSemanticValidator.java 41.17% 12 Missing and 8 partials ⚠️
...edb/query/opencypher/ast/ArithmeticExpression.java 0.00% 13 Missing and 1 partial ⚠️
...b/query/opencypher/ast/FunctionCallExpression.java 63.63% 1 Missing and 3 partials ⚠️
...query/opencypher/executor/CypherExecutionPlan.java 72.72% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3362      +/-   ##
==========================================
+ Coverage   61.05%   61.21%   +0.15%     
==========================================
  Files        1165     1166       +1     
  Lines       78224    78483     +259     
  Branches    15412    15507      +95     
==========================================
+ Hits        47763    48041     +278     
+ Misses      23707    23593     -114     
- Partials     6754     6849      +95     

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

@lvca lvca added this to the 26.2.1 milestone Feb 7, 2026
robfrank pushed a commit that referenced this pull request Feb 17, 2026
* test: including official opencypher tck

* fix: fixed many issues with opencypher from TCK tests

* fix: fixed broken tests from OpenCyphr TCK

* fix: more opencypher issues from tck tests

* fix: opencypher tck more tests pass now

Reached much better compliance with the latest changes:

```
=======================================================
         OpenCypher TCK Compliance Report
=======================================================
Total scenarios:  3897
Passed:           1908 (48%)
Failed:           1939 (49%)
Skipped:          50 (1%)
-------------------------------------------------------
By category:
  clauses/call                               2/ 52 passed (3%)
  clauses/create                            64/ 78 passed (82%)
  clauses/delete                            24/ 41 passed (58%)
  clauses/match                            292/381 passed (76%)
  clauses/match-where                       25/ 34 passed (73%)
  clauses/merge                             47/ 75 passed (62%)
  clauses/remove                            29/ 33 passed (87%)
  clauses/return                            35/ 63 passed (55%)
  clauses/return-orderby                    23/ 35 passed (65%)
  clauses/return-skip-limit                 26/ 31 passed (83%)
  clauses/set                               30/ 53 passed (56%)
  clauses/union                              8/ 12 passed (66%)
  clauses/unwind                            10/ 14 passed (71%)
  clauses/with                              14/ 29 passed (48%)
  clauses/with-orderBy                     124/292 passed (42%)
  clauses/with-skip-limit                    7/  9 passed (77%)
  clauses/with-where                        10/ 19 passed (52%)
  expressions/aggregation                   23/ 35 passed (65%)
  expressions/boolean                      150/150 passed (100%)
  expressions/comparison                    36/ 72 passed (50%)
  expressions/conditional                   13/ 13 passed (100%)
  expressions/existentialSubqueries          4/ 10 passed (40%)
  expressions/graph                         32/ 61 passed (52%)
  expressions/list                         120/185 passed (64%)
  expressions/literals                     120/131 passed (91%)
  expressions/map                           28/ 44 passed (63%)
  expressions/mathematical                   3/  6 passed (50%)
  expressions/null                          44/ 44 passed (100%)
  expressions/path                           0/  7 passed (0%)
  expressions/pattern                       19/ 50 passed (38%)
  expressions/precedence                    20/121 passed (16%)
  expressions/quantifier                   478/604 passed (79%)
  expressions/string                        22/ 32 passed (68%)
  expressions/temporal                       0/1004 passed (0%)
  expressions/typeConversion                19/ 47 passed (40%)
  useCases/countingSubgraphMatches           6/ 11 passed (54%)
  useCases/triadicSelection                  1/ 19 passed (5%)
=======================================================
```

(cherry picked from commit a8a3f37)
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