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 ¶
- Variables
- func ContainsDelete(p LogicalPlan) bool
- func ContainsWrite(p LogicalPlan) bool
- func DegreeCountableComprehension(pc *ast.PatternComprehension) bool
- func Explain(plan LogicalPlan) string
- func IsAggregateFunc(name string) bool
- func IsDDL(query string) bool
- func IsShow(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 DegreeShape
- type DeleteNode
- type DeleteRelationship
- type DetachDelete
- type Direction
- type Distinct
- type DropConstraint
- type DropIndex
- type Eager
- type EagerAggregation
- type Expand
- type Foreach
- type IndexType
- type KVAction
- type Limit
- type LogicalPlan
- type Merge
- type MergePattern
- type MergePatternEndpoint
- type MergePatternHop
- type MergeRelationship
- type MergeSetAll
- type MergeSetExpr
- 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 NewSetAllPropertiesFromExpr(entityVar string, exprAST ast.Expression, 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 ShortestPath
- type ShowConstraints
- type ShowIndexes
- type ShowProjection
- type ShowYield
- 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 ¶
var ShowConstraintColumns = []string{"name", "type", "entityType", "labelsOrTypes", "properties"}
ShowConstraintColumns is the ordered SHOW CONSTRAINTS output schema. It is the single source of truth shared by the executor (cypher.runShowConstraints, which builds rows in this order) and the parser (parseShow, which validates YIELD item names against it).
var ShowIndexColumns = []string{"name", "state", "type", "entityType", "labelsOrTypes", "properties"}
ShowIndexColumns is the ordered SHOW INDEXES output schema, shared by the executor and the parser for the same reason as ShowConstraintColumns.
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, MergePattern). The walk is depth-first; nil plans return false.
func DegreeCountableComprehension ¶ added in v0.11.0
func DegreeCountableComprehension(pc *ast.PatternComprehension) bool
DegreeCountableComprehension reports whether pc is a pattern comprehension whose length can be answered from a degree — that is, whether `size(pc)` is a candidate for the runtime degree rewrite.
A projection is ignored by a degree count, and that is sound rather than a shortcut: it is applied once per match and cannot change how MANY matches there are. An inner WHERE is a different matter — it filters matches — so a comprehension carrying one is refused, as is one that binds a path variable.
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 IsAggregateFunc ¶ added in v0.6.0
IsAggregateFunc reports whether name (case-insensitive, no namespace) is a Cypher aggregate function (count, sum, avg, min, max, collect, stdev, percentileCont, percentileDisc, …). It is the exported form of the internal aggregate-name check, used by the physical planner (#1682) to keep its morsel-parallel fused-scan recognizer's notion of "scalar" consistent with the IR translator's notion of "aggregate".
func IsDDL ¶
IsDDL returns true when query (trimmed, case-insensitive) begins with a known DDL keyword that the lightweight DDL parser handles. This includes the SHOW CONSTRAINTS / SHOW INDEXES read-only schema-introspection statements (IsShow) so they route through ParseDDL and bypass the ANTLR grammar exactly as the CREATE/DROP DDL statements do (#1922). SHOW is DDL for dispatch purposes but is a pure read, not a schema write; callers that must distinguish the two (for example, to permit SHOW on a read-only transaction) use IsShow.
func IsShow ¶ added in v0.9.0
IsShow returns true when query (trimmed, case-insensitive) is a SHOW CONSTRAINTS / SHOW INDEXES schema-introspection statement (or its singular SHOW CONSTRAINT / SHOW INDEX form). SHOW is classified as DDL by IsDDL for dispatch, but unlike CREATE/DROP it is a pure read that emits a result set and mutates nothing, so it is permitted on a read-only transaction where the schema-writing DDL statements are rejected (#1922).
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 {
// 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
// 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
// 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 {
// 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
// NodeVar is the variable name bound to the newly created node.
NodeVar string
// Properties is the opaque string representation of the property map
// expression (e.g. "{name: 'Alice'}").
Properties string
// Labels is the list of labels assigned to the new node.
Labels []string
}
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 {
// 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
// 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
}
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 DegreeShape ¶ added in v0.11.0
type DegreeShape struct {
// AnchorVar is the variable naming the node whose degree is wanted. The
// caller must confirm it is bound in the row before using the shape.
AnchorVar string
// FarVar is the far endpoint's variable, or "" when the pattern does not
// name one. When it is non-empty the caller must confirm it is NOT bound in
// the row: a bound far endpoint makes the pattern an expand-into between two
// fixed nodes, not a degree.
FarVar string
// RelType is the single relationship type, or "" when the pattern is
// untyped. Cypher has no empty relationship type, so "" is unambiguous.
RelType string
}
DegreeShape carries the structural facts a degree count needs, extracted once from the AST. It says nothing about whether the pattern is answerable for a particular row; that is the caller's remaining obligation.
func DegreeCountableShape ¶ added in v0.11.0
DegreeCountableShape reports whether pat is structurally degree-answerable, and returns the extracted shape when it is.
where is the pattern's inline WHERE; a non-nil WHERE is a Selection and disqualifies the pattern outright.
This is the row-INDEPENDENT half of the test. A true result means the pattern has the right shape, not that it can be answered for any given row: the caller must still check that Shape.AnchorVar is bound and that Shape.FarVar, when non-empty, is not.
type DeleteNode ¶
type DeleteNode struct {
// 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
// NodeVar is the already-bound node variable to delete.
NodeVar string
}
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 {
// Child is the driving subplan.
Child LogicalPlan
// RelVar is the already-bound relationship variable to delete.
RelVar string
}
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 {
// 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
// NodeVar is the already-bound node variable to delete.
NodeVar string
}
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 {
// Child is the subplan whose rows are aggregated.
Child LogicalPlan
// 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
}
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 {
// Child is the subplan that produces FromVar.
Child LogicalPlan
// FromVar is the already-bound source node variable.
FromVar string
// RelVar is the variable name bound to the traversed relationship.
RelVar string
// ToVar is the variable name bound to the destination node.
ToVar 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
// RelTypes is the list of allowed relationship types. An empty slice means
// any type is accepted.
RelTypes []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
// Direction is the traversal direction relative to FromVar.
Direction Direction
// IntoVar names an ALREADY-BOUND destination variable this hop must land on —
// the openCypher "expand into" case, which arises whenever a pattern closes a
// cycle (`MATCH (a)-[:K]->(b)-[:K]->(a)`) or re-uses a bound endpoint.
//
// When set, ToVar carries the synthetic `__anon_N_to_<IntoVar>` name the
// translator generates and an equality Selection sits above this node. IntoVar
// records the same fact as a FIELD so the physical builder can act on it without
// parsing that naming convention (#2206); the convention itself stays, because
// lastSyntheticToFor threads the synthetic as the next hop's FromVar.
//
// Empty for every hop whose destination is fresh, which is the common case.
IntoVar string
}
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 Foreach ¶ added in v0.9.0
type Foreach struct {
// Outer is the driving (left) subplan.
Outer LogicalPlan
// Inner is the correlated body sub-plan; its leftmost leaf must be an
// [Argument] whose Tag equals ArgTag.
Inner LogicalPlan
// ArgTag is shared with the inner Argument leaf so the physical builder can
// route the matching exec.Argument instance.
ArgTag uint32
}
Foreach is the FOREACH updating clause: for each element of a list, bind the loop variable and run the body's updating clauses as side-effects, without changing the surrounding query's row cardinality.
Inner is a correlated sub-plan whose leftmost leaf is an Argument carrying ArgTag: Argument(outer vars) → Unwind(list AS loopVar) → body updating clauses. The [exec.Foreach] operator seeds the Argument with each outer row, drains the inner sub-plan (applying its writes for every list element), then emits the outer row unchanged. The loop variable and any variables the body introduces are scoped to the body and are NOT visible after FOREACH — hence Vars reports only the outer variables.
func NewForeach ¶ added in v0.9.0
func NewForeach(outer, inner LogicalPlan, argTag uint32) *Foreach
NewForeach creates a Foreach operator with an explicit Argument tag (the caller threads the same tag into the inner sub-plan's Argument leaf).
func (*Foreach) Children ¶ added in v0.9.0
func (f *Foreach) Children() []LogicalPlan
Children implements LogicalPlan. Returns [Outer, Inner].
func (*Foreach) Vars ¶ added in v0.9.0
Vars implements LogicalPlan. FOREACH introduces no variable visible after it; downstream sees exactly the outer variables. When FOREACH is the leading clause of a query its Outer is nil (there is no preceding pipeline), so it exposes no variables — the nil guard prevents a nil-pointer panic when a following clause (e.g. CREATE, RETURN, a second FOREACH) collects variables.
type KVAction ¶
type KVAction struct {
Key string
Value string // opaque literal string (parsed at physical-build time)
// RetainKeys lists the RHS property keys of a Replace map sentinel — the
// keys that must NOT be cleared. Nil for an entity-copy Replace sentinel
// (the retained set is the source entity's live keys, resolved at write
// time) and for non-Replace actions.
RetainKeys []string
// Replace marks the leading sentinel of a whole-entity `=` replace group.
// When true the exec layer clears the relationship's existing properties
// that are absent from the RHS before applying the subsequent write
// actions. Always false for the additive `+=` form and for
// single-property `SET <relVar>.<key> = <value>` items.
Replace bool
}
KVAction is a (key, value) pair captured by the IR for MERGE ON CREATE / ON MATCH SET items.
A whole-entity REPLACE item (`SET <relVar> = {…}` or `SET <relVar> = node`, the `=` operator) is encoded as a leading sentinel action with Replace=true, Key="" and Value=="" for the map form (RetainKeys lists the RHS keys that must survive the clear) or Value=="<sourceVar>" for the entity-copy form (RetainKeys nil — the retained set is the source entity's live property keys, resolved at write time). The sentinel is immediately followed by the per-key write actions for the map form, so the exec layer clears the edge's existing properties absent from the RHS before applying the writes. The mutate form (`SET <relVar> += {…}`) carries Replace=false and is purely additive.
type Limit ¶
type Limit struct {
// 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
// Count is the maximum number of rows to pass through. Ignored when
// CountExpr is non-nil.
Count int64
}
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.
A leading comment is stripped before dispatch, so the sub-parsers see the statement itself — see [trimLeadingComments].
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 {
// 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
// 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
// OnCreateExprs / OnMatchExprs carry the parsed value-expression ASTs of
// the ON CREATE / ON MATCH property-set items whose right-hand side is a
// non-literal expression (e.g. `ON MATCH SET n.num = n.num + 1`). The
// physical builder installs a per-row evaluator for each so the RHS is
// evaluated against the matched/created row instead of being dropped as a
// literal-parse failure. Literal RHS items are omitted (they use the
// opaque-string fast path in [OnCreate]/[OnMatch]).
OnCreateExprs []MergeSetExpr
OnMatchExprs []MergeSetExpr
// OnCreateSetAll / OnMatchSetAll carry whole-entity ON CREATE / ON MATCH
// SET items (`SET n = <expr>` / `SET n += <expr>`) whose target is a node
// variable rather than a property. The per-property opaque-string path
// drops such keyless items; the physical builder installs a per-row
// expression evaluator for each so the whole map/entity value is written
// (#2031).
OnCreateSetAll []MergeSetAll
OnMatchSetAll []MergeSetAll
}
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 MergePattern ¶ added in v0.7.0
type MergePattern struct {
Child LogicalPlan
// Nodes holds one entry per chain position; len(Nodes) == len(Hops)+1.
Nodes []MergePatternEndpoint
// Hops holds one entry per relationship; Hops[i] connects Nodes[i] to
// Nodes[i+1].
Hops []MergePatternHop
// OnCreate / OnMatch are opaque SET-item strings (the same representation
// [Merge] uses), parsed by the physical builder via the shared
// parseMergeActions helper into actions addressable by any pattern
// variable — any Nodes[i].Var or Hops[i].RelVar, not just one entity.
OnCreate []string
OnMatch []string
// OnCreateExprs / OnMatchExprs carry the value-expression ASTs of the
// ON CREATE / ON MATCH property-set items whose right-hand side is a
// non-literal expression. See [MergeSetExpr]; literal RHS items are
// omitted (handled via the opaque-string fast path in [OnCreate]/[OnMatch]).
OnCreateExprs []MergeSetExpr
OnMatchExprs []MergeSetExpr
// OnCreateSetAll / OnMatchSetAll carry whole-entity ON CREATE / ON MATCH
// SET items on a chain node variable, which the per-property opaque-string
// path drops. See [MergeSetAll] (#2031).
OnCreateSetAll []MergeSetAll
OnMatchSetAll []MergeSetAll
}
MergePattern implements the compound MERGE clause: a chain of one or more relationship hops in which at least one node is NOT already bound by an earlier clause, so the whole pattern (every fresh node plus every relationship) must be searched for as one atomic unit and, when no joint match exists, created as one atomic unit — openCypher's whole-pattern MERGE semantics (never independently reuse an existing node for part of a pattern that fails to match as a whole).
MergePattern complements Merge (a lone node, no relationship) and MergeRelationship (a single relationship hop whose endpoints are BOTH already bound and whose ON CREATE/ON MATCH actions target only the relationship — the narrower, more efficient case). The translator (mergeClause in cypher/ir/writes.go) routes a MERGE pattern with at least one relationship hop to whichever of the two IR nodes matches its exact shape, falling back to MergePattern for everything MergeRelationship's narrow fast path does not cover.
func NewMergePattern ¶ added in v0.7.0
func NewMergePattern(nodes []MergePatternEndpoint, hops []MergePatternHop, onCreate, onMatch []string, child LogicalPlan) *MergePattern
NewMergePattern creates a MergePattern operator for the chain described by nodes and hops. len(nodes) must equal len(hops)+1.
func (*MergePattern) Children ¶ added in v0.7.0
func (m *MergePattern) Children() []LogicalPlan
Children implements LogicalPlan.
func (*MergePattern) Vars ¶ added in v0.7.0
func (m *MergePattern) Vars() []string
Vars implements LogicalPlan: only the FRESH nodes (and named relationships) are newly bound by this node — an already-bound endpoint was introduced by an earlier clause and must not be reported again here.
type MergePatternEndpoint ¶ added in v0.7.0
type MergePatternEndpoint struct {
// PropsAST carries the property-map AST when it contains non-literal
// expressions (variable references, property accesses, parameters).
// nil when the map is absent or fully literal, in which case PropsRaw
// alone drives both the search predicate and the create-time write.
PropsAST ast.Expression
Var string
PropsRaw string // opaque inline `{k: v, ...}` source string, "" when absent
Labels []string
Bound bool
}
MergePatternEndpoint describes one node position in a MergePattern chain.
When Bound is true, Var names a variable already bound by an earlier clause (a preceding MATCH/CREATE/MERGE/WITH); the physical operator pins it to its existing value and never searches for or creates a node for it. Labels/PropsRaw/PropsAST are unset in this case — openCypher forbids re-asserting new labels or properties on an already-bound MERGE variable (rejected at compile time by sema's VariableAlreadyBound check).
When Bound is false, Var names a variable this MERGE clause introduces fresh: Labels and PropsRaw describe the node-pattern predicate used both to search for a satisfying node and, when the whole pattern's search fails, to create one.
type MergePatternHop ¶ added in v0.7.0
type MergePatternHop struct {
// RelPropsAST carries the property-map AST when it contains non-literal
// expressions; nil when the map is absent or fully literal.
RelPropsAST ast.Expression
RelVar string // "" for an anonymous relationship
RelType string
RelPropsRaw string // opaque inline `{k: v, ...}` source string, "" when absent
Undirected bool
// Reversed is true for an incoming `<-` pattern: chain positions stay in
// pattern-declaration order, but the edge is stored/searched from the
// NEXT position back to this one rather than this one to the next.
Reversed bool
}
MergePatternHop describes one relationship connecting two consecutive MergePatternEndpoint positions in a MergePattern chain (position i to position i+1). Every field is fully resolved by sema before translation reaches this node: exactly one relationship type (zero or multiple types are rejected at compile time as NoSingleRelationshipType), never variable-length (rejected as CreatingVarLength), and the property map, when present, is never a bare parameter reference (rejected as InvalidParameterUse) — so RelPropsRaw/RelPropsAST only ever need to represent a `{k: v, ...}` map literal, exactly like MergePatternEndpoint.
type MergeRelationship ¶
type MergeRelationship struct {
// RelPropsAST carries the inline relationship property-map AST when it
// contains a non-literal value (a variable reference, property access,
// or arithmetic expression — e.g. `{kind: r.pk}`). The physical builder
// installs a per-row property evaluator from it so the map drives both
// the match-search predicate and the created edge's properties. nil when
// the map is absent or every value is a literal (or a $param, resolved at
// build time via the opaque RelProps string). Without it a row-driven
// inline property silently degrades to null on the created edge, since
// the literal-only parser drops the non-literal entry (fail-silent
// Consistency defect).
RelPropsAST ast.Expression
// Child is the driving subplan that binds SrcVar and DstVar.
Child LogicalPlan
// 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
// 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
// OnCreateExprs / OnMatchExprs carry the value-expression ASTs of the
// ON CREATE / ON MATCH property-set items whose right-hand side is a
// non-literal expression (e.g. `ON MATCH SET r.n = r.n + 1`). See
// [MergeSetExpr]; literal RHS items are omitted (handled via the
// [KVAction] opaque-string fast path).
OnCreateExprs []MergeSetExpr
OnMatchExprs []MergeSetExpr
// 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
}
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 MergeSetAll ¶ added in v0.9.0
type MergeSetAll struct {
Value ast.Expression
TargetVar string
IsReplace bool
}
MergeSetAll carries a whole-entity ON CREATE / ON MATCH SET item (`SET <TargetVar> = <Value>` / `SET <TargetVar> += <Value>`) on a MERGE. The physical builder installs a per-row evaluator for Value; the exec operator dispatches on the evaluated value's runtime kind (map / node / relationship / null / other). IsReplace selects `=` (true) vs `+=` (false).
type MergeSetExpr ¶ added in v0.8.0
type MergeSetExpr struct {
Value ast.Expression
TargetVar string
Key string
}
MergeSetExpr carries the parsed value-expression AST for a MERGE ON CREATE / ON MATCH property-set item whose right-hand side is a non-literal expression, so the physical builder can install a per-row evaluator (mirroring the regular SET operator's ValueEvalFn) instead of silently dropping the assignment when the RHS fails to parse as a literal.
TargetVar and Key identify which entity property the item writes (the pattern node, bound endpoint, or relationship variable); Value is the right-hand-side expression evaluated per row.
type NamedPath ¶
type NamedPath struct {
// Child is the subplan that produces the chain's variables.
Child LogicalPlan
// 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
}
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 {
// 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
// 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
}
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 {
// Child is the subplan that produces FromVar.
Child LogicalPlan
// FromVar is the already-bound source node variable.
FromVar string
// RelVar is the variable name bound to the traversed relationship (or null).
RelVar string
// ToVar is the variable name bound to the destination node (or null).
ToVar 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
}
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 {
// Child is the driving subplan. May be nil when CALL appears at the start
// of a query.
Child LogicalPlan
// Name is the bare procedure name.
Name string
// Namespace is the optional namespace path of the procedure
// (e.g. ["apoc", "algo"] for apoc.algo.dijkstra).
Namespace []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
}
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 {
// Child is the subplan that produces the result rows.
Child LogicalPlan
// Columns is the ordered list of output column names.
Columns []string
}
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 {
// Child is the subplan that produces RelVar.
Child LogicalPlan
// 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
}
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 {
// Child is the subplan whose rows are projected.
Child LogicalPlan
// Items is the ordered list of output columns.
Items []ProjectionItem
}
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 {
// 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
// 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
// Hidden marks a synthetic passthrough item added only so a downstream
// Sort can resolve an ORDER BY reference to a pre-projection variable. It
// is emitted into the row stream but MUST be excluded from the final
// ProduceResults output columns (#1805).
Hidden bool
}
ProjectionItem is a named expression in a Projection operator.
type RemoveLabels ¶
type RemoveLabels struct {
// Child is the driving subplan.
Child LogicalPlan
// NodeVar is the already-bound node variable.
NodeVar string
// Labels is the list of labels to remove.
Labels []string
}
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 {
// Child is the driving subplan.
Child LogicalPlan
// EntityVar is the already-bound node or relationship variable.
EntityVar string
// PropertyKey is the property key to remove.
PropertyKey string
}
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 {
// 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
// Predicate is the opaque string representation of the filter expression.
Predicate string
}
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 {
// MapAST carries the source map-literal AST when it contains a non-literal
// value (a variable reference, property access, or arithmetic — e.g.
// `SET n += {x: row.y}`). The physical builder installs a per-row map
// evaluator from it so the row-driven values are written (and null-valued
// keys removed). nil when the map is absent or every value is a literal
// (or a $param, resolved at build time via the opaque MapLiteral string).
// Without it a row-driven map value silently degrades to null on the target.
MapAST ast.Expression
// ExprAST carries a whole map-valued RHS expression for the
// `SET n = <expr>` / `SET n += <expr>` forms whose right-hand side is
// neither a `{…}` literal, a bound entity variable, nor a `$param` — e.g.
// `SET n = properties(m)`, a map projection, or coalesce. The physical
// builder installs a per-row expression evaluator from it; the exec operator
// dispatches on the evaluated value's runtime kind (map / node / relationship
// / null / other). nil for the SourceVar, MapLiteral, and ParamName forms.
// Without it such an openCypher-valid expression fails at build time (the
// literal-map parser rejects the stringified expression).
ExprAST ast.Expression
// Child is the driving subplan.
Child LogicalPlan
// EntityVar is the already-bound node or relationship variable.
EntityVar string
// 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
// IsReplace selects `=` (true, replace) vs `+=` (false, merge) semantics.
IsReplace bool
}
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 NewSetAllPropertiesFromExpr ¶ added in v0.9.0
func NewSetAllPropertiesFromExpr(entityVar string, exprAST ast.Expression, isReplace bool, child LogicalPlan) *SetAllProperties
NewSetAllPropertiesFromExpr creates a SetAllProperties operator whose source is an arbitrary map-valued expression (exprAST) evaluated per row. It backs the `SET n = <expr>` / `SET n += <expr>` forms whose right-hand side is neither a `{…}` literal, a bound entity variable, nor a `$param` — e.g. `SET n = properties(m)`. The physical builder installs a per-row evaluator from exprAST; the exec operator dispatches on the evaluated value's kind.
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 {
// Child is the driving subplan.
Child LogicalPlan
// NodeVar is the already-bound node variable.
NodeVar string
// Labels is the list of labels to add.
Labels []string
}
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 {
// 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
// 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
}
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 ShortestPath ¶ added in v0.6.0
type ShortestPath struct {
// Child is the subplan that produces FromVar and ToVar.
Child LogicalPlan
// FromVar / ToVar are the endpoint node variables, both produced by Child.
FromVar string
ToVar string
// PathVar is the named path variable bound to the resulting path. Always
// non-empty (the parser only rewrites the named binding form).
PathVar string
// RelVar is the inner relationship variable name, or empty when the inner
// relationship is anonymous. Bound as LIST<RELATIONSHIP> for the path.
RelVar string
// RelTypes is the inner relationship's accepted type set (OR semantics). An
// empty slice means any type.
RelTypes []string
// MinDepth / MaxDepth bound the path length. MinDepth is 0 or 1 (enforced by
// sema). MaxDepth uses math.MaxInt for "unbounded".
MinDepth int
MaxDepth int
// All selects allShortestPaths (every minimum-length path) over
// shortestPath (a single arbitrary minimum-length path).
All bool
// Optional reports whether the binding sits under OPTIONAL MATCH. When a
// pair has no path: a non-optional binding eliminates the row; an optional
// one keeps the row with the path variable bound to null.
Optional bool
// Direction is the inner relationship's traversal direction relative to
// FromVar.
Direction Direction
}
ShortestPath computes the shortest (fewest-hops) path, or — when All is true — every minimum-length path, between two already-bound endpoint node variables. It is the IR node for a named `MATCH p = shortestPath((a)-[*]-(b))` / `allShortestPaths(...)` binding (rmp #1692): the parser's pre-lex normaliser strips the wrapper keyword and stamps the kind onto the inner named ast.PathPattern (rmp #1690), and [translator.matchShortestPath] turns the stamped pattern into this node.
Both endpoints are produced by Child (bound from an outer clause or scanned when unbound). The physical builder lowers this to an github.com/FlavioCFOliveira/GoGraph/cypher/exec.ShortestPath or github.com/FlavioCFOliveira/GoGraph/cypher/exec.AllShortestPaths operator, which emits the flat alternating path list the path variable's metadata hydrates into a per-instance-typed PathValue.
func NewShortestPath ¶ added in v0.6.0
func NewShortestPath(all, optional bool, fromVar, toVar, pathVar, relVar string, relTypes []string, dir Direction, minDepth, maxDepth int, child LogicalPlan) *ShortestPath
NewShortestPath creates a ShortestPath IR node.
func (*ShortestPath) Children ¶ added in v0.6.0
func (s *ShortestPath) Children() []LogicalPlan
Children implements LogicalPlan.
func (*ShortestPath) Vars ¶ added in v0.6.0
func (s *ShortestPath) Vars() []string
Vars implements LogicalPlan. The path variable, and the relationship-list variable when named, are introduced by this node.
type ShowConstraints ¶ added in v0.9.0
type ShowConstraints struct {
Projection *ShowProjection
}
ShowConstraints is a DDL plan node representing a SHOW CONSTRAINTS (or the singular SHOW CONSTRAINT) statement. It is a leaf node; it has no child plan and introduces no variables. Projection is nil for the plain form and non-nil when a YIELD / WHERE / RETURN sub-clause was supplied (#2044).
func NewShowConstraints ¶ added in v0.9.0
func NewShowConstraints() *ShowConstraints
NewShowConstraints creates a plain ShowConstraints IR node (no YIELD).
func (*ShowConstraints) Children ¶ added in v0.9.0
func (*ShowConstraints) Children() []LogicalPlan
Children implements LogicalPlan. ShowConstraints is a leaf.
func (*ShowConstraints) Vars ¶ added in v0.9.0
func (*ShowConstraints) Vars() []string
Vars implements LogicalPlan. ShowConstraints introduces no variables into the enclosing plan: it is executed directly by the engine's DDL path, never composed with other operators.
type ShowIndexes ¶ added in v0.9.0
type ShowIndexes struct {
Projection *ShowProjection
}
ShowIndexes is a DDL plan node representing a SHOW INDEXES (or the singular SHOW INDEX) statement. It is a leaf node; it has no child plan and introduces no variables. Projection is nil for the plain form and non-nil when a YIELD / WHERE / RETURN sub-clause was supplied (#2044).
func NewShowIndexes ¶ added in v0.9.0
func NewShowIndexes() *ShowIndexes
NewShowIndexes creates a plain ShowIndexes IR node (no YIELD).
func (*ShowIndexes) Children ¶ added in v0.9.0
func (*ShowIndexes) Children() []LogicalPlan
Children implements LogicalPlan. ShowIndexes is a leaf.
func (*ShowIndexes) Vars ¶ added in v0.9.0
func (*ShowIndexes) Vars() []string
Vars implements LogicalPlan. ShowIndexes introduces no variables (see ShowConstraints.Vars).
type ShowProjection ¶ added in v0.9.0
type ShowProjection struct {
Project []ShowYield
Where ast.Expression
Return *ast.Projection
// ReturnColumns are the output column names for an explicit RETURN item list
// (Return non-nil and not RETURN *), precomputed by the parser using the same
// column-naming convention as an ordinary RETURN. Empty otherwise.
ReturnColumns []string
}
ShowProjection carries the optional YIELD / WHERE / RETURN sub-clauses parsed onto a SHOW CONSTRAINTS / SHOW INDEXES statement (#2044). Semantics follow the Neo4j Cypher manual's SHOW-command grammar:
- Project is the ordered YIELD projection (a WITH-style scope barrier): only the Output names are visible to Where and Return. It always has at least one item for a non-nil ShowProjection — YIELD * and the WHERE-only form are expanded to every default column by the parser.
- Where filters the projected rows (evaluated per row; NULL and false both drop the row, three-valued logic).
- Return, when non-nil, is a final scalar projection over the yielded scope (it references only Output names). ORDER BY / SKIP / LIMIT / DISTINCT and aggregations are rejected by the parser, so Return carries only Items (or the RETURN * flag) that the executor evaluates per row.
type ShowYield ¶ added in v0.9.0
ShowYield is one resolved YIELD projection item: it reads the SHOW column named Source and exposes it downstream (to WHERE, RETURN, and the result set) under the name Output. Output equals Source unless the YIELD item carried an AS alias. For YIELD * and the WHERE-without-YIELD form the parser materialises one ShowYield per default column with Source == Output.
type Skip ¶
type Skip struct {
// 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
// Count is the number of leading rows to skip. Ignored when
// CountExpr is non-nil.
Count int64
}
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 {
// Child is the subplan whose rows are sorted.
Child LogicalPlan
// SortItems is the ordered list of sort keys.
SortItems []SortItem
}
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 {
// 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
// Expression is an opaque string representation of the sort key expression.
Expression string
// 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 {
// Child is the subplan whose rows are sorted and truncated.
Child LogicalPlan
// SortItems is the ordered list of sort keys.
SortItems []SortItem
// Limit is the maximum number of rows to produce.
Limit int64
}
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 {
// 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
// Child is the subplan that provides the context rows. May be nil when
// UNWIND appears at the start of a query.
Child LogicalPlan
// ListExpression is the opaque string representation of the list expression.
ListExpression string
// ElementVar is the variable name bound to each list element.
ElementVar string
}
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 {
// Child is the subplan that produces FromVar.
Child LogicalPlan
// FromVar is the already-bound source node variable.
FromVar string
// RelVar is the variable name bound to the collected path relationships.
RelVar string
// ToVar is the variable name bound to the destination node.
ToVar string
// 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
// RelTypes is the list of allowed relationship types. An empty slice means
// any type is accepted.
RelTypes []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
// MinDepth is the minimum number of hops (inclusive, ≥1).
MinDepth int
// MaxDepth is the maximum number of hops (inclusive). Zero means unbounded.
MaxDepth int
// Direction is the traversal direction relative to FromVar.
Direction Direction
}
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.