Skip to content

Conversation

@xav-db
Copy link
Member

@xav-db xav-db commented Feb 8, 2026

Greptile Overview

Greptile Summary

This PR adds a new INTERSECT traversal step to HelixQL end-to-end: Pest grammar support, parser StepType::Intersect, analyzer validation and codegen, plus a new engine adapter (IntersectAdapter) and multiple test fixtures (engine-level Rust tests and HQL tests).

At runtime, the engine implementation collects upstream items, executes a provided sub-traversal closure per item to get candidate results, then returns only values whose IDs appear in every sub-result set (set intersection semantics). The generator emits .intersect(|val, db, txn, arena| { G::from_iter(..) <substeps> ... }) to wire the HQL syntax to the engine adapter.

Main issue to address before merge: one existing HQL test (user_test_12) changes the meaning of GetIndicatorsWithTimeParams from “has any matching time parameter” to “connected to all matching time parameters provided”, which will change expected results when multiple time_vals are passed and should be clarified/adjusted.

Important Files Changed

Filename Overview
helix-db/src/grammar.pest Adds INTERSECT(_::<traversal>) as a new util step in the Pest grammar.
helix-db/src/helix_engine/tests/traversal_tests/intersect_tests.rs Adds engine-level Rust tests for IntersectAdapter across several graph scenarios.
helix-db/src/helix_engine/tests/traversal_tests/mod.rs Registers the new intersect test module.
helix-db/src/helix_engine/traversal_core/ops/util/intersect.rs Introduces IntersectAdapter for RoTraversalIterator; currently collects upstream and sub-traversal results and intersects by id.
helix-db/src/helix_engine/traversal_core/ops/util/mod.rs Exports the new util::intersect module.
helix-db/src/helixc/analyzer/methods/traversal_validation.rs Adds analyzer support for StepType::Intersect by inferring sub-traversal type and emitting generator step.
helix-db/src/helixc/generator/traversal_steps.rs Adds generator Step::Intersect and emits intersect(...) closure code (currently drops sub-traversal errors).
helix-db/src/helixc/generator/utils.rs Imports IntersectAdapter into generated code prelude.
helix-db/src/helixc/parser/graph_step_parse_methods.rs Parses intersect_step into StepType::Intersect using parse_expression.
helix-db/src/helixc/parser/types.rs Adds StepType::Intersect and updates PartialEq accordingly.
hql-tests/tests/intersect/helix.toml Adds new HQL test project config for intersect feature.
hql-tests/tests/intersect/queries.hx Adds HQL queries that use INTERSECT to find articles by all tags.
hql-tests/tests/intersect/schema.hx Defines Tag/Article/HasTag schema for intersect tests.
hql-tests/tests/search_v_with_embed/queries.hx Updates test query to take item param and pass it to Embed().
hql-tests/tests/user_test_12/queries.hx Replaces EXISTS-based semantics with INTERSECT-based query; changes meaning from 'any matching time parameter' to 'all matching time parameters'.
hql-tests/tests/user_test_12/queries.rs Adds generated Rust code for user_test_12; includes new intersect usage and embedded schema/config.

Sequence Diagram

sequenceDiagram
    participant User as HQL User
    participant Parser as helixc parser (pest)
    participant Analyzer as helixc analyzer
    participant Gen as helixc generator
    participant Engine as traversal engine

    User->>Parser: Parse traversal with ::INTERSECT(_::<sub-traversal>)
    Parser->>Analyzer: Emit StepType::Intersect(Expression)
    Analyzer->>Analyzer: infer_expr_type(expr, Some(cur_ty))
    Analyzer->>Gen: GenerateStep::Intersect { traversal }
    Gen->>Engine: Emit Rust: .intersect(|val, db, txn, arena| G::from_iter(..).<substeps>...)
    Engine->>Engine: Collect upstream values
    loop for each upstream value
        Engine->>Engine: Run sub-traversal closure => Vec<TraversalValue>
    end
    Engine->>Engine: Intersect result sets by TraversalValue.id()
    Engine-->>User: Iterator of intersected TraversalValue results
Loading

@xav-db xav-db changed the title Intersect feat(hql): Intersect function Feb 8, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

10 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@xav-db
Copy link
Member Author

xav-db commented Feb 8, 2026

@greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

16 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 8, 2026

Additional Comments (1)

hql-tests/tests/user_test_12/queries.hx
Semantic change in test

GetIndicatorsWithTimeParams was changed from EXISTS(_::Out<HasTimeParameter>::WHERE(...)) ("indicator has at least one matching time parameter") to N<TimeParameter>::...::INTERSECT(_::In<HasTimeParameter>) ("indicator is connected to all matching time parameters in time_vals"). This will produce different results whenever time_vals has >1 entry (e.g., an indicator linked to only one of them used to match, now it won’t). If the intent is to preserve the old behavior, this should stay as EXISTS; if the intent is a behavior change, the test name/fixture should be updated to reflect the new contract.

@xav-db xav-db merged commit b945501 into dev Feb 8, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant