Documentation
¶
Overview ¶
Package ir defines the logical plan intermediate representation (IR) for the Cypher query compiler. It covers the operator set described in Marton (2017), "An optimising Cypher to SQL compiler", adjusted for the openCypher 9 subset supported by this module.
Logical Plan ¶
A logical plan is a tree of LogicalPlan nodes. Each node is a concrete operator that knows its children and the set of variable names it introduces or requires. Leaf operators (AllNodesScan, NodeByLabelScan, etc.) have no children; unary operators (Selection, Projection, etc.) have exactly one child; binary operators (Apply, Union, etc.) have exactly two children.
The IR is produced by the planner after semantic analysis and consumed by the optimiser and code-generation stages.
Operator taxonomy ¶
Scan operators read rows from the graph store:
- Argument — injects bindings passed from an outer subplan
- AllNodesScan — full node scan
- NodeByLabelScan — scan nodes with a specific label
- NodeByIndexSeek — exact-match index lookup
- NodeByIndexRangeScan — range-scan index lookup
Traversal operators follow relationships:
- Expand — single-hop relationship expansion
- OptionalExpand — left-outer-join expansion (OPTIONAL MATCH)
- VarLengthExpand — variable-length path expansion
- ProjectEndpoints — project start/end nodes of a relationship variable
Filter and projection operators reshape the row stream:
- Selection — WHERE predicate
- Projection — RETURN / WITH column computation
- EagerAggregation — GROUP BY + aggregate functions
- Sort — ORDER BY
- Top — ORDER BY … LIMIT (fused operator)
- Limit — LIMIT
- Skip — SKIP
- Distinct — DISTINCT deduplication
Set operators combine row streams:
Apply-family operators implement correlated subplan evaluation:
- Apply — correlated join (inner must produce ≥1 row)
- SemiApply — EXISTS-style filter (keep outer if inner non-empty)
- AntiSemiApply — NOT EXISTS-style filter (keep outer if inner empty)
- RollUpApply — collect inner rows into a list column
Pipeline operators control evaluation order and data flow:
- Eager — full materialisation barrier
- Unwind — list expansion (UNWIND)
- ProduceResults — root operator; defines the result columns
Write operators mutate the graph:
- CreateNode — CREATE (node)
- CreateRelationship — CREATE (relationship)
- SetProperty — SET n.prop = expr
- SetLabels — SET n:Label
- RemoveProperty — REMOVE n.prop
- RemoveLabels — REMOVE n:Label
- DeleteNode — DELETE node
- DeleteRelationship — DELETE relationship
- DetachDelete — DETACH DELETE node
- Merge — MERGE pattern
Procedure operators call stored procedures:
- ProcedureCall — CALL procedure(…) YIELD …
Concurrency ¶
Logical plan nodes are immutable value trees constructed by the planner. Concurrent reads are safe without external locking. Nodes must not be mutated after construction.
Index ¶
- func ContainsDelete(p LogicalPlan) bool
- func ContainsWrite(p LogicalPlan) bool
- func Explain(plan LogicalPlan) string
- func IsDDL(query string) bool
- func NextArgTag() uint32
- func OperatorName(plan LogicalPlan) string
- type AggregateExpr
- type AllNodesScan
- type AntiSemiApply
- type Apply
- type Argument
- type Bound
- type ConstraintKind
- type CorrelatedApply
- type CreateConstraint
- type CreateIndex
- type CreateNode
- type CreateRelationship
- type DeleteNode
- type DeleteRelationship
- type DetachDelete
- type Direction
- type Distinct
- type DropConstraint
- type DropIndex
- type Eager
- type EagerAggregation
- type Expand
- type IndexType
- type KVAction
- type Limit
- type LogicalPlan
- type Merge
- type MergeRelationship
- type NamedPath
- type NodeByIndexRangeScan
- type NodeByIndexSeek
- type NodeByLabelScan
- type OptionalApply
- type OptionalExpand
- type PathChainElement
- type ProcedureCall
- type ProduceResults
- type ProjectEndpoints
- type Projection
- type ProjectionItem
- type RemoveLabels
- type RemoveProperty
- type RollUpApply
- type Selection
- type SemiApply
- type SetAllProperties
- func NewSetAllPropertiesFromEntity(entityVar, sourceVar string, isReplace bool, child LogicalPlan) *SetAllProperties
- func NewSetAllPropertiesFromMap(entityVar, mapLiteral string, isReplace bool, child LogicalPlan) *SetAllProperties
- func NewSetAllPropertiesFromParam(entityVar, paramName string, isReplace bool, child LogicalPlan) *SetAllProperties
- type SetLabels
- type SetProperty
- type Skip
- type Sort
- type SortItem
- type SubqueryCount
- type SubqueryExists
- type Top
- type TranslateError
- type Union
- type UnionAll
- type Unwind
- type VarLengthExpand
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContainsDelete ¶
func ContainsDelete(p LogicalPlan) bool
ContainsDelete reports whether p's subtree contains any DELETE-class operator. Used to decide whether a subsequent MERGE needs an Eager pipeline-breaker so the deletion's writes are visible to the MERGE-search (Merge1 [14]).
func ContainsWrite ¶
func ContainsWrite(p LogicalPlan) bool
ContainsWrite walks p and reports whether any node in the tree is a write operator (CreateNode, CreateRelationship, SetProperty, SetAllProperties, SetLabels, RemoveProperty, RemoveLabels, DeleteNode, DeleteRelationship, DetachDelete, Merge, MergeRelationship). The walk is depth-first; nil plans return false.
func Explain ¶
func Explain(plan LogicalPlan) string
Explain returns a human-readable tree representation of plan, mirroring the style of Neo4j's textual EXPLAIN output. Each line shows the operator name and the variables it introduces or requires. A "-" placeholder occupies the cardinality column, which will be populated by the PROFILE stage in Sprint 28.
Tree edges use box-drawing characters (├─, └─, │) for clarity. The output is deterministic for a given plan tree.
Example:
ProduceResults [n] └─ Projection [n] └─ NodeByLabelScan [n:Person]
Example ¶
ExampleExplain renders a logical plan as a human-readable operator tree.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/GoGraph/cypher/ir"
"github.com/FlavioCFOliveira/GoGraph/cypher/parser"
)
func main() {
q, err := parser.Parse("MATCH (n:Person) RETURN n")
if err != nil {
fmt.Println("error:", err)
return
}
plan, err := ir.FromAST(q)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Print(ir.Explain(plan))
}
Output: ProduceResults [n] └─ Projection [n] └─ NodeByLabelScan [n:Person]
func IsDDL ¶
IsDDL returns true when query (trimmed, case-insensitive) begins with a known DDL keyword that the lightweight DDL parser handles.
func NextArgTag ¶
func NextArgTag() uint32
NextArgTag is the exported wrapper around [nextArgTag]. It is used by the outer cypher package's subquery evaluator (cypher/subquery_eval.go) when it needs to mint a fresh Argument tag while compiling an EXISTS / COUNT subquery's inner plan outside the regular IR-translator path.
func OperatorName ¶
func OperatorName(plan LogicalPlan) string
OperatorName returns the canonical display name for the logical plan operator. It is the exported counterpart of the internal operatorName helper used by Explain, exposed so callers outside this package can render individual nodes (e.g. the Engine's physical-plan explain renderer).
Types ¶
type AggregateExpr ¶
type AggregateExpr struct {
// OutputName is the variable name assigned to the aggregate result.
OutputName string
// Function is the aggregate function name (e.g. "count", "sum", "avg").
Function string
// Argument is the expression argument to the aggregate function. An empty
// string corresponds to count(*).
Argument string
// ArgumentExpr is the parsed AST for the aggregate argument, when available.
// Non-nil when the argument is a non-trivial expression (property access,
// function call, …); when nil, callers fall back to schema lookup keyed on
// Argument or supply the constant Null. count(*) keeps ArgumentExpr == nil.
ArgumentExpr ast.Expression
// SecondArgExpr captures the second argument of two-arg aggregates
// (percentileCont, percentileDisc). The value is constant across the
// aggregation (it parameterises the factory, not the per-row Step) and
// is evaluated once at physical-build time, typically from a parameter
// or a literal.
SecondArgExpr ast.Expression
// Distinct indicates whether the DISTINCT qualifier is applied inside the
// aggregate (e.g. count(DISTINCT n)).
Distinct bool
}
AggregateExpr is a named aggregate function in an EagerAggregation operator.
type AllNodesScan ¶
type AllNodesScan struct {
// NodeVar is the variable name bound to each scanned node.
NodeVar string
}
AllNodesScan scans every node in the graph and binds each to NodeVar.
func NewAllNodesScan ¶
func NewAllNodesScan(nodeVar string) *AllNodesScan
NewAllNodesScan creates an AllNodesScan operator.
func (*AllNodesScan) Children ¶
func (a *AllNodesScan) Children() []LogicalPlan
Children implements LogicalPlan. AllNodesScan is a leaf; it returns nil.
type AntiSemiApply ¶
type AntiSemiApply struct {
// Outer is the driving subplan.
Outer LogicalPlan
// Inner is the correlated non-existence-check subplan; its leftmost leaf
// must be an [Argument] whose Tag equals [AntiSemiApply.ArgTag].
Inner LogicalPlan
// ArgTag is the tag shared with the inner-side Argument leaf so that the
// physical builder can route the matching exec.Argument instance.
ArgTag uint32
}
AntiSemiApply implements a NOT EXISTS-style filter: outer rows are kept only when Inner produces zero result rows for the given outer bindings.
func NewAntiSemiApply ¶
func NewAntiSemiApply(outer, inner LogicalPlan) *AntiSemiApply
NewAntiSemiApply creates an AntiSemiApply operator with a freshly issued Argument tag.
func NewAntiSemiApplyWithTag ¶
func NewAntiSemiApplyWithTag(outer, inner LogicalPlan, tag uint32) *AntiSemiApply
NewAntiSemiApplyWithTag creates an AntiSemiApply with an explicit tag.
func (*AntiSemiApply) Children ¶
func (a *AntiSemiApply) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
func (*AntiSemiApply) Vars ¶
func (a *AntiSemiApply) Vars() []string
Vars implements LogicalPlan. Only outer variables are visible downstream.
type Apply ¶
type Apply struct {
// Outer is the driving (left) subplan.
Outer LogicalPlan
// Inner is the correlated (right) subplan.
Inner LogicalPlan
}
Apply is a correlated join: for each row produced by Outer, Inner is evaluated with the outer bindings injected (via an Argument leaf). The combined row is emitted only when Inner produces at least one result row.
func (*Apply) Children ¶
func (a *Apply) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
type Argument ¶
type Argument struct {
// Variables holds the variable names that are injected from the outer scope.
Variables []string
// Tag uniquely identifies this Argument node so the physical builder can
// route the matching [exec.Argument] instance from an enclosing
// [CorrelatedApply] or [OptionalApply]. Tags are assigned at construction
// time and are stable for the lifetime of the node.
Tag uint32
}
Argument injects a set of variable bindings from an outer subplan into an inner subplan. It is the leaf node on the inner side of Apply-family operators.
func NewArgument ¶
NewArgument creates an Argument operator with the given injected variables and a freshly allocated [Argument.Tag].
func NewArgumentWithTag ¶
NewArgumentWithTag creates an Argument operator with the given variables and an explicit tag. It is used by IR-building helpers that need the inner-side Argument to share a tag with an enclosing Apply-family operator.
func (*Argument) Children ¶
func (a *Argument) Children() []LogicalPlan
Children implements LogicalPlan. Argument is a leaf; it returns nil.
type Bound ¶
type Bound struct {
// Value is the opaque string representation of the bound expression.
Value string
// Inclusive reports whether the bound is inclusive (≤/≥) or exclusive (</>).
Inclusive bool
}
Bound is an optional inclusive bound used in range-scan operators. A nil pointer means the bound is absent (open-ended range).
type ConstraintKind ¶
type ConstraintKind uint8
ConstraintKind distinguishes UNIQUE from NOT_NULL constraints.
const ( // ConstraintUnique requires that at most one node with a given label has a // particular value for the constrained property. ConstraintUnique ConstraintKind = iota // ConstraintNotNull requires that every node with a given label has a // non-null value for the constrained property. ConstraintNotNull )
type CorrelatedApply ¶
type CorrelatedApply struct {
Outer LogicalPlan
// [Argument] whose Tag equals [CorrelatedApply.ArgTag].
Inner LogicalPlan
// physical builder can route the matching exec.Argument instance.
ArgTag uint32
}
CorrelatedApply is a dependent join in which the inner subplan starts with an Argument leaf re-emitting the outer row. Unlike Apply, the physical executor for CorrelatedApply forwards the inner row verbatim and does not concatenate it with the outer row — the outer columns are already present in the inner row's leading positions.
CorrelatedApply is used for multi-pattern MATCH where subsequent patterns share at least one variable with a previously bound pattern: the shared variable acts as a join key implicit in the dataflow.
func NewCorrelatedApply ¶
func NewCorrelatedApply(outer, inner LogicalPlan) *CorrelatedApply
NewCorrelatedApply creates a CorrelatedApply operator with a freshly issued Argument tag. The caller is responsible for placing an Argument node carrying the same tag at the leftmost leaf of inner.
func NewCorrelatedApplyWithTag ¶
func NewCorrelatedApplyWithTag(outer, inner LogicalPlan, tag uint32) *CorrelatedApply
NewCorrelatedApplyWithTag creates a CorrelatedApply with an explicit tag. Use when constructing the IR top-down and threading the tag into the inner subplan's Argument leaf at the same time.
func (*CorrelatedApply) Children ¶
func (c *CorrelatedApply) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
func (*CorrelatedApply) Vars ¶
func (c *CorrelatedApply) Vars() []string
Vars implements LogicalPlan. The outer variables come first; inner variables not already present are appended.
type CreateConstraint ¶
type CreateConstraint struct {
// Name is the user-defined constraint name.
Name string
// Label is the node label to which the constraint applies.
Label string
// Property is the node property key constrained.
Property string
// Kind is the constraint type (unique or not-null).
Kind ConstraintKind
// IfNotExists suppresses an error when the constraint already exists.
IfNotExists bool
}
CreateConstraint is a DDL plan node representing a Cypher CREATE CONSTRAINT statement.
CreateConstraint is a leaf node; it has no child plan.
func NewCreateConstraint ¶
func NewCreateConstraint(name, label, property string, kind ConstraintKind, ifNotExists bool) *CreateConstraint
NewCreateConstraint creates a CreateConstraint IR node.
func (*CreateConstraint) Children ¶
func (c *CreateConstraint) Children() []LogicalPlan
Children implements LogicalPlan. CreateConstraint is a leaf.
func (*CreateConstraint) Vars ¶
func (c *CreateConstraint) Vars() []string
Vars implements LogicalPlan. CreateConstraint introduces no variables.
type CreateIndex ¶
type CreateIndex struct {
// Name is the user-defined index name, or empty for an auto-named index.
Name string
// Label is the node label on which the index is built.
Label string
// Property is the node property key indexed.
Property string
// Type is the backing index kind (hash or btree).
Type IndexType
// IfNotExists suppresses ErrIndexExists when the index already exists.
IfNotExists bool
}
CreateIndex is a DDL plan node representing a Cypher CREATE INDEX statement.
CreateIndex is a leaf node; it has no child plan.
func NewCreateIndex ¶
func NewCreateIndex(name, label, property string, idxType IndexType, ifNotExists bool) *CreateIndex
NewCreateIndex creates a CreateIndex IR node.
func (*CreateIndex) Children ¶
func (c *CreateIndex) Children() []LogicalPlan
Children implements LogicalPlan. CreateIndex is a leaf.
func (*CreateIndex) Vars ¶
func (c *CreateIndex) Vars() []string
Vars implements LogicalPlan. CreateIndex introduces no variables.
type CreateNode ¶
type CreateNode struct {
// NodeVar is the variable name bound to the newly created node.
NodeVar string
// Labels is the list of labels assigned to the new node.
Labels []string
// Properties is the opaque string representation of the property map
// expression (e.g. "{name: 'Alice'}").
Properties string
// PropertiesExpr is the parsed AST for the property map, when available.
// Non-nil when the property map contains non-literal expressions (variable
// references, property accesses, arithmetic) that must be evaluated at
// runtime against the current row. The physical builder uses PropertiesExpr
// when non-nil to construct a per-row evaluation closure; nil means all
// values were literals and Properties (the string form) is sufficient.
PropertiesExpr ast.Expression
// Child is the driving subplan.
Child LogicalPlan
}
CreateNode creates a new graph node with the given labels and properties, binding it to NodeVar.
func NewCreateNode ¶
func NewCreateNode(nodeVar string, labels []string, properties string, child LogicalPlan) *CreateNode
NewCreateNode creates a CreateNode operator.
func NewCreateNodeExpr ¶
func NewCreateNodeExpr(nodeVar string, labels []string, properties string, propertiesExpr ast.Expression, child LogicalPlan) *CreateNode
NewCreateNodeExpr creates a CreateNode operator with a parsed AST for the property map. Use when the property map contains non-literal expressions that require runtime evaluation.
func (*CreateNode) Children ¶
func (c *CreateNode) Children() []LogicalPlan
Children implements LogicalPlan.
type CreateRelationship ¶
type CreateRelationship struct {
// StartVar is the already-bound source node variable.
StartVar string
// EndVar is the already-bound destination node variable.
EndVar string
// RelVar is the variable name bound to the newly created relationship.
RelVar string
// RelType is the relationship type.
RelType string
// Properties is the opaque string representation of the property map
// expression.
Properties string
// PropertiesExpr is the parsed AST for the property map, when available.
// Non-nil when the property map contains non-literal expressions that must
// be evaluated at runtime against the current row. See CreateNode.PropertiesExpr.
PropertiesExpr ast.Expression
// Child is the driving subplan.
Child LogicalPlan
}
CreateRelationship creates a new graph relationship between two already-bound nodes, binding the new relationship to RelVar.
func NewCreateRelationship ¶
func NewCreateRelationship(startVar, endVar, relVar, relType, properties string, child LogicalPlan) *CreateRelationship
NewCreateRelationship creates a CreateRelationship operator.
func NewCreateRelationshipExpr ¶
func NewCreateRelationshipExpr(startVar, endVar, relVar, relType, properties string, propertiesExpr ast.Expression, child LogicalPlan) *CreateRelationship
NewCreateRelationshipExpr creates a CreateRelationship operator with a parsed AST for the property map.
func (*CreateRelationship) Children ¶
func (c *CreateRelationship) Children() []LogicalPlan
Children implements LogicalPlan.
func (*CreateRelationship) Vars ¶
func (c *CreateRelationship) Vars() []string
Vars implements LogicalPlan.
type DeleteNode ¶
type DeleteNode struct {
// NodeVar is the already-bound node variable to delete.
NodeVar string
// TargetExpr is the parsed AST for the delete target when the target
// is not a bare variable (e.g. `DELETE friends[$i]`, `DELETE map.key`,
// `DELETE coll[0]`). When non-nil the exec builder uses it to evaluate
// the target per row; the resulting NodeValue / IntegerValue identifies
// the node to delete.
TargetExpr ast.Expression
// Child is the driving subplan.
Child LogicalPlan
}
DeleteNode deletes an already-bound node from the graph. The node must have no relationships; use DetachDelete to delete a node together with its relationships.
func NewDeleteNode ¶
func NewDeleteNode(nodeVar string, child LogicalPlan) *DeleteNode
NewDeleteNode creates a DeleteNode operator.
func NewDeleteNodeExpr ¶
func NewDeleteNodeExpr(nodeVar string, targetExpr ast.Expression, child LogicalPlan) *DeleteNode
NewDeleteNodeExpr creates a DeleteNode operator carrying the parsed AST for the delete target. The exec builder evaluates the expression per row when the target is not a bare variable (e.g. `DELETE friends[$i]`, `DELETE map.key`).
func (*DeleteNode) Children ¶
func (d *DeleteNode) Children() []LogicalPlan
Children implements LogicalPlan.
type DeleteRelationship ¶
type DeleteRelationship struct {
// RelVar is the already-bound relationship variable to delete.
RelVar string
// Child is the driving subplan.
Child LogicalPlan
}
DeleteRelationship deletes an already-bound relationship from the graph.
func NewDeleteRelationship ¶
func NewDeleteRelationship(relVar string, child LogicalPlan) *DeleteRelationship
NewDeleteRelationship creates a DeleteRelationship operator.
func (*DeleteRelationship) Children ¶
func (d *DeleteRelationship) Children() []LogicalPlan
Children implements LogicalPlan.
func (*DeleteRelationship) Vars ¶
func (d *DeleteRelationship) Vars() []string
Vars implements LogicalPlan.
type DetachDelete ¶
type DetachDelete struct {
// NodeVar is the already-bound node variable to delete.
NodeVar string
// TargetExpr is the parsed AST for the delete target when the target
// is not a bare variable (e.g. `DETACH DELETE friends[$i]`,
// `DETACH DELETE map.key`). Same role as DeleteNode.TargetExpr.
TargetExpr ast.Expression
// Child is the driving subplan.
Child LogicalPlan
}
DetachDelete deletes an already-bound node and all its incident relationships.
func NewDetachDelete ¶
func NewDetachDelete(nodeVar string, child LogicalPlan) *DetachDelete
NewDetachDelete creates a DetachDelete operator.
func NewDetachDeleteExpr ¶
func NewDetachDeleteExpr(nodeVar string, targetExpr ast.Expression, child LogicalPlan) *DetachDelete
NewDetachDeleteExpr creates a DetachDelete operator carrying the parsed AST for the delete target.
func (*DetachDelete) Children ¶
func (d *DetachDelete) Children() []LogicalPlan
Children implements LogicalPlan.
type Direction ¶
type Direction uint8
Direction is the traversal direction for relationship expansion operators.
type Distinct ¶
type Distinct struct {
// Child is the subplan whose duplicate rows are removed.
Child LogicalPlan
}
Distinct removes duplicate rows from its child's output. Rows are equal when all column values are equal.
func NewDistinct ¶
func NewDistinct(child LogicalPlan) *Distinct
NewDistinct creates a Distinct operator.
func (*Distinct) Children ¶
func (d *Distinct) Children() []LogicalPlan
Children implements LogicalPlan.
type DropConstraint ¶
type DropConstraint struct {
// Name is the constraint name to drop.
Name string
// Label is the node label associated with the constraint.
// May be empty for DROP CONSTRAINT by name only.
Label string
// Property is the constrained property key.
// May be empty for DROP CONSTRAINT by name only.
Property string
// Kind is the constraint type (unique or not-null).
Kind ConstraintKind
// IfExists suppresses an error when the constraint is absent.
IfExists bool
}
DropConstraint is a DDL plan node representing a Cypher DROP CONSTRAINT statement.
DropConstraint is a leaf node; it has no child plan.
func NewDropConstraint ¶
func NewDropConstraint(name, label, property string, kind ConstraintKind, ifExists bool) *DropConstraint
NewDropConstraint creates a DropConstraint IR node.
func (*DropConstraint) Children ¶
func (d *DropConstraint) Children() []LogicalPlan
Children implements LogicalPlan. DropConstraint is a leaf.
func (*DropConstraint) Vars ¶
func (d *DropConstraint) Vars() []string
Vars implements LogicalPlan. DropConstraint introduces no variables.
type DropIndex ¶
type DropIndex struct {
// Name is the index name to drop.
Name string
// IfExists suppresses ErrIndexNotFound when the index is absent.
IfExists bool
}
DropIndex is a DDL plan node representing a Cypher DROP INDEX statement.
DropIndex is a leaf node; it has no child plan.
func NewDropIndex ¶
NewDropIndex creates a DropIndex IR node.
func (*DropIndex) Children ¶
func (d *DropIndex) Children() []LogicalPlan
Children implements LogicalPlan. DropIndex is a leaf.
type Eager ¶
type Eager struct {
// Child is the subplan to materialise.
Child LogicalPlan
}
Eager forces full materialisation of its child's output before producing any rows. It acts as a pipeline-breaking barrier to ensure write-read isolation in queries that both read and write the graph.
type EagerAggregation ¶
type EagerAggregation struct {
// GroupBy is the ordered list of grouping key variable names.
GroupBy []string
// GroupByExprs holds the parsed AST expression for each grouping key, in
// the same order as GroupBy. Entries may be nil for legacy callers that
// only supplied string keys; non-nil entries enable property-access and
// complex expression evaluation at execution time.
GroupByExprs []ast.Expression
// Aggregates is the list of aggregate expressions computed per group.
Aggregates []AggregateExpr
// Child is the subplan whose rows are aggregated.
Child LogicalPlan
}
EagerAggregation groups rows from its child by GroupBy keys and computes aggregate functions over each group.
func NewEagerAggregation ¶
func NewEagerAggregation(groupBy []string, aggregates []AggregateExpr, child LogicalPlan) *EagerAggregation
NewEagerAggregation creates an EagerAggregation operator.
func NewEagerAggregationWithExprs ¶
func NewEagerAggregationWithExprs( groupBy []string, groupByExprs []ast.Expression, aggregates []AggregateExpr, child LogicalPlan, ) *EagerAggregation
NewEagerAggregationWithExprs creates an EagerAggregation operator with parsed AST expressions for the grouping keys. groupBy and groupByExprs must have the same length; entries in groupByExprs may be nil (the executor falls back to a schema lookup keyed on the corresponding groupBy string in that case).
func (*EagerAggregation) Children ¶
func (e *EagerAggregation) Children() []LogicalPlan
Children implements LogicalPlan.
func (*EagerAggregation) Vars ¶
func (e *EagerAggregation) Vars() []string
Vars implements LogicalPlan. The output variables are the grouping keys followed by the aggregate output names.
type Expand ¶
type Expand struct {
// FromVar is the already-bound source node variable.
FromVar string
// RelVar is the variable name bound to the traversed relationship.
RelVar string
// RelTypes is the list of allowed relationship types. An empty slice means
// any type is accepted.
RelTypes []string
// Direction is the traversal direction relative to FromVar.
Direction Direction
// ToVar is the variable name bound to the destination node.
ToVar string
// SiblingRelVars carries the names of relationship variables already bound
// by earlier hops in the SAME MATCH pattern. The physical builder
// translates each name to its schema column and passes the column set as
// the Expand operator's relationship-isomorphism (cyphermorphism) guard,
// so every anonymous or named relationship in one pattern maps to a
// distinct edge per openCypher 9 §3.2.2.
SiblingRelVars []string
// PathVar, when non-empty, is the named-path variable this Expand
// step participates in. Set by applyPathVar for mixed paths
// (Expand + VLE) so the physical builder can record this hop's
// (src, edge, dst) triplet as a leading segment in the same
// pathVarMeta entry the downstream VLE updates — closing the
// "missing leading hop" path-reconstruction gap (Match6 [14]).
PathVar string
// Child is the subplan that produces FromVar.
Child LogicalPlan
}
Expand performs a single-hop relationship expansion from an already-bound FromVar and introduces a RelVar (relationship) and ToVar (destination node).
func NewExpand ¶
func NewExpand(fromVar, relVar string, relTypes []string, dir Direction, toVar string, child LogicalPlan) *Expand
NewExpand creates an Expand operator.
func (*Expand) Children ¶
func (e *Expand) Children() []LogicalPlan
Children implements LogicalPlan.
type KVAction ¶
type KVAction struct {
Key string
Value string // opaque literal string (parsed at physical-build time)
}
KVAction is a (key, value) pair captured by the IR for MERGE ON CREATE / ON MATCH SET items.
type Limit ¶
type Limit struct {
// Count is the maximum number of rows to pass through. Ignored when
// CountExpr is non-nil.
Count int64
// CountExpr is the parsed AST for the LIMIT expression when it is
// not a literal integer (typically a parameter reference like
// $limit). Nil when Count is the authoritative value.
CountExpr ast.Expression
// Child is the subplan whose output is truncated.
Child LogicalPlan
}
Limit truncates the row stream from its child to at most Count rows. When CountExpr is non-nil it overrides Count and the limit is evaluated at physical-build time against the query parameters; this defers parameter resolution so the same cached plan works across calls with different parameter values.
func NewLimit ¶
func NewLimit(count int64, child LogicalPlan) *Limit
NewLimit creates a Limit operator with a literal count.
func NewLimitExpr ¶
func NewLimitExpr(countExpr ast.Expression, child LogicalPlan) *Limit
NewLimitExpr creates a Limit operator whose count is resolved at physical-build time from the given AST expression. countExpr must be a parameter reference or another expression whose evaluation yields an integer.
type LogicalPlan ¶
type LogicalPlan interface {
// Children returns the direct children of this operator. Leaf operators
// return nil. Unary operators return a single-element slice. Binary
// operators return a two-element slice [left, right].
Children() []LogicalPlan
// Vars returns the variable names introduced or required by this operator.
// The order is unspecified but deterministic for a given operator instance.
Vars() []string
}
LogicalPlan is the root interface implemented by every logical-plan operator. Children returns the operator's child plans in evaluation order (left to right for binary operators). Vars returns the set of variable names produced or consumed by this operator.
Concurrency: plan trees are immutable after construction; concurrent reads are safe without external locking.
func FromAST ¶
func FromAST(q ast.Query) (LogicalPlan, error)
FromAST converts a post-parse ast.Query into a LogicalPlan tree following the Marton (2017) algebra. The function dispatches per clause and assembles operators bottom-up.
Unsupported constructs (FOREACH, multi-graph constructs beyond UNION) return a *TranslateError so callers can distinguish them from internal failures.
Concurrency: FromAST is stateless; it is safe to call concurrently.
Example ¶
ExampleFromAST translates a parsed query into a logical plan and prints the canonical name of the root operator.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/GoGraph/cypher/ir"
"github.com/FlavioCFOliveira/GoGraph/cypher/parser"
)
func main() {
q, err := parser.Parse("MATCH (n:Person) RETURN n")
if err != nil {
fmt.Println("error:", err)
return
}
plan, err := ir.FromAST(q)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("root operator:", ir.OperatorName(plan))
}
Output: root operator: ProduceResults
func ParseDDL ¶
func ParseDDL(query string) (LogicalPlan, error)
ParseDDL parses a DDL query string and returns a LogicalPlan (one of *CreateIndex, *DropIndex, *CreateConstraint, *DropConstraint). Returns an error for unrecognised DDL.
func TranslateSubquery ¶
func TranslateSubquery(q *ast.SingleQuery, outerVars []string, argTag uint32) (LogicalPlan, error)
TranslateSubquery translates a single-query AST (the body of an EXISTS / COUNT subquery) into a LogicalPlan rooted at an Argument leaf carrying the supplied correlation variables and ArgTag. The returned plan is suitable as the inner pipeline of a per-row subquery driver.
outerVars is the list of variable names visible from the lexical outer scope at the subquery's call site; they are injected into the inner pipeline through the leading Argument so correlated patterns (e.g. (n)-->() where n is bound outside) observe the outer row's bindings at runtime.
argTag must equal the tag the physical builder will register the seed Argument under in its argByTag map; the leading IR Argument carries this tag so the leaf operator resolves to the same exec.Argument instance.
Concurrency: stateless; safe to call concurrently.
type Merge ¶
type Merge struct {
// Pattern is the opaque string representation of the MERGE pattern.
Pattern string
// OnCreate is the list of update expression strings applied when the pattern
// is created (the ON CREATE SET sub-clause).
OnCreate []string
// OnMatch is the list of update expression strings applied when the pattern
// is matched (the ON MATCH SET sub-clause).
OnMatch []string
// BoundVars lists the variable names that are bound by the MERGE pattern and
// made available downstream.
BoundVars []string
// NodePropsAST carries the property-map AST of the first node pattern in
// the MERGE pattern, when present. The physical builder consults it to
// decide whether the property map contains row-driven expressions (e.g.
// `MERGE (p:Person {login: prop.login})` after an UNWIND) and, if so,
// installs a per-row PropsEvalFn on the [exec.Merge] operator.
// nil when no inline property map is present or when MERGE is shaped as
// a relationship MERGE (handled by [MergeRelationship]).
NodePropsAST ast.Expression
// Child is the driving subplan.
Child LogicalPlan
}
Merge implements the MERGE clause: it matches the given pattern or creates it if absent. OnCreate and OnMatch hold the update expressions applied under each branch (opaque strings; a dedicated expression IR is introduced later).
type MergeRelationship ¶
type MergeRelationship struct {
// SrcVar is the variable name of the source endpoint.
SrcVar string
// DstVar is the variable name of the destination endpoint.
DstVar string
// RelVar is the relationship variable name (may be empty for an
// anonymous relationship).
RelVar string
// RelType is the relationship type label.
RelType string
// RelProps is the opaque map-literal string representation of the
// inline relationship property predicate (e.g. `{name: 'r2'}`). Empty
// when the MERGE pattern declares no inline properties on the
// relationship. When non-empty the exec operator filters the
// search by these properties and writes them on creation.
RelProps string
// Undirected reports whether the MERGE relationship pattern declares
// an undirected hop (`MERGE (a)-[r:T]-(b)`). When true the exec
// operator searches for an existing edge in either direction before
// creating one (closes Merge5 [13]).
Undirected bool
// OnCreate is the list of (key, value) pairs to set on the
// relationship when a new edge is created.
OnCreate []KVAction
// OnMatch is the list of (key, value) pairs to set on the
// relationship when an existing edge is matched.
OnMatch []KVAction
// Child is the driving subplan that binds SrcVar and DstVar.
Child LogicalPlan
}
MergeRelationship is the relationship-pattern variant of Merge. It targets the single-hop MERGE shape `(src)-[r:T]->(dst)` where both endpoints are bound by an upstream operator (a preceding MATCH or CREATE). The physical builder emits an exec.MergeRelationship that checks for an existing edge between the bound endpoints with the requested type and creates one when absent. ON CREATE / ON MATCH actions targeting the relationship variable are applied to the matched-or-created edge.
More elaborate MERGE shapes (multi-hop patterns, inline relationship properties, ON-actions on a different variable, re-asserted endpoint predicates) keep using the node-only Merge path.
func NewMergeRelationship ¶
func NewMergeRelationship(srcVar, dstVar, relVar, relType string, child LogicalPlan) *MergeRelationship
NewMergeRelationship creates a MergeRelationship operator without ON CREATE / ON MATCH actions.
func NewMergeRelationshipWithActions ¶
func NewMergeRelationshipWithActions(srcVar, dstVar, relVar, relType string, onCreate, onMatch []KVAction, child LogicalPlan) *MergeRelationship
NewMergeRelationshipWithActions creates a MergeRelationship that also applies the supplied ON CREATE / ON MATCH actions.
func (*MergeRelationship) Children ¶
func (m *MergeRelationship) Children() []LogicalPlan
Children implements LogicalPlan.
func (*MergeRelationship) Vars ¶
func (m *MergeRelationship) Vars() []string
Vars implements LogicalPlan. The merged relationship introduces its variable into the downstream scope when named.
type NamedPath ¶
type NamedPath struct {
// PathName is the user-visible path variable name (e.g. "p").
PathName string
// Chain is the alternating node/rel description of the pattern, in
// document order. The first entry has IsLeading=true.
Chain []PathChainElement
// Child is the subplan that produces the chain's variables.
Child LogicalPlan
}
NamedPath is a pure pass-through operator that records the structure of a named-path pattern (`p = (a)-[r]->(b)`). Its sole purpose is to convey the alternating node/rel chain from the IR translator down to the physical builder so the projection can reconstruct an [expr.PathValue] by reading the rows emitted by the underlying Expand operators.
Concurrency: immutable after construction; safe for concurrent reads.
func NewNamedPath ¶
func NewNamedPath(pathName string, chain []PathChainElement, child LogicalPlan) *NamedPath
NewNamedPath constructs a NamedPath operator wrapping child. The chain is shallow-copied; element slices (RelTypes) are not deep-copied because callers always pass freshly-allocated slices.
func (*NamedPath) Children ¶
func (n *NamedPath) Children() []LogicalPlan
Children implements LogicalPlan.
type NodeByIndexRangeScan ¶
type NodeByIndexRangeScan struct {
// NodeVar is the variable name bound to each matching node.
NodeVar string
// Label is the indexed node label.
Label string
// Property is the indexed property key.
Property string
// Min is the lower bound (inclusive/exclusive) or nil for an open lower end.
Min *Bound
// Max is the upper bound (inclusive/exclusive) or nil for an open upper end.
Max *Bound
}
NodeByIndexRangeScan performs a range-scan index lookup on a property and binds each matching node to NodeVar. Either Min or Max (or both) must be non-nil; a nil bound means the range is open on that end.
func NewNodeByIndexRangeScan ¶
func NewNodeByIndexRangeScan(nodeVar, label, property string, lower, upper *Bound) *NodeByIndexRangeScan
NewNodeByIndexRangeScan creates a NodeByIndexRangeScan operator.
func (*NodeByIndexRangeScan) Children ¶
func (n *NodeByIndexRangeScan) Children() []LogicalPlan
Children implements LogicalPlan. NodeByIndexRangeScan is a leaf; it returns nil.
func (*NodeByIndexRangeScan) Vars ¶
func (n *NodeByIndexRangeScan) Vars() []string
Vars implements LogicalPlan.
type NodeByIndexSeek ¶
type NodeByIndexSeek struct {
// NodeVar is the variable name bound to each matching node.
NodeVar string
// Label is the indexed node label.
Label string
// Property is the indexed property key.
Property string
// Value is the opaque string representation of the exact-match value.
Value string
}
NodeByIndexSeek performs an exact-match index lookup and binds each matching node to NodeVar.
func NewNodeByIndexSeek ¶
func NewNodeByIndexSeek(nodeVar, label, property, value string) *NodeByIndexSeek
NewNodeByIndexSeek creates a NodeByIndexSeek operator.
func (*NodeByIndexSeek) Children ¶
func (n *NodeByIndexSeek) Children() []LogicalPlan
Children implements LogicalPlan. NodeByIndexSeek is a leaf; it returns nil.
func (*NodeByIndexSeek) Vars ¶
func (n *NodeByIndexSeek) Vars() []string
Vars implements LogicalPlan.
type NodeByLabelScan ¶
type NodeByLabelScan struct {
// NodeVar is the variable name bound to each scanned node.
NodeVar string
// Label is the node label to filter on.
Label string
}
NodeByLabelScan scans nodes that carry a specific label and binds each to NodeVar.
func NewNodeByLabelScan ¶
func NewNodeByLabelScan(nodeVar, label string) *NodeByLabelScan
NewNodeByLabelScan creates a NodeByLabelScan operator.
func (*NodeByLabelScan) Children ¶
func (n *NodeByLabelScan) Children() []LogicalPlan
Children implements LogicalPlan. NodeByLabelScan is a leaf; it returns nil.
func (*NodeByLabelScan) Vars ¶
func (n *NodeByLabelScan) Vars() []string
Vars implements LogicalPlan.
type OptionalApply ¶
type OptionalApply struct {
// Outer is the driving (left) subplan.
Outer LogicalPlan
// Inner is the optional correlated subplan.
Inner LogicalPlan
// ArgTag is the tag shared with the inner-side Argument leaf.
ArgTag uint32
}
OptionalApply is the left-outer variant of CorrelatedApply. When the inner subplan produces zero rows for an outer row, the physical executor emits a single NULL-extended row consisting of the outer columns followed by NULL placeholders for every column the inner pipeline would have introduced.
OptionalApply is used for OPTIONAL MATCH when a non-empty driving subplan already provides the outer bindings (e.g. a preceding MATCH clause).
func NewOptionalApply ¶
func NewOptionalApply(outer, inner LogicalPlan) *OptionalApply
NewOptionalApply creates an OptionalApply operator with a freshly issued Argument tag.
func NewOptionalApplyWithTag ¶
func NewOptionalApplyWithTag(outer, inner LogicalPlan, tag uint32) *OptionalApply
NewOptionalApplyWithTag creates an OptionalApply with an explicit tag.
func (*OptionalApply) Children ¶
func (o *OptionalApply) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
func (*OptionalApply) Vars ¶
func (o *OptionalApply) Vars() []string
Vars implements LogicalPlan. The outer variables come first; inner variables not already present are appended.
type OptionalExpand ¶
type OptionalExpand struct {
// FromVar is the already-bound source node variable.
FromVar string
// RelVar is the variable name bound to the traversed relationship (or null).
RelVar string
// RelTypes is the list of allowed relationship types. An empty slice means
// any type is accepted.
RelTypes []string
// Direction is the traversal direction relative to FromVar.
Direction Direction
// ToVar is the variable name bound to the destination node (or null).
ToVar string
// Child is the subplan that produces FromVar.
Child LogicalPlan
}
OptionalExpand performs a left-outer-join relationship expansion. When no relationship is found the row is kept with RelVar and ToVar bound to null.
func NewOptionalExpand ¶
func NewOptionalExpand(fromVar, relVar string, relTypes []string, dir Direction, toVar string, child LogicalPlan) *OptionalExpand
NewOptionalExpand creates an OptionalExpand operator.
func (*OptionalExpand) Children ¶
func (o *OptionalExpand) Children() []LogicalPlan
Children implements LogicalPlan.
type PathChainElement ¶
type PathChainElement struct {
// NodeVar is the variable name of the (destination) node for this step,
// or "" when the node is anonymous.
NodeVar string
// RelVar is the variable name of the relationship leading into NodeVar,
// or "" when the relationship is anonymous. Empty when IsLeading is true.
RelVar string
// RelTypes carries the relationship type filter declared in the pattern
// (e.g. KNOWS in `-[:KNOWS]->`). Empty when IsLeading is true or when no
// type was specified. Used as a fallback edge type when the live graph
// lookup cannot resolve one.
RelTypes []string
// Direction is the traversal direction relative to the previous node
// (PreviousNode → NodeVar). Meaningful only when IsLeading is false.
Direction Direction
// IsLeading is true for the first element of the chain (the source node
// of the path).
IsLeading bool
}
PathChainElement is one step in a named-path chain. The leading step has IsLeading=true and only NodeVar is meaningful; subsequent steps describe an alternating relationship+destination-node pair: the relationship's RelVar, RelTypes and Direction together with the destination NodeVar.
Anonymous node and relationship variables are conveyed as empty strings; they are not user-projectable but are still required so that the physical builder can locate the matching schema slot emitted by the upstream Expand operator (which always allocates a slot, even for anonymous patterns).
type ProcedureCall ¶
type ProcedureCall struct {
// Namespace is the optional namespace path of the procedure
// (e.g. ["apoc", "algo"] for apoc.algo.dijkstra).
Namespace []string
// Name is the bare procedure name.
Name string
// Arguments is the list of opaque string representations of the call
// argument expressions.
Arguments []string
// YieldVars is the ordered list of variable names produced by the YIELD
// clause. An empty slice means YIELD * (all output columns).
YieldVars []string
// YieldSourceNames is the parallel list of declared procedure-output
// names that each YieldVars entry binds (the LHS in `YIELD col AS alias`,
// or the same name as YieldVars when no AS rename is present). Used by
// the physical builder to map yield aliases to the procedure's declared
// output column index, so `CALL proc(…) YIELD b, a` (procedure declares
// outputs in order a, b) reads each column from the correct slot.
// Empty slice means defaulted to YieldVars (no AS rename).
YieldSourceNames []string
// Child is the driving subplan. May be nil when CALL appears at the start
// of a query.
Child LogicalPlan
}
ProcedureCall invokes a stored procedure and binds its yield columns. It corresponds to CALL procedure(…) YIELD col1, col2 in Cypher.
func NewProcedureCall ¶
func NewProcedureCall(namespace []string, name string, arguments, yieldVars []string, child LogicalPlan) *ProcedureCall
NewProcedureCall creates a ProcedureCall operator.
func (*ProcedureCall) Children ¶
func (p *ProcedureCall) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Child] when Child is non-nil, otherwise nil.
type ProduceResults ¶
type ProduceResults struct {
// Columns is the ordered list of output column names.
Columns []string
// Child is the subplan that produces the result rows.
Child LogicalPlan
}
ProduceResults is the root operator of every logical plan tree. It names the final output columns that are returned to the query caller.
func NewProduceResults ¶
func NewProduceResults(columns []string, child LogicalPlan) *ProduceResults
NewProduceResults creates a ProduceResults operator.
func (*ProduceResults) Children ¶
func (p *ProduceResults) Children() []LogicalPlan
Children implements LogicalPlan.
type ProjectEndpoints ¶
type ProjectEndpoints struct {
// RelVar is the already-bound relationship variable.
RelVar string
// StartVar is the variable name bound to the start node (may be empty if
// not needed).
StartVar string
// EndVar is the variable name bound to the end node (may be empty if not
// needed).
EndVar string
// Child is the subplan that produces RelVar.
Child LogicalPlan
}
ProjectEndpoints projects the start and/or end nodes of a relationship variable that is already in scope.
func NewProjectEndpoints ¶
func NewProjectEndpoints(relVar, startVar, endVar string, child LogicalPlan) *ProjectEndpoints
NewProjectEndpoints creates a ProjectEndpoints operator.
func (*ProjectEndpoints) Children ¶
func (p *ProjectEndpoints) Children() []LogicalPlan
Children implements LogicalPlan.
func (*ProjectEndpoints) Vars ¶
func (p *ProjectEndpoints) Vars() []string
Vars implements LogicalPlan.
type Projection ¶
type Projection struct {
// Items is the ordered list of output columns.
Items []ProjectionItem
// Child is the subplan whose rows are projected.
Child LogicalPlan
}
Projection computes a set of named expressions (RETURN / WITH items) from its child's rows. Only the columns declared in Items are propagated downstream.
func NewProjection ¶
func NewProjection(items []ProjectionItem, child LogicalPlan) *Projection
NewProjection creates a Projection operator.
func (*Projection) Children ¶
func (p *Projection) Children() []LogicalPlan
Children implements LogicalPlan.
type ProjectionItem ¶
type ProjectionItem struct {
// Name is the output variable name (the AS alias, or the expression's
// canonical string representation when no alias is given).
Name string
// Expression is an opaque string representation of the expression.
Expression string
// Expr is the parsed AST for the expression, when available. Nil for
// legacy or string-only callers. When non-nil, the executor evaluates it
// via expr.Eval rather than falling back to a schema-key lookup.
Expr ast.Expression
}
ProjectionItem is a named expression in a Projection operator.
type RemoveLabels ¶
type RemoveLabels struct {
// NodeVar is the already-bound node variable.
NodeVar string
// Labels is the list of labels to remove.
Labels []string
// Child is the driving subplan.
Child LogicalPlan
}
RemoveLabels removes one or more labels from an already-bound node.
func NewRemoveLabels ¶
func NewRemoveLabels(nodeVar string, labels []string, child LogicalPlan) *RemoveLabels
NewRemoveLabels creates a RemoveLabels operator.
func (*RemoveLabels) Children ¶
func (r *RemoveLabels) Children() []LogicalPlan
Children implements LogicalPlan.
type RemoveProperty ¶
type RemoveProperty struct {
// EntityVar is the already-bound node or relationship variable.
EntityVar string
// PropertyKey is the property key to remove.
PropertyKey string
// Child is the driving subplan.
Child LogicalPlan
}
RemoveProperty removes a single property from a node or relationship.
func NewRemoveProperty ¶
func NewRemoveProperty(entityVar, propertyKey string, child LogicalPlan) *RemoveProperty
NewRemoveProperty creates a RemoveProperty operator.
func (*RemoveProperty) Children ¶
func (r *RemoveProperty) Children() []LogicalPlan
Children implements LogicalPlan.
type RollUpApply ¶
type RollUpApply struct {
// Outer is the driving subplan.
Outer LogicalPlan
// Inner is the correlated subplan whose results are collected.
Inner LogicalPlan
// CollectVar is the variable name bound to the collected list.
CollectVar string
// ArgTag identifies the [Argument] leaf that anchors the Inner
// subplan. The physical builder pre-allocates the matching
// exec.Argument under this tag so RollUpApply's loop can seed it
// with each outer row before re-initialising Inner.
ArgTag uint32
}
RollUpApply evaluates Inner for each outer row and collects all Inner result rows into a list, which is bound to CollectVar in the output row.
func NewRollUpApply ¶
func NewRollUpApply(outer, inner LogicalPlan, collectVar string) *RollUpApply
NewRollUpApply creates a RollUpApply operator. The Inner subplan's Argument leaf must carry the same ArgTag so the build pipeline can route the exec.Argument instance.
func (*RollUpApply) Children ¶
func (r *RollUpApply) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
type Selection ¶
type Selection struct {
// Predicate is the opaque string representation of the filter expression.
Predicate string
// PredicateExpr is the parsed AST for the predicate, when available. Nil
// for legacy or string-only callers. When non-nil, the executor evaluates
// it via expr.Eval rather than the pass-through stub.
PredicateExpr ast.Expression
// Child is the subplan whose rows are filtered.
Child LogicalPlan
}
Selection filters rows from its child using Predicate. It corresponds to a WHERE clause in the logical plan.
func NewSelection ¶
func NewSelection(predicate string, child LogicalPlan) *Selection
NewSelection creates a Selection operator with a string-only predicate.
func NewSelectionExpr ¶
func NewSelectionExpr(predicate string, predExpr ast.Expression, child LogicalPlan) *Selection
NewSelectionExpr creates a Selection with both the string predicate and its parsed AST. The executor uses PredicateExpr when non-nil, falling back to the pass-through stub otherwise.
func (*Selection) Children ¶
func (s *Selection) Children() []LogicalPlan
Children implements LogicalPlan.
type SemiApply ¶
type SemiApply struct {
// Outer is the driving subplan.
Outer LogicalPlan
// Inner is the correlated existence-check subplan; its leftmost leaf must
// be an [Argument] whose Tag equals [SemiApply.ArgTag].
Inner LogicalPlan
// ArgTag is the tag shared with the inner-side Argument leaf so that the
// physical builder can route the matching exec.Argument instance.
ArgTag uint32
}
SemiApply implements an EXISTS-style filter: outer rows are kept only when Inner produces at least one result row for the given outer bindings. The inner variables are not propagated to the output.
func NewSemiApply ¶
func NewSemiApply(outer, inner LogicalPlan) *SemiApply
NewSemiApply creates a SemiApply operator with a freshly issued Argument tag. The caller is responsible for placing an Argument node carrying the same tag at the leftmost leaf of inner.
func NewSemiApplyWithTag ¶
func NewSemiApplyWithTag(outer, inner LogicalPlan, tag uint32) *SemiApply
NewSemiApplyWithTag creates a SemiApply with an explicit tag. Use when constructing the IR top-down and threading the tag into the inner subplan's Argument leaf at the same time.
func (*SemiApply) Children ¶
func (s *SemiApply) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
type SetAllProperties ¶
type SetAllProperties struct {
// EntityVar is the already-bound node or relationship variable.
EntityVar string
// IsReplace selects `=` (true, replace) vs `+=` (false, merge) semantics.
IsReplace bool
// SourceVar names a bound node/relationship whose properties are copied.
// Empty when the source is a literal map or a parameter reference.
SourceVar string
// MapLiteral holds the opaque literal-map string (e.g. `{a: 1, b: "x"}`)
// produced by the AST printer. Empty when the source is a SourceVar or a
// parameter reference.
MapLiteral string
// ParamName holds the `$name` reference text (without the dollar sign)
// when the source is a parameter. Empty otherwise.
ParamName string
// Child is the driving subplan.
Child LogicalPlan
}
SetAllProperties replaces or merges every property on an already-bound node or relationship per input row. It implements the Cypher SET entity-replace (`SET n = …`) and entity-append (`SET n += …`) forms.
The source side may be one of:
- A bound entity reference (SourceVar non-empty): copy all of the source entity's properties to the target.
- A literal map (MapLiteral non-empty): write each key/value pair as parsed by the exec literal-map parser.
- A query parameter (ParamName non-empty): resolve at exec time.
IsReplace=true models `SET n = …` semantics: every existing property of the target is removed before the source is applied. IsReplace=false models `SET n += …` semantics: existing properties are kept unless overwritten by a same-keyed entry in the source.
In both modes, null values in the source map remove the matching property from the target.
func NewSetAllPropertiesFromEntity ¶
func NewSetAllPropertiesFromEntity(entityVar, sourceVar string, isReplace bool, child LogicalPlan) *SetAllProperties
NewSetAllPropertiesFromEntity creates a SetAllProperties operator copying every property from sourceVar (a bound node or relationship) to entityVar.
func NewSetAllPropertiesFromMap ¶
func NewSetAllPropertiesFromMap(entityVar, mapLiteral string, isReplace bool, child LogicalPlan) *SetAllProperties
NewSetAllPropertiesFromMap creates a SetAllProperties operator writing every key/value pair from a literal map expression to entityVar.
func NewSetAllPropertiesFromParam ¶
func NewSetAllPropertiesFromParam(entityVar, paramName string, isReplace bool, child LogicalPlan) *SetAllProperties
NewSetAllPropertiesFromParam creates a SetAllProperties operator writing every key/value pair from the named query parameter to entityVar.
func (*SetAllProperties) Children ¶
func (s *SetAllProperties) Children() []LogicalPlan
Children implements LogicalPlan.
func (*SetAllProperties) Vars ¶
func (s *SetAllProperties) Vars() []string
Vars implements LogicalPlan. SetAllProperties does not introduce new variables. When a SourceVar is set, it is reported so plan walkers can see the dependency.
type SetLabels ¶
type SetLabels struct {
// NodeVar is the already-bound node variable.
NodeVar string
// Labels is the list of labels to add.
Labels []string
// Child is the driving subplan.
Child LogicalPlan
}
SetLabels adds one or more labels to an already-bound node.
func NewSetLabels ¶
func NewSetLabels(nodeVar string, labels []string, child LogicalPlan) *SetLabels
NewSetLabels creates a SetLabels operator.
func (*SetLabels) Children ¶
func (s *SetLabels) Children() []LogicalPlan
Children implements LogicalPlan.
type SetProperty ¶
type SetProperty struct {
// EntityVar is the already-bound node or relationship variable.
EntityVar string
// PropertyKey is the property key to set.
PropertyKey string
// Value is the opaque string representation of the new value expression.
Value string
// ValueExpr is the parsed AST for the value expression when available.
// The physical builder uses it to construct a per-row evaluator so that
// non-literal RHS expressions (variable references, arithmetic, property
// access, function calls) actually run against each input row instead of
// silently failing the literal-parser fast path.
ValueExpr ast.Expression
// Child is the driving subplan.
Child LogicalPlan
}
SetProperty sets or updates a single property on a node or relationship.
func NewSetProperty ¶
func NewSetProperty(entityVar, propertyKey, value string, child LogicalPlan) *SetProperty
NewSetProperty creates a SetProperty operator.
func NewSetPropertyExpr ¶
func NewSetPropertyExpr(entityVar, propertyKey, value string, valueExpr ast.Expression, child LogicalPlan) *SetProperty
NewSetPropertyExpr creates a SetProperty operator carrying the parsed AST for the value expression. The exec builder uses it to evaluate non-literal RHS expressions per row.
func (*SetProperty) Children ¶
func (s *SetProperty) Children() []LogicalPlan
Children implements LogicalPlan.
func (*SetProperty) Vars ¶
func (s *SetProperty) Vars() []string
Vars implements LogicalPlan. SetProperty does not introduce new variables.
type Skip ¶
type Skip struct {
// Count is the number of leading rows to skip. Ignored when
// CountExpr is non-nil.
Count int64
// CountExpr is the parsed AST for the SKIP expression when it is
// not a literal integer. Nil when Count is the authoritative value.
CountExpr ast.Expression
// Child is the subplan whose leading rows are discarded.
Child LogicalPlan
}
Skip discards the first Count rows from its child's output. See Limit for the CountExpr deferred-resolution contract.
func NewSkip ¶
func NewSkip(count int64, child LogicalPlan) *Skip
NewSkip creates a Skip operator with a literal count.
func NewSkipExpr ¶
func NewSkipExpr(countExpr ast.Expression, child LogicalPlan) *Skip
NewSkipExpr creates a Skip operator whose count is resolved at physical-build time from the given AST expression.
type Sort ¶
type Sort struct {
// SortItems is the ordered list of sort keys.
SortItems []SortItem
// Child is the subplan whose rows are sorted.
Child LogicalPlan
}
Sort orders rows from its child according to SortItems.
func NewSort ¶
func NewSort(items []SortItem, child LogicalPlan) *Sort
NewSort creates a Sort operator.
type SortItem ¶
type SortItem struct {
// Expression is an opaque string representation of the sort key expression.
Expression string
// Expr is the original AST expression for the sort key. It is carried
// alongside Expression so the physical builder can compile an expression
// evaluator for keys that are not directly present in the output schema
// (e.g. ORDER BY n.age after RETURN n — n.age is not a projected column
// but it can be derived by evaluating the expression against the row).
// May be nil for sort items constructed without access to the AST.
Expr ast.Expression
// Descending indicates DESC ordering; false means ASC.
Descending bool
}
SortItem is a single ORDER BY term in a Sort or Top operator.
type SubqueryCount ¶
type SubqueryCount struct {
// Inner is the subplan whose row-count is reported by the count.
Inner LogicalPlan
// CorrelationVars is the snapshot of outer-scope variable names visible
// inside the subquery.
CorrelationVars []string
// ArgTag is the tag shared with the inner-side Argument leaf.
ArgTag uint32
}
SubqueryCount is the COUNT { … } counterpart of SubqueryExists. The expression evaluator drives the inner plan per outer row and yields an IntegerValue equal to the exact number of rows the inner plan produced for the seeded correlation bindings (0 when the inner plan is empty).
SubqueryCount is a logical-plan node only by virtue of holding an Inner plan tree; it is not itself wired into the operator pipeline.
func NewSubqueryCount ¶
func NewSubqueryCount(inner LogicalPlan, correlationVars []string) *SubqueryCount
NewSubqueryCount creates a SubqueryCount node with a freshly issued Argument tag.
func NewSubqueryCountWithTag ¶
func NewSubqueryCountWithTag(inner LogicalPlan, correlationVars []string, tag uint32) *SubqueryCount
NewSubqueryCountWithTag creates a SubqueryCount with an explicit tag.
func (*SubqueryCount) Children ¶
func (s *SubqueryCount) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Inner].
func (*SubqueryCount) Vars ¶
func (s *SubqueryCount) Vars() []string
Vars implements LogicalPlan. SubqueryCount itself introduces no new variables in the outer scope: it yields an integer value at evaluation time.
type SubqueryExists ¶
type SubqueryExists struct {
// Inner is the subplan whose row-count drives the existence check. Its
// leftmost leaf must be an [Argument] whose Tag equals
// [SubqueryExists.ArgTag].
Inner LogicalPlan
// CorrelationVars is the snapshot of outer-scope variable names that the
// inner plan may reference at evaluation time. The expression evaluator
// projects the outer row onto these names before seeding the Argument.
CorrelationVars []string
// ArgTag is the tag shared with the inner-side Argument leaf so the
// physical builder routes the matching exec.Argument instance per outer
// row.
ArgTag uint32
}
SubqueryExists is a self-contained IR container for an EXISTS { … } subquery that appears inside an arbitrary expression (e.g. nested in a BinaryOp, a CASE branch, or a RETURN projection item). The node holds the inner logical plan plus the variables the subquery correlates from its lexical outer scope; the expression evaluator drives the inner plan per outer row at evaluation time and yields a BoolValue per openCypher semantics:
- true when the inner plan produces at least one row for the seeded correlation bindings;
- false when the inner plan produces zero rows.
Unlike SemiApply, which is a top-level plan operator that filters its outer pipeline by row-count, SubqueryExists is an expression-embedded form used wherever an EXISTS { … } occurs as a sub-expression. The two paths are complementary: the IR translator emits SemiApply whenever an EXISTS is the entire WHERE predicate (so the existence check can short-circuit at the plan level), and emits SubqueryExists for every other occurrence.
SubqueryExists is a logical-plan node only by virtue of holding an Inner plan tree; it is not itself wired into the operator pipeline. The physical builder reaches it through the expression evaluator, not through [buildOperator].
func NewSubqueryExists ¶
func NewSubqueryExists(inner LogicalPlan, correlationVars []string) *SubqueryExists
NewSubqueryExists creates a SubqueryExists node with a freshly issued Argument tag. The caller is responsible for placing an Argument node carrying the same tag at the leftmost leaf of inner.
func NewSubqueryExistsWithTag ¶
func NewSubqueryExistsWithTag(inner LogicalPlan, correlationVars []string, tag uint32) *SubqueryExists
NewSubqueryExistsWithTag creates a SubqueryExists with an explicit tag.
func (*SubqueryExists) Children ¶
func (s *SubqueryExists) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Inner].
func (*SubqueryExists) Vars ¶
func (s *SubqueryExists) Vars() []string
Vars implements LogicalPlan. SubqueryExists itself introduces no new variables in the outer scope: it yields a boolean value at evaluation time.
type Top ¶
type Top struct {
// SortItems is the ordered list of sort keys.
SortItems []SortItem
// Limit is the maximum number of rows to produce.
Limit int64
// Child is the subplan whose rows are sorted and truncated.
Child LogicalPlan
}
Top is a fused ORDER BY … LIMIT operator that sorts and truncates in a single pass, avoiding the need to materialise the full sorted result.
type TranslateError ¶
type TranslateError struct {
// UnsupportedClause is the name of the clause or construct that triggered
// the error (e.g. "FOREACH", "multi-graph UNION").
UnsupportedClause string
// Pos is the source position of the unsupported clause.
Pos ast.Position
}
TranslateError is returned by FromAST when it encounters an AST construct that the translator does not support. Callers can use errors.As to inspect the unsupported clause name and its source position.
func (*TranslateError) Error ¶
func (e *TranslateError) Error() string
Error implements the error interface.
type Union ¶
type Union struct {
// Left is the first input subplan.
Left LogicalPlan
// Right is the second input subplan.
Right LogicalPlan
}
Union computes the set union of two row streams, eliminating duplicates. The left and right children must produce the same column schema.
func (*Union) Children ¶
func (u *Union) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Left, Right].
type UnionAll ¶
type UnionAll struct {
// Left is the first input subplan.
Left LogicalPlan
// Right is the second input subplan.
Right LogicalPlan
}
UnionAll computes the multiset union (bag union) of two row streams without duplicate elimination.
func NewUnionAll ¶
func NewUnionAll(left, right LogicalPlan) *UnionAll
NewUnionAll creates a UnionAll operator.
func (*UnionAll) Children ¶
func (u *UnionAll) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Left, Right].
type Unwind ¶
type Unwind struct {
// ListExpression is the opaque string representation of the list expression.
ListExpression string
// ListExpr is the parsed AST for the list expression, when available. Nil
// means the expression could not be parsed; callers must fall back to a
// static empty list. The executor uses ListExpr when non-nil.
ListExpr ast.Expression
// ElementVar is the variable name bound to each list element.
ElementVar string
// Child is the subplan that provides the context rows. May be nil when
// UNWIND appears at the start of a query.
Child LogicalPlan
}
Unwind expands a list-valued expression into one row per element, binding each element to ElementVar. It corresponds to the UNWIND clause.
func NewUnwind ¶
func NewUnwind(listExpression, elementVar string, child LogicalPlan) *Unwind
NewUnwind creates an Unwind operator with a string-only list expression.
func NewUnwindExpr ¶
func NewUnwindExpr(listExpression string, listExpr ast.Expression, elementVar string, child LogicalPlan) *Unwind
NewUnwindExpr creates an Unwind operator with both the string and its parsed AST. The executor uses ListExpr when non-nil, falling back to an empty list.
func (*Unwind) Children ¶
func (u *Unwind) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Child] when Child is non-nil, otherwise nil.
type VarLengthExpand ¶
type VarLengthExpand struct {
// FromVar is the already-bound source node variable.
FromVar string
// RelVar is the variable name bound to the collected path relationships.
RelVar string
// RelTypes is the list of allowed relationship types. An empty slice means
// any type is accepted.
RelTypes []string
// Direction is the traversal direction relative to FromVar.
Direction Direction
// ToVar is the variable name bound to the destination node.
ToVar string
// MinDepth is the minimum number of hops (inclusive, ≥1).
MinDepth int
// MaxDepth is the maximum number of hops (inclusive). Zero means unbounded.
MaxDepth int
// PathVar, when non-empty, is the named path variable (`p` in
// `MATCH p=(a)-[*1..3]->(b)`). The physical builder allocates a schema slot
// for it and emits a PathValue in that column.
PathVar string
// ExcludedRelVars lists relationship-variable names already in scope
// at the time this VLE step is reached whose bound edge must not be
// traversed. Implements the openCypher no-repeated-relationships rule
// across distinct rel patterns in the same MATCH (e.g. `MATCH ()-[r]
// -() MATCH (n)-[*0..1]-()-[r]-()-[*0..1]-(m)` — the two VLE steps
// must exclude r's edge). The physical builder resolves each name
// against the current schema; unresolved names are silently dropped
// (the variable is not yet bound).
ExcludedRelVars []string
// Child is the subplan that produces FromVar.
Child LogicalPlan
}
VarLengthExpand performs a variable-length path expansion between MinDepth and MaxDepth hops. A MaxDepth of zero means unbounded.
func NewVarLengthExpand ¶
func NewVarLengthExpand(fromVar, relVar string, relTypes []string, dir Direction, toVar string, minDepth, maxDepth int, child LogicalPlan) *VarLengthExpand
NewVarLengthExpand creates a VarLengthExpand operator.
func (*VarLengthExpand) Children ¶
func (v *VarLengthExpand) Children() []LogicalPlan
Children implements LogicalPlan.
func (*VarLengthExpand) Vars ¶
func (v *VarLengthExpand) Vars() []string
Vars implements LogicalPlan.