graphforge 0.3.2__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {graphforge-0.3.2 → graphforge-0.3.4}/CHANGELOG.md +128 -1
- graphforge-0.3.4/CLAUDE.md +430 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/PKG-INFO +22 -14
- {graphforge-0.3.2 → graphforge-0.3.4}/README.md +21 -13
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/implementation-status/clauses.md +15 -10
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/implementation-status/functions.md +13 -14
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/implementation-status/operators.md +38 -30
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/implementation-status/patterns.md +43 -26
- {graphforge-0.3.2 → graphforge-0.3.4}/pyproject.toml +1 -1
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/__init__.py +1 -1
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/ast/clause.py +19 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/ast/expression.py +20 -1
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/executor/evaluator.py +109 -2
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/executor/executor.py +69 -15
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/parser/cypher.lark +19 -4
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/parser/parser.py +64 -6
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/planner/operators.py +20 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/planner/planner.py +32 -1
- graphforge-0.3.4/tests/integration/test_call_subqueries.py +294 -0
- graphforge-0.3.4/tests/integration/test_pattern_comprehension.py +361 -0
- graphforge-0.3.4/tests/integration/test_power_operator.py +309 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_string_functions.py +195 -0
- graphforge-0.3.4/tests/integration/test_xor_operator.py +235 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_parser.py +52 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/uv.lock +1 -1
- graphforge-0.3.2/CLAUDE.md +0 -899
- {graphforge-0.3.2 → graphforge-0.3.4}/.codecov.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.coderabbit.yaml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.editorconfig +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/CODEOWNERS +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_TEMPLATE/question.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/ISSUE_WORKFLOW.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/SECURITY.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/dependabot.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/pull_request_template.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/README.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/changelog-check.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/docs.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/pr-labeler.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/publish.yaml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/release-tracking.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.github/workflows/test.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.gitignore +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/.pre-commit-config.yaml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/CHANGELOG_v0.3.0.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/CODE_OF_CONDUCT.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/CONTRIBUTING.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/IMPLEMENTATION_PLAN.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/LICENSE +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/Makefile +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/RELEASING.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/coverage.json +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/architecture/ast-and-planning.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/architecture/execution-model.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/architecture/overview.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/architecture/storage-analysis.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/architecture/storage.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/community/code-of-conduct.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/community/security.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/cypher-guide.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/datasets/cypher-script-loading.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/datasets/ldbc.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/datasets/neo4j-examples.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/datasets/networkrepository.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/datasets/overview.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/datasets/snap.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/QUICKSTART_V0.2.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/codecov-integration.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/contributing.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/documentation-update-summary.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/phase-1a-completion-report.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/release-process.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/release-strategy.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/requirements.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-2026-01-31-cicd-infrastructure.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-2026-01-31-documentation.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-2026-01-31-regression-fix.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-2026-01-31-with-clause.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-2026-02-01-codecov-setup.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-2026-02-01-column-naming-investigation.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/session-summary.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/tck-session-2026-01-31-final.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/sessions/tck-session-2026-01-31.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/tck_baseline_analysis_v0.3.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/testing-setup-complete.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/testing.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/v0.2-plan-summary.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/v0.4-revised-plan.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/development/workflow.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/getting-started/installation.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/getting-started/quickstart.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/getting-started/tutorial.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/guide/cypher-guide.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/guide/graph-construction.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/guide/overview.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/index.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/INCOMPLETE_FEATURES_ISSUES.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/README.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/RELEASE_TRACKING.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/VALIDATION_REPORT.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/api.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/changelog.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/column-naming-behavior.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-aggregation-functions.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-graph-queries.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-graph-schema.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-mapping/clause-to-tck.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-mapping/function-to-tck.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-order-by.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/feature-return-aliasing.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-compatibility-matrix.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-compatibility.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-features/01-clauses.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-features/02-functions.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-features/03-operators.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-features/04-patterns.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/opencypher-features/05-data-types.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/tck-compliance.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/reference/tck-inventory.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/releases/implementation-summary.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/releases/next-steps.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/releases/phase-1-complete.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/releases/phase-2-complete.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/releases/phase-3-complete.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/releases/roadmap.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/stylesheets/extra.css +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/docs/use-cases/agent-grounding.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/01_social_network.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/02_knowledge_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/03_data_lineage.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/04_citation_network.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/05_migration_from_networkx.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/agent_grounding/ecommerce_agent.ipynb +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/basic_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/examples/basic_usage.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/mkdocs.yml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/scripts/build_feature_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/scripts/bump_version.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/scripts/check_release_needed.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/scripts/inventory_tck.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/scripts/pre-push-check.sh +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/scripts/validate_datasets.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/api.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/ast/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/ast/pattern.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/ast/query.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/base.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/data/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/data/networkrepository.json +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/data/snap.json +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/exporters/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/exporters/json_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/formats/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/formats/json_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/compression.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/csv.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/cypher.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/graphml.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/json_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/ldbc.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/loaders/ldbc_schema.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/registry.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/sources/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/sources/graphml.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/sources/json_graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/sources/ldbc.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/sources/networkrepository.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/datasets/sources/snap.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/executor/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/optimizer/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/optimizer/cost_model.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/optimizer/join_reorder.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/optimizer/optimizer.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/optimizer/predicate_utils.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/optimizer/statistics.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/parser/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/planner/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/planner/types.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/storage/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/storage/memory.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/storage/pydantic_serialization.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/storage/serialization.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/storage/sqlite_backend.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/types/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/types/graph.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/src/graphforge/types/values.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/README.md +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/conftest.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/conftest.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_compression.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_cypher_loader_docs.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_end_to_end_workflows.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_graphml_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_json_graph_exporter.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_json_graph_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_json_graph_roundtrip.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_ldbc_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/datasets/test_networkrepository_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/executor/test_graph_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_aggregation_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_aggregation_functions_advanced.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_arithmetic.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_builder_api.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_case_expressions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_collect.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_column_naming.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_complex_merge_patterns.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_complex_where_predicates.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_create_clause.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_create_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_delete_null.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_detach_delete.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_distinct_clause.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_e2e_queries.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_executor_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_exists_is_empty.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_id_function.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_label_disjunction.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_list_comprehension.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_list_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_list_operations.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_list_path_overloading.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_list_subscript.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_logical_operators.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_match_create.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_math_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_merge_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_merge_on_create_real.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_merge_on_match_real.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_null_handling.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_optimizer_aggregate_pushdown.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_optimizer_integration.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_optimizer_redundant_elimination.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_optional_match.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_optional_match_delete.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_path_binding.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_path_binding_variable_length.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_path_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_pattern_predicates.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_persistence.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_predicate_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_relationship_directions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_remove_clause.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_set_delete_merge.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_size_function.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_snap_dataset_loading.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_sort_after_aggregation.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_spatial_api.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_sqlite_persistence.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_string_functions_new.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_string_matching.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_subquery_expressions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_temporal_map_constructors.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_temporal_queries.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_transactions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_type_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_union.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_unwind.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_variable_length_paths.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_wildcard_execution.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_with_aggregation_real.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_with_clause.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_with_clause_modifiers.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/integration/test_with_distinct_skip_limit.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/property/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/property/strategies.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/conftest.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/coverage_matrix.json +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/download_tck.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/Aggregation1_BasicAggregation.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/Match1_SimpleMatches.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/call/Call1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/call/Call2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/call/Call3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/call/Call4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/call/Call5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/call/Call6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/create/Create1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/create/Create2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/create/Create3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/create/Create4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/create/Create5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/create/Create6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/delete/Delete1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/delete/Delete2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/delete/Delete3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/delete/Delete4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/delete/Delete5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/delete/Delete6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match/Match9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match-where/MatchWhere1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match-where/MatchWhere2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match-where/MatchWhere3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match-where/MatchWhere4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match-where/MatchWhere5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/match-where/MatchWhere6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/merge/Merge9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/remove/Remove1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/remove/Remove2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/remove/Remove3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return/Return8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-orderby/ReturnOrderBy6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-skip-limit/ReturnSkipLimit1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-skip-limit/ReturnSkipLimit2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/return-skip-limit/ReturnSkipLimit3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/set/Set1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/set/Set2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/set/Set3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/set/Set4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/set/Set5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/set/Set6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/union/Union1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/union/Union2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/union/Union3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/unwind/Unwind1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with/With7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-orderBy/WithOrderBy4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-skip-limit/WithSkipLimit1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-skip-limit/WithSkipLimit2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-skip-limit/WithSkipLimit3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/clauses/with-where/WithWhere7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/aggregation/Aggregation8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/boolean/Boolean1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/boolean/Boolean2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/boolean/Boolean3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/boolean/Boolean4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/boolean/Boolean5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/comparison/Comparison1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/comparison/Comparison2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/comparison/Comparison3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/comparison/Comparison4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/conditional/Conditional1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/conditional/Conditional2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/existentialSubqueries/ExistentialSubquery1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/existentialSubqueries/ExistentialSubquery2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/existentialSubqueries/ExistentialSubquery3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/graph/Graph9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List10.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List11.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List12.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/list/List9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/literals/Literals8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/map/Map1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/map/Map2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/map/Map3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical10.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical11.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical12.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical13.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical14.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical15.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical16.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical17.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/mathematical/Mathematical9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/null/Null1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/null/Null2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/null/Null3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/path/Path1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/path/Path2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/path/Path3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/pattern/Pattern1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/pattern/Pattern2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/precedence/Precedence1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/precedence/Precedence2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/precedence/Precedence3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/precedence/Precedence4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier10.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier11.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier12.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/quantifier/Quantifier9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String10.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String11.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String12.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String13.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String14.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/string/String9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal10.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal7.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal8.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/temporal/Temporal9.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/typeConversion/TypeConversion1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/typeConversion/TypeConversion2.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/typeConversion/TypeConversion3.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/typeConversion/TypeConversion4.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/typeConversion/TypeConversion5.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/expressions/typeConversion/TypeConversion6.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/useCases/countingSubgraphMatches/CountingSubgraphMatches1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/features/official/useCases/triadicSelection/TriadicSelection1.feature +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/graphs/binary-tree-1/binary-tree-1.cypher +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/graphs/binary-tree-1/binary-tree-1.json +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/graphs/binary-tree-2/binary-tree-2.cypher +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/graphs/binary-tree-2/binary-tree-2.json +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/graphs/named-graphs.adoc +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/tck_config.yaml +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/tck_markers.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/test_features.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/test_official_tck.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/tck/test_tck_compliance.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/api/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/api/test_cypher_value_conversion.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/ast/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/ast/test_ast_nodes.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_csv_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_cypher_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_graphml_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_json_graph_exporter.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_json_graph_format.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_json_graph_loader.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_ldbc_schema.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_networkrepository.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_registry.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_snap_datasets.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/datasets/test_sources_registration.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_aggregation_errors.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_aggregation_functions_advanced.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_arithmetic_evaluator.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_evaluator.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_evaluator_additional_coverage.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_evaluator_error_paths.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_executor_error_paths.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_expression_matching.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_expressions_match.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_graph_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_id_function.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_in_operator.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_list_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_list_functions_errors.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_map_property_access.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_merge_on_create.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_merge_on_match.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_multihop_create.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_optional_scan_coverage.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_path_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_sort_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_spatial_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_string_functions_new.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_string_matching_evaluator.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_subquery_planner_check.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_temporal_functions.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_temporal_truncate_arithmetic.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_three_valued_logic.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_type_conversion_complex.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_undirected_relationship_bugs.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/executor/test_with_aggregation.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_aggregate_pushdown.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_cost_model.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_filter_pushdown.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_join_reorder.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_predicate_reorder.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_predicate_utils.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_redundant_elimination.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/optimizer/test_statistics.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_arithmetic_parser.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_case_parser.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_collect_parser.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_delete_parser.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_grammar.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_merge_on_create.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_merge_on_match.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_optional_match_delete.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_path_binding.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_pattern_predicates.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_remove_parser.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_string_matching_parser.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_wildcard_parsing.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/parser/test_with_at_query_start.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_expand_multi_hop_operator.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_operator_validation.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_operators.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_planner_branch_coverage.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_planner_comprehensive.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_planner_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_remove_planner.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_type_tracking.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/planner/test_with_validation.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/__init__.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_graph_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_memory_store.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_pydantic_serialization.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_serialization_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_spatial_serialization.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_sqlite_backend_adjacency.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/storage/test_temporal_serialization.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/test_graph_elements.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/test_values.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/types/test_cypher_values_deep_equality.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/types/test_cypher_values_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/types/test_graph_element_edge_cases.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/types/test_path_values.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/types/test_spatial_values.py +0 -0
- {graphforge-0.3.2 → graphforge-0.3.4}/tests/unit/types/test_temporal_values.py +0 -0
|
@@ -5,7 +5,134 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.3.4] - 2026-02-18
|
|
9
|
+
|
|
10
|
+
### Added - Power Arithmetic Operator (#213)
|
|
11
|
+
- **^ (power/exponentiation) operator** - Full exponentiation support
|
|
12
|
+
- Right-associative: `2^3^2 = 2^(3^2) = 512`
|
|
13
|
+
- Highest arithmetic precedence (above `*`, `/`)
|
|
14
|
+
- Type handling: `int^int` returns int if whole, else float
|
|
15
|
+
- Negative exponents: `2^-1 = 0.5`
|
|
16
|
+
- Fractional exponents: `4^0.5 = 2.0`
|
|
17
|
+
- NULL propagation for both operands
|
|
18
|
+
- 39 integration tests covering associativity, precedence, types, and edge cases
|
|
19
|
+
|
|
20
|
+
### Added - XOR Logical Operator (#212)
|
|
21
|
+
- **XOR operator** - Exclusive OR with proper ternary logic
|
|
22
|
+
- `true XOR false = true`, `true XOR true = false`
|
|
23
|
+
- Precedence: NOT > AND > XOR > OR
|
|
24
|
+
- NULL propagation: any NULL operand yields NULL
|
|
25
|
+
- Left-associative chaining: `a XOR b XOR c`
|
|
26
|
+
- Case-insensitive keyword (`XOR`, `xor`, `Xor`)
|
|
27
|
+
- 22 integration tests + 4 unit tests
|
|
28
|
+
|
|
29
|
+
### Documentation - Feature Completion Updates
|
|
30
|
+
|
|
31
|
+
#### Already-Implemented Features Now Documented (#193, #214, #215)
|
|
32
|
+
- **length() function** - Documented as COMPLETE for paths
|
|
33
|
+
- `length(path)` returns relationship count in path
|
|
34
|
+
- For strings/lists, use `size()` function instead
|
|
35
|
+
- File: `src/graphforge/executor/evaluator.py:2604`
|
|
36
|
+
- **List slicing [start..end]** - Documented as COMPLETE
|
|
37
|
+
- Example: `RETURN [1, 2, 3, 4, 5][1..3]` → `[2, 3]`
|
|
38
|
+
- Supports open-ended slicing: `[..]`, `[1..]`, `[..3]`
|
|
39
|
+
- File: `src/graphforge/executor/evaluator.py:1458`
|
|
40
|
+
- **Negative list indexing** - Documented as COMPLETE
|
|
41
|
+
- Example: `RETURN [1, 2, 3][-1]` → `3` (last element)
|
|
42
|
+
- Supports both index and slice operations: `[1, 2, 3][-2..-1]`
|
|
43
|
+
- File: `src/graphforge/executor/evaluator.py:1458`
|
|
44
|
+
|
|
45
|
+
### Added - String Function Aliases
|
|
46
|
+
|
|
47
|
+
#### toUpper()/toLower() camelCase variants (#194)
|
|
48
|
+
- **toUpper(string)** - CamelCase alias for UPPER(), converts string to uppercase
|
|
49
|
+
- Example: `RETURN toUpper('hello') AS result` -> `'HELLO'`
|
|
50
|
+
- **toLower(string)** - CamelCase alias for LOWER(), converts string to lowercase
|
|
51
|
+
- Example: `RETURN toLower('HELLO') AS result` -> `'hello'`
|
|
52
|
+
- Both camelCase and legacy forms (UPPER/LOWER) supported
|
|
53
|
+
- Case-insensitive keywords: toUpper, TOUPPER, toLower, TOLOWER all work
|
|
54
|
+
- 18 new integration tests (7 toUpper + 7 toLower + 4 interop)
|
|
55
|
+
|
|
56
|
+
### Implementation Status Updates
|
|
57
|
+
- Functions: 58/72 (81%, +3%) - String functions now 13/13 (100%)
|
|
58
|
+
- Operators: 32/34 (94%, +6%) - All list operators now COMPLETE
|
|
59
|
+
- Documentation reflects actual implementation status
|
|
60
|
+
|
|
61
|
+
## [0.3.3] - 2026-02-18
|
|
62
|
+
|
|
63
|
+
### Added - Pattern & CALL Features (Feature Completion: 88%)
|
|
64
|
+
|
|
65
|
+
#### Pattern Predicates - COMPLETE (#216)
|
|
66
|
+
- **Inline WHERE in patterns** - Filter relationships during pattern matching
|
|
67
|
+
- Example: `MATCH ()-[r:KNOWS WHERE r.since > 2020]->(f) RETURN f.name`
|
|
68
|
+
- Property comparisons, complex expressions (AND, OR, NOT)
|
|
69
|
+
- Function calls in predicates, NULL handling
|
|
70
|
+
- Variable-length paths with predicates
|
|
71
|
+
- Works with undirected relationships
|
|
72
|
+
- 16 comprehensive integration tests
|
|
73
|
+
|
|
74
|
+
#### CALL Subqueries - COMPLETE (#189)
|
|
75
|
+
- **General CALL { } subquery support** - Execute nested queries with full openCypher syntax
|
|
76
|
+
- Example: `CALL { MATCH (p:Person) RETURN p.name AS name } RETURN name`
|
|
77
|
+
- **Correlated scoping:** Access outer variables from parent query
|
|
78
|
+
- **UNION support:** CALL can contain UNION and UNION ALL queries
|
|
79
|
+
- **Unit subqueries:** Preserve 1:1 cardinality for side-effect queries
|
|
80
|
+
- **Nested CALL:** Support for CALL within CALL
|
|
81
|
+
- **Multiple CALL:** Cartesian product of multiple subqueries
|
|
82
|
+
- 13 comprehensive integration tests
|
|
83
|
+
|
|
84
|
+
#### Pattern Comprehension - COMPLETE (#217)
|
|
85
|
+
- **Pattern-based list operations** - Transform graph patterns into lists
|
|
86
|
+
- Example: `[(p:Person) WHERE p.age > 18 | p.name]`
|
|
87
|
+
- Simple node patterns: `[(p:Person) | p.name]`
|
|
88
|
+
- Relationship patterns: `[(p)-[:KNOWS]->(f) | f.name]`
|
|
89
|
+
- Optional WHERE filters for pattern results
|
|
90
|
+
- Complex expressions in map clause
|
|
91
|
+
- Correlated variables from outer scope
|
|
92
|
+
- Nested in RETURN, WHERE, WITH clauses
|
|
93
|
+
- NULL property handling
|
|
94
|
+
- 15 comprehensive integration tests
|
|
95
|
+
|
|
96
|
+
### Implementation
|
|
97
|
+
|
|
98
|
+
**AST Nodes:**
|
|
99
|
+
- PatternComprehension (expression.py) - pattern, filter_expr, map_expr
|
|
100
|
+
- CallClause (clause.py) - nested query support
|
|
101
|
+
|
|
102
|
+
**Grammar (cypher.lark):**
|
|
103
|
+
- pattern_comprehension rule with optional WHERE
|
|
104
|
+
- call_clause and call_query rules
|
|
105
|
+
- Pattern WHERE predicates already existed, now fully documented
|
|
106
|
+
|
|
107
|
+
**Parser (parser.py):**
|
|
108
|
+
- pattern_comprehension transformer
|
|
109
|
+
- call_clause and call_query transformers
|
|
110
|
+
- Enhanced list_literal to handle pattern comprehension
|
|
111
|
+
|
|
112
|
+
**Planner (planner.py):**
|
|
113
|
+
- Call operator with UNION support
|
|
114
|
+
- TypeContext preservation for nested queries
|
|
115
|
+
|
|
116
|
+
**Executor (executor.py, evaluator.py):**
|
|
117
|
+
- _execute_call with correlated scoping and unit subquery detection
|
|
118
|
+
- PatternComprehension evaluation via temporary MATCH execution
|
|
119
|
+
- Pattern predicate evaluation in relationship matching (already existed)
|
|
120
|
+
|
|
121
|
+
### Testing
|
|
122
|
+
- 44 new integration tests (16 + 13 + 15)
|
|
123
|
+
- All tests passing with 100% coverage on new code
|
|
124
|
+
- TCK pass rate: ~40% (1,530 / 3,837 tests)
|
|
125
|
+
|
|
126
|
+
### Documentation
|
|
127
|
+
- Updated patterns.md: 100% completion (8/8 pattern types)
|
|
128
|
+
- Updated clauses.md: CALL marked as COMPLETE
|
|
129
|
+
- All features documented with examples and implementation references
|
|
130
|
+
- Feature completion: 85% → 88% (+3 features)
|
|
131
|
+
|
|
132
|
+
### Performance
|
|
133
|
+
- No performance regressions
|
|
134
|
+
- Pattern comprehension uses existing pattern matching infrastructure
|
|
135
|
+
- CALL subqueries properly isolated with TypeContext.copy()
|
|
9
136
|
|
|
10
137
|
## [0.3.2] - 2026-02-17
|
|
11
138
|
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
GraphForge is an embedded, openCypher-compatible graph database for Python, designed for research and analysis workflows. It prioritizes **correctness over performance** and provides declarative querying with automatic persistence via SQLite.
|
|
8
|
+
|
|
9
|
+
**Not a production database** - optimized for interactive analysis on small-to-medium graphs (< 10M nodes).
|
|
10
|
+
|
|
11
|
+
**Core Use Cases:**
|
|
12
|
+
- **AI Agent Grounding**: Ground LLM agents in ontologies with tool definitions for semantic, deterministic action (see `docs/use-cases/agent-grounding.md`)
|
|
13
|
+
- **Knowledge Graph Construction**: Extract and refine entities/relationships from unstructured data
|
|
14
|
+
- **Network Analysis**: Analyze social networks, dependencies, citation graphs in notebooks
|
|
15
|
+
- **LLM-Powered Workflows**: Store and query structured outputs from language models
|
|
16
|
+
|
|
17
|
+
## Development Workflow (CRITICAL)
|
|
18
|
+
|
|
19
|
+
**Every piece of work MUST follow this workflow. No exceptions.**
|
|
20
|
+
|
|
21
|
+
### 1. Create an Issue First
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gh issue create --title "feat: add UNWIND clause support" \
|
|
25
|
+
--body "Description..." --label "enhancement"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Never start work without an issue. If you discover out-of-scope work, create a NEW issue and continue with current work.
|
|
29
|
+
|
|
30
|
+
### 2. Create Branch with Issue Number
|
|
31
|
+
|
|
32
|
+
**Format:** `<type>/<issue-number>-<short-description>`
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git checkout -b feature/42-unwind-clause
|
|
36
|
+
|
|
37
|
+
# Branch types: feature/, fix/, docs/, refactor/, test/
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3. Do the Work with Comprehensive Tests
|
|
41
|
+
|
|
42
|
+
- Unit tests for each layer (parser, planner, executor)
|
|
43
|
+
- Integration tests for end-to-end behavior
|
|
44
|
+
- Aim for 100% coverage on new code (90% minimum)
|
|
45
|
+
|
|
46
|
+
### 4. Run Pre-Push Checks
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
make pre-push
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Runs: format-check, lint, type-check, coverage (85% total, 90% patch).
|
|
53
|
+
|
|
54
|
+
### 5. Commit with Issue Number
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git commit -m "feat: implement UNWIND clause (#42)
|
|
58
|
+
|
|
59
|
+
- Add UNWIND grammar rule to cypher.lark
|
|
60
|
+
- Implement UnwindClause AST node
|
|
61
|
+
- Add planner support for Unwind operator
|
|
62
|
+
- Implement executor logic for list iteration
|
|
63
|
+
- Add 15 unit tests + 8 integration tests
|
|
64
|
+
|
|
65
|
+
All tests passing, coverage at 100% for new code."
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 6. Create PR with "Closes #XX"
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
gh pr create --title "feat: implement UNWIND clause" \
|
|
72
|
+
--body "Closes #42"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
GitHub automatically closes the issue when PR merges.
|
|
76
|
+
|
|
77
|
+
## Development Commands
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
make pre-push # Run all checks (mirrors CI)
|
|
81
|
+
make test # All tests
|
|
82
|
+
make test-unit # Unit tests only
|
|
83
|
+
make test-integration # Integration tests only
|
|
84
|
+
make coverage # Run with coverage
|
|
85
|
+
make coverage-report # View HTML coverage report
|
|
86
|
+
make coverage-diff # Coverage for changed files only
|
|
87
|
+
|
|
88
|
+
# Run tests in parallel (4x faster for TCK)
|
|
89
|
+
pytest tests/ -n auto
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Coverage Requirements:**
|
|
93
|
+
- Total: 85% minimum
|
|
94
|
+
- Patch: 90% minimum for changed files
|
|
95
|
+
- Best practice: Aim for 100% on new code
|
|
96
|
+
|
|
97
|
+
## Architecture: 4-Layer System
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
User Code (Python API / Cypher)
|
|
101
|
+
↓
|
|
102
|
+
┌─────────────────────────────────────────────────┐
|
|
103
|
+
│ 1. Parser (src/graphforge/parser/) │
|
|
104
|
+
│ - cypher.lark: Grammar │
|
|
105
|
+
│ - parser.py: Transformer (Lark → AST) │
|
|
106
|
+
└─────────────────────────────────────────────────┘
|
|
107
|
+
↓
|
|
108
|
+
┌─────────────────────────────────────────────────┐
|
|
109
|
+
│ 2. Planner (src/graphforge/planner/) │
|
|
110
|
+
│ - planner.py: AST → Logical operators │
|
|
111
|
+
│ - operators.py: Operator definitions │
|
|
112
|
+
└─────────────────────────────────────────────────┘
|
|
113
|
+
↓
|
|
114
|
+
┌─────────────────────────────────────────────────┐
|
|
115
|
+
│ 3. Executor (src/graphforge/executor/) │
|
|
116
|
+
│ - executor.py: Operator execution │
|
|
117
|
+
│ - evaluator.py: Expression evaluation │
|
|
118
|
+
└─────────────────────────────────────────────────┘
|
|
119
|
+
↓
|
|
120
|
+
┌─────────────────────────────────────────────────┐
|
|
121
|
+
│ 4. Storage (src/graphforge/storage/) │
|
|
122
|
+
│ - memory.py: In-memory graph │
|
|
123
|
+
│ - sqlite_backend.py: SQLite persistence │
|
|
124
|
+
│ - serialization.py: MessagePack encoding │
|
|
125
|
+
└─────────────────────────────────────────────────┘
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Key Principles
|
|
129
|
+
|
|
130
|
+
1. **Each layer is independent** - Parser knows nothing about execution
|
|
131
|
+
2. **AST is the contract** - Parser produces AST, planner consumes it
|
|
132
|
+
3. **Operators are composable** - Planner emits list, executor chains them
|
|
133
|
+
4. **Storage is pluggable** - Executor uses Graph interface
|
|
134
|
+
|
|
135
|
+
### Adding Cypher Features
|
|
136
|
+
|
|
137
|
+
**You must modify ALL four layers:**
|
|
138
|
+
|
|
139
|
+
1. **Parser:** Add grammar to `cypher.lark` + transformer in `parser.py`
|
|
140
|
+
2. **AST:** Add/modify dataclasses in `src/graphforge/ast/`
|
|
141
|
+
3. **Planner:** Update `planner.py` to emit operators
|
|
142
|
+
4. **Executor:** Implement execution in `executor.py`
|
|
143
|
+
|
|
144
|
+
**Decision matrix:**
|
|
145
|
+
- 1-2 layers affected: Simpler, focused changes
|
|
146
|
+
- 3-4 layers affected: More complex, comprehensive changes
|
|
147
|
+
- Extensive tests needed: Plan for thorough test coverage
|
|
148
|
+
- New to feature: Take time to understand the architecture
|
|
149
|
+
|
|
150
|
+
## Critical Code Patterns
|
|
151
|
+
|
|
152
|
+
### Value Types System
|
|
153
|
+
|
|
154
|
+
All query results use `CypherValue` wrappers:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
# src/graphforge/types/values.py
|
|
158
|
+
CypherString, CypherInt, CypherFloat, CypherBool, CypherNull
|
|
159
|
+
CypherList, CypherMap
|
|
160
|
+
|
|
161
|
+
# Always wrap results in executor
|
|
162
|
+
return CypherString("hello")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Pydantic Validation
|
|
166
|
+
|
|
167
|
+
All AST nodes, operators, and metadata use **Pydantic v2 BaseModel**:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
class BinaryOp(BaseModel):
|
|
171
|
+
op: str = Field(...)
|
|
172
|
+
left: Any = Field(...)
|
|
173
|
+
right: Any = Field(...)
|
|
174
|
+
|
|
175
|
+
@field_validator("op")
|
|
176
|
+
@classmethod
|
|
177
|
+
def validate_op(cls, v: str) -> str:
|
|
178
|
+
if v not in {"=", "<>", "<", ">", "<=", ">=", "AND", "OR", ...}:
|
|
179
|
+
raise ValueError(f"Unsupported operator: {v}")
|
|
180
|
+
return v
|
|
181
|
+
|
|
182
|
+
model_config = {"frozen": True} # Immutable
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Key patterns:**
|
|
186
|
+
- Always use keyword arguments (Pydantic v2 requirement)
|
|
187
|
+
- Use `@field_validator` for single-field validation
|
|
188
|
+
- Use `@model_validator(mode="after")` for cross-field validation
|
|
189
|
+
- All AST nodes are frozen (immutable)
|
|
190
|
+
|
|
191
|
+
**When to use:**
|
|
192
|
+
- Pydantic: AST nodes, operators, metadata (needs validation)
|
|
193
|
+
- Dataclasses: NodeRef, EdgeRef, CypherValue (performance-critical)
|
|
194
|
+
|
|
195
|
+
### Two Serialization Systems
|
|
196
|
+
|
|
197
|
+
**System 1: SQLite + MessagePack (Graph Data)**
|
|
198
|
+
- Purpose: Store nodes, edges, properties
|
|
199
|
+
- Location: `src/graphforge/storage/serialization.py`
|
|
200
|
+
- Format: Binary (fast, compact)
|
|
201
|
+
- Use for: Runtime graph operations
|
|
202
|
+
|
|
203
|
+
**System 2: Pydantic + JSON (Metadata)**
|
|
204
|
+
- Purpose: Store dataset metadata, schemas, ontologies
|
|
205
|
+
- Location: `src/graphforge/storage/pydantic_serialization.py`
|
|
206
|
+
- Format: JSON (human-readable, validatable)
|
|
207
|
+
- Use for: Configuration, dataset definitions
|
|
208
|
+
|
|
209
|
+
**CRITICAL:** Never mix these systems. Graph data → MessagePack. Metadata → JSON.
|
|
210
|
+
|
|
211
|
+
### Graph Storage Duality
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
# In-memory (fast, volatile)
|
|
215
|
+
gf = GraphForge()
|
|
216
|
+
|
|
217
|
+
# Persistent (SQLite backend)
|
|
218
|
+
gf = GraphForge("path/to/db.db")
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Transaction Handling
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
# Auto-commit (default)
|
|
225
|
+
gf.execute("CREATE (n:Person)")
|
|
226
|
+
|
|
227
|
+
# Explicit transactions
|
|
228
|
+
gf.begin()
|
|
229
|
+
gf.execute("CREATE (n:Person)")
|
|
230
|
+
gf.execute("CREATE (m:Person)")
|
|
231
|
+
gf.commit() # or rollback()
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Dataset System
|
|
235
|
+
|
|
236
|
+
Registry pattern in `src/graphforge/datasets/`:
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
datasets/
|
|
240
|
+
├── base.py # DatasetInfo model
|
|
241
|
+
├── registry.py # Global registry
|
|
242
|
+
├── loaders/ # Format-specific loaders
|
|
243
|
+
│ ├── csv.py
|
|
244
|
+
│ └── cypher.py
|
|
245
|
+
└── sources/ # Dataset registrations
|
|
246
|
+
├── snap.py
|
|
247
|
+
└── __init__.py # Auto-registers
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Testing Strategy
|
|
251
|
+
|
|
252
|
+
### Test Organization
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
tests/
|
|
256
|
+
├── unit/ # Fast, isolated (< 1ms)
|
|
257
|
+
│ ├── parser/
|
|
258
|
+
│ ├── planner/
|
|
259
|
+
│ ├── executor/
|
|
260
|
+
│ └── storage/
|
|
261
|
+
├── integration/ # End-to-end Cypher queries
|
|
262
|
+
├── tck/ # OpenCypher TCK compliance
|
|
263
|
+
│ ├── features/ # Gherkin scenarios
|
|
264
|
+
│ └── steps/ # pytest-bdd steps
|
|
265
|
+
└── property/ # Hypothesis property tests
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Writing Tests
|
|
269
|
+
|
|
270
|
+
**Unit tests** - Test ONE component in isolation:
|
|
271
|
+
```python
|
|
272
|
+
def test_parse_simple_match():
|
|
273
|
+
query = "MATCH (n:Person) RETURN n"
|
|
274
|
+
ast = parse_cypher(query)
|
|
275
|
+
assert isinstance(ast.clauses[0], MatchClause)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Integration tests** - Test end-to-end:
|
|
279
|
+
```python
|
|
280
|
+
def test_match_returns_nodes():
|
|
281
|
+
gf = GraphForge()
|
|
282
|
+
gf.execute("CREATE (:Person {name: 'Alice'})")
|
|
283
|
+
results = gf.execute("MATCH (p:Person) RETURN p.name AS name")
|
|
284
|
+
assert results[0]['name'].value == 'Alice'
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**TCK tests** - Gherkin syntax:
|
|
288
|
+
```gherkin
|
|
289
|
+
Scenario: Match simple node
|
|
290
|
+
Given an empty graph
|
|
291
|
+
When executing query:
|
|
292
|
+
"""
|
|
293
|
+
CREATE (n:Person {name: 'Alice'})
|
|
294
|
+
"""
|
|
295
|
+
Then the result should be empty
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Test Parametrization
|
|
299
|
+
|
|
300
|
+
Use for testing same logic with different inputs:
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
@pytest.mark.parametrize("op,left,right,expected", [
|
|
304
|
+
("=", 5, 5, True),
|
|
305
|
+
("<>", 5, 10, True),
|
|
306
|
+
("<", 5, 10, True),
|
|
307
|
+
])
|
|
308
|
+
def test_comparison_operators(op, left, right, expected):
|
|
309
|
+
gf = GraphForge()
|
|
310
|
+
result = gf.execute(f"RETURN {left} {op} {right} AS result")
|
|
311
|
+
assert result[0]['result'].value == expected
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Property-Based Testing
|
|
315
|
+
|
|
316
|
+
Use Hypothesis for testing invariants:
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
from hypothesis import given
|
|
320
|
+
from hypothesis import strategies as st
|
|
321
|
+
|
|
322
|
+
@given(st.integers(), st.text(), st.booleans())
|
|
323
|
+
def test_cypher_value_roundtrip(int_val, str_val, bool_val):
|
|
324
|
+
"""CypherValues serialize and deserialize correctly."""
|
|
325
|
+
values = [CypherInt(int_val), CypherString(str_val), CypherBool(bool_val)]
|
|
326
|
+
for val in values:
|
|
327
|
+
serialized = serialize_value(val)
|
|
328
|
+
deserialized = deserialize_value(serialized)
|
|
329
|
+
assert deserialized == val
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Test Isolation
|
|
333
|
+
|
|
334
|
+
Always use fresh fixtures:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
# ✅ Good - Each test gets fresh graph
|
|
338
|
+
def test_create_node(empty_graph):
|
|
339
|
+
empty_graph.execute("CREATE (:Person)")
|
|
340
|
+
assert len(empty_graph.execute("MATCH (n) RETURN n")) == 1
|
|
341
|
+
|
|
342
|
+
# ❌ Bad - Shared mutable state
|
|
343
|
+
graph = GraphForge()
|
|
344
|
+
def test_create_node():
|
|
345
|
+
graph.execute("CREATE (:Person)") # Pollutes state
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Common Development Tasks
|
|
349
|
+
|
|
350
|
+
### Adding a New Cypher Clause
|
|
351
|
+
|
|
352
|
+
1. Grammar: Add to `cypher.lark`
|
|
353
|
+
2. AST: Add dataclass to `ast/clause.py`
|
|
354
|
+
3. Transformer: Add method to `parser.py`
|
|
355
|
+
4. Planner: Update to emit operator
|
|
356
|
+
5. Operator: Add to `operators.py`
|
|
357
|
+
6. Executor: Implement execution
|
|
358
|
+
7. Tests: Unit + integration tests
|
|
359
|
+
|
|
360
|
+
### Adding a New Function
|
|
361
|
+
|
|
362
|
+
1. Grammar: Add to `function_call` rule in `cypher.lark`
|
|
363
|
+
2. Evaluator: Implement in `executor/evaluator.py`
|
|
364
|
+
3. Tests: Unit + integration tests
|
|
365
|
+
|
|
366
|
+
### Fixing Parser Issues
|
|
367
|
+
|
|
368
|
+
1. Check grammar: `src/graphforge/parser/cypher.lark` (EBNF syntax)
|
|
369
|
+
2. Check transformer: `parser.py` (methods match rule names)
|
|
370
|
+
3. Debug with: `tree.pretty()` to see parse tree structure
|
|
371
|
+
|
|
372
|
+
### Fixing Executor Issues
|
|
373
|
+
|
|
374
|
+
**Common problems:**
|
|
375
|
+
1. Not wrapping values as `CypherValue` instances
|
|
376
|
+
2. Not handling NULL (use ternary logic)
|
|
377
|
+
3. Mutating input rows (always create new contexts)
|
|
378
|
+
4. Not checking bound variables
|
|
379
|
+
|
|
380
|
+
**Debug with logging:**
|
|
381
|
+
```python
|
|
382
|
+
import logging
|
|
383
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
384
|
+
gf.execute("MATCH (n) RETURN n") # See operator pipeline
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Important Files
|
|
388
|
+
|
|
389
|
+
### Entry Points
|
|
390
|
+
- `src/graphforge/api.py` - Main `GraphForge` class
|
|
391
|
+
- `src/graphforge/__init__.py` - Public exports
|
|
392
|
+
|
|
393
|
+
### Core Grammar
|
|
394
|
+
- `src/graphforge/parser/cypher.lark` - Complete Cypher grammar
|
|
395
|
+
|
|
396
|
+
### Type Definitions
|
|
397
|
+
- `src/graphforge/types/values.py` - CypherValue type system
|
|
398
|
+
- `src/graphforge/types/graph.py` - NodeRef/EdgeRef handles
|
|
399
|
+
|
|
400
|
+
### Storage
|
|
401
|
+
- `src/graphforge/storage/memory.py` - Graph interface + in-memory
|
|
402
|
+
- `src/graphforge/storage/sqlite_backend.py` - SQLite persistence
|
|
403
|
+
- `src/graphforge/storage/serialization.py` - MessagePack encoding
|
|
404
|
+
|
|
405
|
+
## Documentation
|
|
406
|
+
|
|
407
|
+
Full docs in `docs/`:
|
|
408
|
+
- `docs/reference/opencypher-compatibility.md` - Feature matrix
|
|
409
|
+
- `docs/datasets/` - Dataset integration docs
|
|
410
|
+
- `docs/tutorial.md` - Getting started guide
|
|
411
|
+
|
|
412
|
+
Generated docs: `mkdocs serve` (requires `uv sync --group docs`)
|
|
413
|
+
|
|
414
|
+
## CI/CD
|
|
415
|
+
|
|
416
|
+
GitHub Actions (`.github/workflows/`):
|
|
417
|
+
- `test.yml` - Runs on all PRs (same as `make pre-push`)
|
|
418
|
+
- `codecov.yml` - Coverage reporting
|
|
419
|
+
- `test-analytics.yml` - Test performance tracking
|
|
420
|
+
|
|
421
|
+
All tests must pass + coverage thresholds met before merge.
|
|
422
|
+
|
|
423
|
+
## Project Philosophy
|
|
424
|
+
|
|
425
|
+
1. **Correctness over performance** - Match openCypher semantics exactly
|
|
426
|
+
2. **Inspectability** - Simple, debuggable code over clever optimizations
|
|
427
|
+
3. **Modularity** - Each layer independent and replaceable
|
|
428
|
+
4. **Developer experience** - Clear errors, good defaults, zero config
|
|
429
|
+
|
|
430
|
+
**Not goals:** High throughput, massive graphs, production deployment
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphforge
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Composable graph tooling for analysis, construction, and refinement
|
|
5
5
|
Project-URL: Homepage, https://github.com/DecisionNerd/graphforge
|
|
6
6
|
Project-URL: Repository, https://github.com/DecisionNerd/graphforge
|
|
@@ -98,19 +98,25 @@ Modern data science and ML workflows increasingly produce **graph-shaped data**
|
|
|
98
98
|
> *We are not building a database for applications.*
|
|
99
99
|
> *We are building a graph execution environment for thinking.*
|
|
100
100
|
|
|
101
|
-
### Latest Release: v0.3.
|
|
101
|
+
### Latest Release: v0.3.4
|
|
102
102
|
|
|
103
|
-
Version 0.3.
|
|
103
|
+
Version 0.3.4 completes operator and string function enhancements:
|
|
104
104
|
|
|
105
|
-
- **
|
|
106
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **
|
|
109
|
-
- **
|
|
105
|
+
- **String functions**: `toUpper()`, `toLower()` camelCase variants - Aliases for existing UPPER/LOWER functions
|
|
106
|
+
- **Logical operators**: `XOR` - Exclusive OR with proper precedence (NOT > AND > XOR > OR) and NULL handling
|
|
107
|
+
- **Arithmetic operators**: `^` (power/exponentiation) - Right-associative with full numeric support (negative and fractional exponents)
|
|
108
|
+
- **List operations**: List slicing `[start..end]` and negative indexing `list[-1]` (already implemented, now documented)
|
|
109
|
+
- **Comprehensive testing**: 79 new integration tests (18 string, 22 XOR, 39 power)
|
|
110
|
+
- **Operator completion**: List operators 100% (5/5), Overall operators 94% (32/34, up from 88%)
|
|
111
|
+
- **Function progress**: 56/72 functions (78%, up from 76%)
|
|
110
112
|
|
|
111
|
-
**Previous
|
|
113
|
+
**Previous Releases**:
|
|
114
|
+
- **v0.3.3**: Pattern comprehensions, CALL subqueries, Pattern predicates
|
|
115
|
+
- **v0.3.2**: List operations (`filter()`, `extract()`, `reduce()`)
|
|
116
|
+
- **v0.3.1**: Quantifier functions (`all()`, `any()`, `none()`, `single()`), `exists()`, `isEmpty()`
|
|
117
|
+
- **v0.3.0**: OPTIONAL MATCH, UNION, List comprehensions, EXISTS/COUNT subqueries, Variable-length paths, 109+ datasets
|
|
112
118
|
|
|
113
|
-
**TCK Coverage**:
|
|
119
|
+
**TCK Coverage**: ~38% openCypher compatibility
|
|
114
120
|
|
|
115
121
|
See [CHANGELOG.md](CHANGELOG.md) for complete release notes.
|
|
116
122
|
|
|
@@ -1396,10 +1402,11 @@ GraphForge implements a **practical subset of OpenCypher** focused on common gra
|
|
|
1396
1402
|
|
|
1397
1403
|
**Expressions:**
|
|
1398
1404
|
- CASE expressions (conditional logic)
|
|
1399
|
-
- Arithmetic operators: +, -, *, /,
|
|
1405
|
+
- Arithmetic operators: +, -, *, /, %, ^ (power)
|
|
1400
1406
|
- Comparison operators: =, <>, <, >, <=, >=
|
|
1401
|
-
- Logical operators: AND, OR, NOT
|
|
1407
|
+
- Logical operators: AND, OR, XOR, NOT
|
|
1402
1408
|
- String matching: STARTS WITH, ENDS WITH, CONTAINS
|
|
1409
|
+
- List operations: Slicing `[start..end]`, negative indexing `list[-1]`
|
|
1403
1410
|
|
|
1404
1411
|
**Aggregations:**
|
|
1405
1412
|
- COUNT, SUM, AVG, MIN, MAX, COLLECT
|
|
@@ -1407,11 +1414,12 @@ GraphForge implements a **practical subset of OpenCypher** focused on common gra
|
|
|
1407
1414
|
- DISTINCT modifier
|
|
1408
1415
|
|
|
1409
1416
|
**Functions:**
|
|
1410
|
-
- String: length, substring, toUpper,
|
|
1411
|
-
- Type conversion: toInteger, toFloat, toString
|
|
1417
|
+
- String: length, substring, toUpper/toLower (both camelCase and UPPERCASE variants), trim, reverse, split, replace, left, right, ltrim, rtrim
|
|
1418
|
+
- Type conversion: toInteger, toFloat, toString, toBoolean
|
|
1412
1419
|
- Spatial: point, distance
|
|
1413
1420
|
- Temporal: date, datetime, time, duration
|
|
1414
1421
|
- Graph: id, labels, type
|
|
1422
|
+
- Predicates: all, any, none, single, exists, isEmpty
|
|
1415
1423
|
- Utility: coalesce
|
|
1416
1424
|
|
|
1417
1425
|
**Data Types:**
|