ir

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2026 License: MIT Imports: 7 Imported by: 0

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:

Traversal operators follow relationships:

Filter and projection operators reshape the row stream:

Set operators combine row streams:

  • Union — UNION (with duplicate elimination)
  • UnionAll — UNION ALL (without duplicate elimination)

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:

Procedure operators call stored procedures:

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContainsDelete

func ContainsDelete(p LogicalPlan) bool

ContainsDelete reports whether p's subtree contains any DELETE-class operator. Used to decide whether a subsequent MERGE needs an Eager pipeline-breaker so the deletion's writes are visible to the MERGE-search (Merge1 [14]).

func ContainsWrite

func ContainsWrite(p LogicalPlan) bool

ContainsWrite walks p and reports whether any node in the tree is a write operator (CreateNode, CreateRelationship, SetProperty, SetAllProperties, SetLabels, RemoveProperty, RemoveLabels, DeleteNode, DeleteRelationship, DetachDelete, Merge, MergeRelationship). The walk is depth-first; nil plans return false.

func Explain

func Explain(plan LogicalPlan) string

Explain returns a human-readable tree representation of plan, mirroring the style of Neo4j's textual EXPLAIN output. Each line shows the operator name and the variables it introduces or requires. A "-" placeholder occupies the cardinality column, which will be populated by the PROFILE stage in Sprint 28.

Tree edges use box-drawing characters (├─, └─, │) for clarity. The output is deterministic for a given plan tree.

Example:

ProduceResults [n]
└─ Projection [n]
   └─ NodeByLabelScan [n:Person]
Example

ExampleExplain renders a logical plan as a human-readable operator tree.

package main

import (
	"fmt"

	"github.com/FlavioCFOliveira/GoGraph/cypher/ir"
	"github.com/FlavioCFOliveira/GoGraph/cypher/parser"
)

func main() {
	q, err := parser.Parse("MATCH (n:Person) RETURN n")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	plan, err := ir.FromAST(q)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Print(ir.Explain(plan))
}
Output:
ProduceResults [n]
└─ Projection [n]
   └─ NodeByLabelScan [n:Person]

func IsDDL

func IsDDL(query string) bool

IsDDL returns true when query (trimmed, case-insensitive) begins with a known DDL keyword that the lightweight DDL parser handles.

func NextArgTag

func NextArgTag() uint32

NextArgTag is the exported wrapper around [nextArgTag]. It is used by the outer cypher package's subquery evaluator (cypher/subquery_eval.go) when it needs to mint a fresh Argument tag while compiling an EXISTS / COUNT subquery's inner plan outside the regular IR-translator path.

func OperatorName

func OperatorName(plan LogicalPlan) string

OperatorName returns the canonical display name for the logical plan operator. It is the exported counterpart of the internal operatorName helper used by Explain, exposed so callers outside this package can render individual nodes (e.g. the Engine's physical-plan explain renderer).

Types

type AggregateExpr

type AggregateExpr struct {
	// OutputName is the variable name assigned to the aggregate result.
	OutputName string
	// Function is the aggregate function name (e.g. "count", "sum", "avg").
	Function string
	// Argument is the expression argument to the aggregate function. An empty
	// string corresponds to count(*).
	Argument string
	// ArgumentExpr is the parsed AST for the aggregate argument, when available.
	// Non-nil when the argument is a non-trivial expression (property access,
	// function call, …); when nil, callers fall back to schema lookup keyed on
	// Argument or supply the constant Null. count(*) keeps ArgumentExpr == nil.
	ArgumentExpr ast.Expression
	// SecondArgExpr captures the second argument of two-arg aggregates
	// (percentileCont, percentileDisc). The value is constant across the
	// aggregation (it parameterises the factory, not the per-row Step) and
	// is evaluated once at physical-build time, typically from a parameter
	// or a literal.
	SecondArgExpr ast.Expression
	// Distinct indicates whether the DISTINCT qualifier is applied inside the
	// aggregate (e.g. count(DISTINCT n)).
	Distinct bool
}

AggregateExpr is a named aggregate function in an EagerAggregation operator.

type AllNodesScan

type AllNodesScan struct {
	// NodeVar is the variable name bound to each scanned node.
	NodeVar string
}

AllNodesScan scans every node in the graph and binds each to NodeVar.

func NewAllNodesScan

func NewAllNodesScan(nodeVar string) *AllNodesScan

NewAllNodesScan creates an AllNodesScan operator.

func (*AllNodesScan) Children

func (a *AllNodesScan) Children() []LogicalPlan

Children implements LogicalPlan. AllNodesScan is a leaf; it returns nil.

func (*AllNodesScan) Vars

func (a *AllNodesScan) Vars() []string

Vars implements LogicalPlan.

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 NewApply

func NewApply(outer, inner LogicalPlan) *Apply

NewApply creates an Apply operator.

func (*Apply) Children

func (a *Apply) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Outer, Inner].

func (*Apply) Vars

func (a *Apply) Vars() []string

Vars implements LogicalPlan.

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

func NewArgument(vars []string) *Argument

NewArgument creates an Argument operator with the given injected variables and a freshly allocated [Argument.Tag].

func NewArgumentWithTag

func NewArgumentWithTag(vars []string, tag uint32) *Argument

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.

func (*Argument) Vars

func (a *Argument) Vars() []string

Vars implements LogicalPlan.

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 is the driving (left) subplan.
	Outer LogicalPlan
	// Inner is the correlated (right) subplan; its leftmost leaf must be an
	// [Argument] whose Tag equals [CorrelatedApply.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
}

CorrelatedApply is a dependent join in which the inner subplan starts with an Argument leaf re-emitting the outer row. Unlike Apply, the physical executor for CorrelatedApply forwards the inner row verbatim and does not concatenate it with the outer row — the outer columns are already present in the inner row's leading positions.

CorrelatedApply is used for multi-pattern MATCH where subsequent patterns share at least one variable with a previously bound pattern: the shared variable acts as a join key implicit in the dataflow.

func NewCorrelatedApply

func NewCorrelatedApply(outer, inner LogicalPlan) *CorrelatedApply

NewCorrelatedApply creates a CorrelatedApply operator with a freshly issued Argument tag. The caller is responsible for placing an Argument node carrying the same tag at the leftmost leaf of inner.

func NewCorrelatedApplyWithTag

func NewCorrelatedApplyWithTag(outer, inner LogicalPlan, tag uint32) *CorrelatedApply

NewCorrelatedApplyWithTag creates a CorrelatedApply with an explicit tag. Use when constructing the IR top-down and threading the tag into the inner subplan's Argument leaf at the same time.

func (*CorrelatedApply) Children

func (c *CorrelatedApply) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Outer, Inner].

func (*CorrelatedApply) Vars

func (c *CorrelatedApply) Vars() []string

Vars implements LogicalPlan. The outer variables come first; inner variables not already present are appended.

type CreateConstraint

type CreateConstraint struct {
	// Name is the user-defined constraint name.
	Name string
	// Label is the node label to which the constraint applies.
	Label string
	// Property is the node property key constrained.
	Property string
	// Kind is the constraint type (unique or not-null).
	Kind ConstraintKind
	// IfNotExists suppresses an error when the constraint already exists.
	IfNotExists bool
}

CreateConstraint is a DDL plan node representing a Cypher CREATE CONSTRAINT statement.

CreateConstraint is a leaf node; it has no child plan.

func NewCreateConstraint

func NewCreateConstraint(name, label, property string, kind ConstraintKind, ifNotExists bool) *CreateConstraint

NewCreateConstraint creates a CreateConstraint IR node.

func (*CreateConstraint) Children

func (c *CreateConstraint) Children() []LogicalPlan

Children implements LogicalPlan. CreateConstraint is a leaf.

func (*CreateConstraint) Vars

func (c *CreateConstraint) Vars() []string

Vars implements LogicalPlan. CreateConstraint introduces no variables.

type CreateIndex

type CreateIndex struct {
	// Name is the user-defined index name, or empty for an auto-named index.
	Name string
	// Label is the node label on which the index is built.
	Label string
	// Property is the node property key indexed.
	Property string
	// Type is the backing index kind (hash or btree).
	Type IndexType
	// IfNotExists suppresses ErrIndexExists when the index already exists.
	IfNotExists bool
}

CreateIndex is a DDL plan node representing a Cypher CREATE INDEX statement.

CreateIndex is a leaf node; it has no child plan.

func NewCreateIndex

func NewCreateIndex(name, label, property string, idxType IndexType, ifNotExists bool) *CreateIndex

NewCreateIndex creates a CreateIndex IR node.

func (*CreateIndex) Children

func (c *CreateIndex) Children() []LogicalPlan

Children implements LogicalPlan. CreateIndex is a leaf.

func (*CreateIndex) Vars

func (c *CreateIndex) Vars() []string

Vars implements LogicalPlan. CreateIndex introduces no variables.

type CreateNode

type CreateNode struct {
	// NodeVar is the variable name bound to the newly created node.
	NodeVar string
	// Labels is the list of labels assigned to the new node.
	Labels []string
	// Properties is the opaque string representation of the property map
	// expression (e.g. "{name: 'Alice'}").
	Properties string
	// PropertiesExpr is the parsed AST for the property map, when available.
	// Non-nil when the property map contains non-literal expressions (variable
	// references, property accesses, arithmetic) that must be evaluated at
	// runtime against the current row. The physical builder uses PropertiesExpr
	// when non-nil to construct a per-row evaluation closure; nil means all
	// values were literals and Properties (the string form) is sufficient.
	PropertiesExpr ast.Expression
	// Child is the driving subplan.
	Child LogicalPlan
}

CreateNode creates a new graph node with the given labels and properties, binding it to NodeVar.

func NewCreateNode

func NewCreateNode(nodeVar string, labels []string, properties string, child LogicalPlan) *CreateNode

NewCreateNode creates a CreateNode operator.

func NewCreateNodeExpr

func NewCreateNodeExpr(nodeVar string, labels []string, properties string, propertiesExpr ast.Expression, child LogicalPlan) *CreateNode

NewCreateNodeExpr creates a CreateNode operator with a parsed AST for the property map. Use when the property map contains non-literal expressions that require runtime evaluation.

func (*CreateNode) Children

func (c *CreateNode) Children() []LogicalPlan

Children implements LogicalPlan.

func (*CreateNode) Vars

func (c *CreateNode) Vars() []string

Vars implements LogicalPlan.

type CreateRelationship

type CreateRelationship struct {
	// StartVar is the already-bound source node variable.
	StartVar string
	// EndVar is the already-bound destination node variable.
	EndVar string
	// RelVar is the variable name bound to the newly created relationship.
	RelVar string
	// RelType is the relationship type.
	RelType string
	// Properties is the opaque string representation of the property map
	// expression.
	Properties string
	// PropertiesExpr is the parsed AST for the property map, when available.
	// Non-nil when the property map contains non-literal expressions that must
	// be evaluated at runtime against the current row. See CreateNode.PropertiesExpr.
	PropertiesExpr ast.Expression
	// Child is the driving subplan.
	Child LogicalPlan
}

CreateRelationship creates a new graph relationship between two already-bound nodes, binding the new relationship to RelVar.

func NewCreateRelationship

func NewCreateRelationship(startVar, endVar, relVar, relType, properties string, child LogicalPlan) *CreateRelationship

NewCreateRelationship creates a CreateRelationship operator.

func NewCreateRelationshipExpr

func NewCreateRelationshipExpr(startVar, endVar, relVar, relType, properties string, propertiesExpr ast.Expression, child LogicalPlan) *CreateRelationship

NewCreateRelationshipExpr creates a CreateRelationship operator with a parsed AST for the property map.

func (*CreateRelationship) Children

func (c *CreateRelationship) Children() []LogicalPlan

Children implements LogicalPlan.

func (*CreateRelationship) Vars

func (c *CreateRelationship) Vars() []string

Vars implements LogicalPlan.

type DeleteNode

type DeleteNode struct {
	// NodeVar is the already-bound node variable to delete.
	NodeVar string
	// TargetExpr is the parsed AST for the delete target when the target
	// is not a bare variable (e.g. `DELETE friends[$i]`, `DELETE map.key`,
	// `DELETE coll[0]`). When non-nil the exec builder uses it to evaluate
	// the target per row; the resulting NodeValue / IntegerValue identifies
	// the node to delete.
	TargetExpr ast.Expression
	// Child is the driving subplan.
	Child LogicalPlan
}

DeleteNode deletes an already-bound node from the graph. The node must have no relationships; use DetachDelete to delete a node together with its relationships.

func NewDeleteNode

func NewDeleteNode(nodeVar string, child LogicalPlan) *DeleteNode

NewDeleteNode creates a DeleteNode operator.

func NewDeleteNodeExpr

func NewDeleteNodeExpr(nodeVar string, targetExpr ast.Expression, child LogicalPlan) *DeleteNode

NewDeleteNodeExpr creates a DeleteNode operator carrying the parsed AST for the delete target. The exec builder evaluates the expression per row when the target is not a bare variable (e.g. `DELETE friends[$i]`, `DELETE map.key`).

func (*DeleteNode) Children

func (d *DeleteNode) Children() []LogicalPlan

Children implements LogicalPlan.

func (*DeleteNode) Vars

func (d *DeleteNode) Vars() []string

Vars implements LogicalPlan.

type DeleteRelationship

type DeleteRelationship struct {
	// RelVar is the already-bound relationship variable to delete.
	RelVar string
	// Child is the driving subplan.
	Child LogicalPlan
}

DeleteRelationship deletes an already-bound relationship from the graph.

func NewDeleteRelationship

func NewDeleteRelationship(relVar string, child LogicalPlan) *DeleteRelationship

NewDeleteRelationship creates a DeleteRelationship operator.

func (*DeleteRelationship) Children

func (d *DeleteRelationship) Children() []LogicalPlan

Children implements LogicalPlan.

func (*DeleteRelationship) Vars

func (d *DeleteRelationship) Vars() []string

Vars implements LogicalPlan.

type DetachDelete

type DetachDelete struct {
	// NodeVar is the already-bound node variable to delete.
	NodeVar string
	// TargetExpr is the parsed AST for the delete target when the target
	// is not a bare variable (e.g. `DETACH DELETE friends[$i]`,
	// `DETACH DELETE map.key`). Same role as DeleteNode.TargetExpr.
	TargetExpr ast.Expression
	// Child is the driving subplan.
	Child LogicalPlan
}

DetachDelete deletes an already-bound node and all its incident relationships.

func NewDetachDelete

func NewDetachDelete(nodeVar string, child LogicalPlan) *DetachDelete

NewDetachDelete creates a DetachDelete operator.

func NewDetachDeleteExpr

func NewDetachDeleteExpr(nodeVar string, targetExpr ast.Expression, child LogicalPlan) *DetachDelete

NewDetachDeleteExpr creates a DetachDelete operator carrying the parsed AST for the delete target.

func (*DetachDelete) Children

func (d *DetachDelete) Children() []LogicalPlan

Children implements LogicalPlan.

func (*DetachDelete) Vars

func (d *DetachDelete) Vars() []string

Vars implements LogicalPlan.

type Direction

type Direction uint8

Direction is the traversal direction for relationship expansion operators.

const (
	// DirectionOutgoing follows relationships in the outgoing direction (→).
	DirectionOutgoing Direction = iota
	// DirectionIncoming follows relationships in the incoming direction (←).
	DirectionIncoming
	// DirectionBoth follows relationships in either direction (—).
	DirectionBoth
)

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.

func (*Distinct) Vars

func (d *Distinct) Vars() []string

Vars implements LogicalPlan. Distinct does not introduce new variables.

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

func NewDropIndex(name string, ifExists bool) *DropIndex

NewDropIndex creates a DropIndex IR node.

func (*DropIndex) Children

func (d *DropIndex) Children() []LogicalPlan

Children implements LogicalPlan. DropIndex is a leaf.

func (*DropIndex) Vars

func (d *DropIndex) Vars() []string

Vars implements LogicalPlan. DropIndex introduces no variables.

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.

func NewEager

func NewEager(child LogicalPlan) *Eager

NewEager creates an Eager operator.

func (*Eager) Children

func (e *Eager) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Eager) Vars

func (e *Eager) Vars() []string

Vars implements LogicalPlan. Eager does not introduce new variables.

type EagerAggregation

type EagerAggregation struct {
	// GroupBy is the ordered list of grouping key variable names.
	GroupBy []string
	// GroupByExprs holds the parsed AST expression for each grouping key, in
	// the same order as GroupBy. Entries may be nil for legacy callers that
	// only supplied string keys; non-nil entries enable property-access and
	// complex expression evaluation at execution time.
	GroupByExprs []ast.Expression
	// Aggregates is the list of aggregate expressions computed per group.
	Aggregates []AggregateExpr
	// Child is the subplan whose rows are aggregated.
	Child LogicalPlan
}

EagerAggregation groups rows from its child by GroupBy keys and computes aggregate functions over each group.

func NewEagerAggregation

func NewEagerAggregation(groupBy []string, aggregates []AggregateExpr, child LogicalPlan) *EagerAggregation

NewEagerAggregation creates an EagerAggregation operator.

func NewEagerAggregationWithExprs

func NewEagerAggregationWithExprs(
	groupBy []string,
	groupByExprs []ast.Expression,
	aggregates []AggregateExpr,
	child LogicalPlan,
) *EagerAggregation

NewEagerAggregationWithExprs creates an EagerAggregation operator with parsed AST expressions for the grouping keys. groupBy and groupByExprs must have the same length; entries in groupByExprs may be nil (the executor falls back to a schema lookup keyed on the corresponding groupBy string in that case).

func (*EagerAggregation) Children

func (e *EagerAggregation) Children() []LogicalPlan

Children implements LogicalPlan.

func (*EagerAggregation) Vars

func (e *EagerAggregation) Vars() []string

Vars implements LogicalPlan. The output variables are the grouping keys followed by the aggregate output names.

type Expand

type Expand struct {
	// FromVar is the already-bound source node variable.
	FromVar string
	// RelVar is the variable name bound to the traversed relationship.
	RelVar string
	// RelTypes is the list of allowed relationship types. An empty slice means
	// any type is accepted.
	RelTypes []string
	// Direction is the traversal direction relative to FromVar.
	Direction Direction
	// ToVar is the variable name bound to the destination node.
	ToVar string
	// SiblingRelVars carries the names of relationship variables already bound
	// by earlier hops in the SAME MATCH pattern. The physical builder
	// translates each name to its schema column and passes the column set as
	// the Expand operator's relationship-isomorphism (cyphermorphism) guard,
	// so every anonymous or named relationship in one pattern maps to a
	// distinct edge per openCypher 9 §3.2.2.
	SiblingRelVars []string
	// PathVar, when non-empty, is the named-path variable this Expand
	// step participates in. Set by applyPathVar for mixed paths
	// (Expand + VLE) so the physical builder can record this hop's
	// (src, edge, dst) triplet as a leading segment in the same
	// pathVarMeta entry the downstream VLE updates — closing the
	// "missing leading hop" path-reconstruction gap (Match6 [14]).
	PathVar string
	// Child is the subplan that produces FromVar.
	Child LogicalPlan
}

Expand performs a single-hop relationship expansion from an already-bound FromVar and introduces a RelVar (relationship) and ToVar (destination node).

func NewExpand

func NewExpand(fromVar, relVar string, relTypes []string, dir Direction, toVar string, child LogicalPlan) *Expand

NewExpand creates an Expand operator.

func (*Expand) Children

func (e *Expand) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Expand) Vars

func (e *Expand) Vars() []string

Vars implements LogicalPlan.

type IndexType

type IndexType uint8

IndexType selects the backing store for a Cypher index.

const (
	// IndexTypeHash is a hash-based exact-match index (default).
	IndexTypeHash IndexType = iota
	// IndexTypeBTree is a B-tree range-capable index.
	IndexTypeBTree
)

type KVAction

type KVAction struct {
	Key   string
	Value string // opaque literal string (parsed at physical-build time)
}

KVAction is a (key, value) pair captured by the IR for MERGE ON CREATE / ON MATCH SET items.

type Limit

type Limit struct {
	// Count is the maximum number of rows to pass through. Ignored when
	// CountExpr is non-nil.
	Count int64
	// CountExpr is the parsed AST for the LIMIT expression when it is
	// not a literal integer (typically a parameter reference like
	// $limit). Nil when Count is the authoritative value.
	CountExpr ast.Expression
	// Child is the subplan whose output is truncated.
	Child LogicalPlan
}

Limit truncates the row stream from its child to at most Count rows. When CountExpr is non-nil it overrides Count and the limit is evaluated at physical-build time against the query parameters; this defers parameter resolution so the same cached plan works across calls with different parameter values.

func NewLimit

func NewLimit(count int64, child LogicalPlan) *Limit

NewLimit creates a Limit operator with a literal count.

func NewLimitExpr

func NewLimitExpr(countExpr ast.Expression, child LogicalPlan) *Limit

NewLimitExpr creates a Limit operator whose count is resolved at physical-build time from the given AST expression. countExpr must be a parameter reference or another expression whose evaluation yields an integer.

func (*Limit) Children

func (l *Limit) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Limit) Vars

func (l *Limit) Vars() []string

Vars implements LogicalPlan. Limit does not introduce new variables.

type LogicalPlan

type LogicalPlan interface {
	// Children returns the direct children of this operator. Leaf operators
	// return nil. Unary operators return a single-element slice. Binary
	// operators return a two-element slice [left, right].
	Children() []LogicalPlan

	// Vars returns the variable names introduced or required by this operator.
	// The order is unspecified but deterministic for a given operator instance.
	Vars() []string
}

LogicalPlan is the root interface implemented by every logical-plan operator. Children returns the operator's child plans in evaluation order (left to right for binary operators). Vars returns the set of variable names produced or consumed by this operator.

Concurrency: plan trees are immutable after construction; concurrent reads are safe without external locking.

func FromAST

func FromAST(q ast.Query) (LogicalPlan, error)

FromAST converts a post-parse ast.Query into a LogicalPlan tree following the Marton (2017) algebra. The function dispatches per clause and assembles operators bottom-up.

Unsupported constructs (FOREACH, multi-graph constructs beyond UNION) return a *TranslateError so callers can distinguish them from internal failures.

Concurrency: FromAST is stateless; it is safe to call concurrently.

Example

ExampleFromAST translates a parsed query into a logical plan and prints the canonical name of the root operator.

package main

import (
	"fmt"

	"github.com/FlavioCFOliveira/GoGraph/cypher/ir"
	"github.com/FlavioCFOliveira/GoGraph/cypher/parser"
)

func main() {
	q, err := parser.Parse("MATCH (n:Person) RETURN n")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	plan, err := ir.FromAST(q)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("root operator:", ir.OperatorName(plan))
}
Output:
root operator: ProduceResults

func ParseDDL

func ParseDDL(query string) (LogicalPlan, error)

ParseDDL parses a DDL query string and returns a LogicalPlan (one of *CreateIndex, *DropIndex, *CreateConstraint, *DropConstraint). Returns an error for unrecognised DDL.

func TranslateSubquery

func TranslateSubquery(q *ast.SingleQuery, outerVars []string, argTag uint32) (LogicalPlan, error)

TranslateSubquery translates a single-query AST (the body of an EXISTS / COUNT subquery) into a LogicalPlan rooted at an Argument leaf carrying the supplied correlation variables and ArgTag. The returned plan is suitable as the inner pipeline of a per-row subquery driver.

outerVars is the list of variable names visible from the lexical outer scope at the subquery's call site; they are injected into the inner pipeline through the leading Argument so correlated patterns (e.g. (n)-->() where n is bound outside) observe the outer row's bindings at runtime.

argTag must equal the tag the physical builder will register the seed Argument under in its argByTag map; the leading IR Argument carries this tag so the leaf operator resolves to the same exec.Argument instance.

Concurrency: stateless; safe to call concurrently.

type Merge

type Merge struct {
	// Pattern is the opaque string representation of the MERGE pattern.
	Pattern string
	// OnCreate is the list of update expression strings applied when the pattern
	// is created (the ON CREATE SET sub-clause).
	OnCreate []string
	// OnMatch is the list of update expression strings applied when the pattern
	// is matched (the ON MATCH SET sub-clause).
	OnMatch []string
	// BoundVars lists the variable names that are bound by the MERGE pattern and
	// made available downstream.
	BoundVars []string
	// NodePropsAST carries the property-map AST of the first node pattern in
	// the MERGE pattern, when present. The physical builder consults it to
	// decide whether the property map contains row-driven expressions (e.g.
	// `MERGE (p:Person {login: prop.login})` after an UNWIND) and, if so,
	// installs a per-row PropsEvalFn on the [exec.Merge] operator.
	// nil when no inline property map is present or when MERGE is shaped as
	// a relationship MERGE (handled by [MergeRelationship]).
	NodePropsAST ast.Expression
	// Child is the driving subplan.
	Child LogicalPlan
}

Merge implements the MERGE clause: it matches the given pattern or creates it if absent. OnCreate and OnMatch hold the update expressions applied under each branch (opaque strings; a dedicated expression IR is introduced later).

func NewMerge

func NewMerge(pattern string, onCreate, onMatch, boundVars []string, child LogicalPlan) *Merge

NewMerge creates a Merge operator.

func (*Merge) Children

func (m *Merge) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Merge) Vars

func (m *Merge) Vars() []string

Vars implements LogicalPlan.

type MergeRelationship

type MergeRelationship struct {
	// SrcVar is the variable name of the source endpoint.
	SrcVar string
	// DstVar is the variable name of the destination endpoint.
	DstVar string
	// RelVar is the relationship variable name (may be empty for an
	// anonymous relationship).
	RelVar string
	// RelType is the relationship type label.
	RelType string
	// RelProps is the opaque map-literal string representation of the
	// inline relationship property predicate (e.g. `{name: 'r2'}`). Empty
	// when the MERGE pattern declares no inline properties on the
	// relationship. When non-empty the exec operator filters the
	// search by these properties and writes them on creation.
	RelProps string
	// Undirected reports whether the MERGE relationship pattern declares
	// an undirected hop (`MERGE (a)-[r:T]-(b)`). When true the exec
	// operator searches for an existing edge in either direction before
	// creating one (closes Merge5 [13]).
	Undirected bool
	// OnCreate is the list of (key, value) pairs to set on the
	// relationship when a new edge is created.
	OnCreate []KVAction
	// OnMatch is the list of (key, value) pairs to set on the
	// relationship when an existing edge is matched.
	OnMatch []KVAction
	// Child is the driving subplan that binds SrcVar and DstVar.
	Child LogicalPlan
}

MergeRelationship is the relationship-pattern variant of Merge. It targets the single-hop MERGE shape `(src)-[r:T]->(dst)` where both endpoints are bound by an upstream operator (a preceding MATCH or CREATE). The physical builder emits an exec.MergeRelationship that checks for an existing edge between the bound endpoints with the requested type and creates one when absent. ON CREATE / ON MATCH actions targeting the relationship variable are applied to the matched-or-created edge.

More elaborate MERGE shapes (multi-hop patterns, inline relationship properties, ON-actions on a different variable, re-asserted endpoint predicates) keep using the node-only Merge path.

func NewMergeRelationship

func NewMergeRelationship(srcVar, dstVar, relVar, relType string, child LogicalPlan) *MergeRelationship

NewMergeRelationship creates a MergeRelationship operator without ON CREATE / ON MATCH actions.

func NewMergeRelationshipWithActions

func NewMergeRelationshipWithActions(srcVar, dstVar, relVar, relType string, onCreate, onMatch []KVAction, child LogicalPlan) *MergeRelationship

NewMergeRelationshipWithActions creates a MergeRelationship that also applies the supplied ON CREATE / ON MATCH actions.

func (*MergeRelationship) Children

func (m *MergeRelationship) Children() []LogicalPlan

Children implements LogicalPlan.

func (*MergeRelationship) Vars

func (m *MergeRelationship) Vars() []string

Vars implements LogicalPlan. The merged relationship introduces its variable into the downstream scope when named.

type NamedPath

type NamedPath struct {
	// PathName is the user-visible path variable name (e.g. "p").
	PathName string
	// Chain is the alternating node/rel description of the pattern, in
	// document order. The first entry has IsLeading=true.
	Chain []PathChainElement
	// Child is the subplan that produces the chain's variables.
	Child LogicalPlan
}

NamedPath is a pure pass-through operator that records the structure of a named-path pattern (`p = (a)-[r]->(b)`). Its sole purpose is to convey the alternating node/rel chain from the IR translator down to the physical builder so the projection can reconstruct an [expr.PathValue] by reading the rows emitted by the underlying Expand operators.

Concurrency: immutable after construction; safe for concurrent reads.

func NewNamedPath

func NewNamedPath(pathName string, chain []PathChainElement, child LogicalPlan) *NamedPath

NewNamedPath constructs a NamedPath operator wrapping child. The chain is shallow-copied; element slices (RelTypes) are not deep-copied because callers always pass freshly-allocated slices.

func (*NamedPath) Children

func (n *NamedPath) Children() []LogicalPlan

Children implements LogicalPlan.

func (*NamedPath) Vars

func (n *NamedPath) Vars() []string

Vars implements LogicalPlan. The path variable is the only new name introduced by this operator.

type NodeByIndexRangeScan

type NodeByIndexRangeScan struct {
	// NodeVar is the variable name bound to each matching node.
	NodeVar string
	// Label is the indexed node label.
	Label string
	// Property is the indexed property key.
	Property string
	// Min is the lower bound (inclusive/exclusive) or nil for an open lower end.
	Min *Bound
	// Max is the upper bound (inclusive/exclusive) or nil for an open upper end.
	Max *Bound
}

NodeByIndexRangeScan performs a range-scan index lookup on a property and binds each matching node to NodeVar. Either Min or Max (or both) must be non-nil; a nil bound means the range is open on that end.

func NewNodeByIndexRangeScan

func NewNodeByIndexRangeScan(nodeVar, label, property string, lower, upper *Bound) *NodeByIndexRangeScan

NewNodeByIndexRangeScan creates a NodeByIndexRangeScan operator.

func (*NodeByIndexRangeScan) Children

func (n *NodeByIndexRangeScan) Children() []LogicalPlan

Children implements LogicalPlan. NodeByIndexRangeScan is a leaf; it returns nil.

func (*NodeByIndexRangeScan) Vars

func (n *NodeByIndexRangeScan) Vars() []string

Vars implements LogicalPlan.

type NodeByIndexSeek

type NodeByIndexSeek struct {
	// NodeVar is the variable name bound to each matching node.
	NodeVar string
	// Label is the indexed node label.
	Label string
	// Property is the indexed property key.
	Property string
	// Value is the opaque string representation of the exact-match value.
	Value string
}

NodeByIndexSeek performs an exact-match index lookup and binds each matching node to NodeVar.

func NewNodeByIndexSeek

func NewNodeByIndexSeek(nodeVar, label, property, value string) *NodeByIndexSeek

NewNodeByIndexSeek creates a NodeByIndexSeek operator.

func (*NodeByIndexSeek) Children

func (n *NodeByIndexSeek) Children() []LogicalPlan

Children implements LogicalPlan. NodeByIndexSeek is a leaf; it returns nil.

func (*NodeByIndexSeek) Vars

func (n *NodeByIndexSeek) Vars() []string

Vars implements LogicalPlan.

type NodeByLabelScan

type NodeByLabelScan struct {
	// NodeVar is the variable name bound to each scanned node.
	NodeVar string
	// Label is the node label to filter on.
	Label string
}

NodeByLabelScan scans nodes that carry a specific label and binds each to NodeVar.

func NewNodeByLabelScan

func NewNodeByLabelScan(nodeVar, label string) *NodeByLabelScan

NewNodeByLabelScan creates a NodeByLabelScan operator.

func (*NodeByLabelScan) Children

func (n *NodeByLabelScan) Children() []LogicalPlan

Children implements LogicalPlan. NodeByLabelScan is a leaf; it returns nil.

func (*NodeByLabelScan) Vars

func (n *NodeByLabelScan) Vars() []string

Vars implements LogicalPlan.

type OptionalApply

type OptionalApply struct {
	// Outer is the driving (left) subplan.
	Outer LogicalPlan
	// Inner is the optional correlated subplan.
	Inner LogicalPlan
	// ArgTag is the tag shared with the inner-side Argument leaf.
	ArgTag uint32
}

OptionalApply is the left-outer variant of CorrelatedApply. When the inner subplan produces zero rows for an outer row, the physical executor emits a single NULL-extended row consisting of the outer columns followed by NULL placeholders for every column the inner pipeline would have introduced.

OptionalApply is used for OPTIONAL MATCH when a non-empty driving subplan already provides the outer bindings (e.g. a preceding MATCH clause).

func NewOptionalApply

func NewOptionalApply(outer, inner LogicalPlan) *OptionalApply

NewOptionalApply creates an OptionalApply operator with a freshly issued Argument tag.

func NewOptionalApplyWithTag

func NewOptionalApplyWithTag(outer, inner LogicalPlan, tag uint32) *OptionalApply

NewOptionalApplyWithTag creates an OptionalApply with an explicit tag.

func (*OptionalApply) Children

func (o *OptionalApply) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Outer, Inner].

func (*OptionalApply) Vars

func (o *OptionalApply) Vars() []string

Vars implements LogicalPlan. The outer variables come first; inner variables not already present are appended.

type OptionalExpand

type OptionalExpand struct {
	// FromVar is the already-bound source node variable.
	FromVar string
	// RelVar is the variable name bound to the traversed relationship (or null).
	RelVar string
	// RelTypes is the list of allowed relationship types. An empty slice means
	// any type is accepted.
	RelTypes []string
	// Direction is the traversal direction relative to FromVar.
	Direction Direction
	// ToVar is the variable name bound to the destination node (or null).
	ToVar string
	// Child is the subplan that produces FromVar.
	Child LogicalPlan
}

OptionalExpand performs a left-outer-join relationship expansion. When no relationship is found the row is kept with RelVar and ToVar bound to null.

func NewOptionalExpand

func NewOptionalExpand(fromVar, relVar string, relTypes []string, dir Direction, toVar string, child LogicalPlan) *OptionalExpand

NewOptionalExpand creates an OptionalExpand operator.

func (*OptionalExpand) Children

func (o *OptionalExpand) Children() []LogicalPlan

Children implements LogicalPlan.

func (*OptionalExpand) Vars

func (o *OptionalExpand) Vars() []string

Vars implements LogicalPlan.

type PathChainElement

type PathChainElement struct {
	// NodeVar is the variable name of the (destination) node for this step,
	// or "" when the node is anonymous.
	NodeVar string
	// RelVar is the variable name of the relationship leading into NodeVar,
	// or "" when the relationship is anonymous. Empty when IsLeading is true.
	RelVar string
	// RelTypes carries the relationship type filter declared in the pattern
	// (e.g. KNOWS in `-[:KNOWS]->`). Empty when IsLeading is true or when no
	// type was specified. Used as a fallback edge type when the live graph
	// lookup cannot resolve one.
	RelTypes []string
	// Direction is the traversal direction relative to the previous node
	// (PreviousNode → NodeVar). Meaningful only when IsLeading is false.
	Direction Direction
	// IsLeading is true for the first element of the chain (the source node
	// of the path).
	IsLeading bool
}

PathChainElement is one step in a named-path chain. The leading step has IsLeading=true and only NodeVar is meaningful; subsequent steps describe an alternating relationship+destination-node pair: the relationship's RelVar, RelTypes and Direction together with the destination NodeVar.

Anonymous node and relationship variables are conveyed as empty strings; they are not user-projectable but are still required so that the physical builder can locate the matching schema slot emitted by the upstream Expand operator (which always allocates a slot, even for anonymous patterns).

type ProcedureCall

type ProcedureCall struct {
	// Namespace is the optional namespace path of the procedure
	// (e.g. ["apoc", "algo"] for apoc.algo.dijkstra).
	Namespace []string
	// Name is the bare procedure name.
	Name string
	// Arguments is the list of opaque string representations of the call
	// argument expressions.
	Arguments []string
	// YieldVars is the ordered list of variable names produced by the YIELD
	// clause. An empty slice means YIELD * (all output columns).
	YieldVars []string
	// YieldSourceNames is the parallel list of declared procedure-output
	// names that each YieldVars entry binds (the LHS in `YIELD col AS alias`,
	// or the same name as YieldVars when no AS rename is present). Used by
	// the physical builder to map yield aliases to the procedure's declared
	// output column index, so `CALL proc(…) YIELD b, a` (procedure declares
	// outputs in order a, b) reads each column from the correct slot.
	// Empty slice means defaulted to YieldVars (no AS rename).
	YieldSourceNames []string
	// Child is the driving subplan. May be nil when CALL appears at the start
	// of a query.
	Child LogicalPlan
}

ProcedureCall invokes a stored procedure and binds its yield columns. It corresponds to CALL procedure(…) YIELD col1, col2 in Cypher.

func NewProcedureCall

func NewProcedureCall(namespace []string, name string, arguments, yieldVars []string, child LogicalPlan) *ProcedureCall

NewProcedureCall creates a ProcedureCall operator.

func (*ProcedureCall) Children

func (p *ProcedureCall) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Child] when Child is non-nil, otherwise nil.

func (*ProcedureCall) Vars

func (p *ProcedureCall) Vars() []string

Vars implements LogicalPlan.

type ProduceResults

type ProduceResults struct {
	// Columns is the ordered list of output column names.
	Columns []string
	// Child is the subplan that produces the result rows.
	Child LogicalPlan
}

ProduceResults is the root operator of every logical plan tree. It names the final output columns that are returned to the query caller.

func NewProduceResults

func NewProduceResults(columns []string, child LogicalPlan) *ProduceResults

NewProduceResults creates a ProduceResults operator.

func (*ProduceResults) Children

func (p *ProduceResults) Children() []LogicalPlan

Children implements LogicalPlan.

func (*ProduceResults) Vars

func (p *ProduceResults) Vars() []string

Vars implements LogicalPlan.

type ProjectEndpoints

type ProjectEndpoints struct {
	// RelVar is the already-bound relationship variable.
	RelVar string
	// StartVar is the variable name bound to the start node (may be empty if
	// not needed).
	StartVar string
	// EndVar is the variable name bound to the end node (may be empty if not
	// needed).
	EndVar string
	// Child is the subplan that produces RelVar.
	Child LogicalPlan
}

ProjectEndpoints projects the start and/or end nodes of a relationship variable that is already in scope.

func NewProjectEndpoints

func NewProjectEndpoints(relVar, startVar, endVar string, child LogicalPlan) *ProjectEndpoints

NewProjectEndpoints creates a ProjectEndpoints operator.

func (*ProjectEndpoints) Children

func (p *ProjectEndpoints) Children() []LogicalPlan

Children implements LogicalPlan.

func (*ProjectEndpoints) Vars

func (p *ProjectEndpoints) Vars() []string

Vars implements LogicalPlan.

type Projection

type Projection struct {
	// Items is the ordered list of output columns.
	Items []ProjectionItem
	// Child is the subplan whose rows are projected.
	Child LogicalPlan
}

Projection computes a set of named expressions (RETURN / WITH items) from its child's rows. Only the columns declared in Items are propagated downstream.

func NewProjection

func NewProjection(items []ProjectionItem, child LogicalPlan) *Projection

NewProjection creates a Projection operator.

func (*Projection) Children

func (p *Projection) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Projection) Vars

func (p *Projection) Vars() []string

Vars implements LogicalPlan.

type ProjectionItem

type ProjectionItem struct {
	// Name is the output variable name (the AS alias, or the expression's
	// canonical string representation when no alias is given).
	Name string
	// Expression is an opaque string representation of the expression.
	Expression string
	// Expr is the parsed AST for the expression, when available. Nil for
	// legacy or string-only callers. When non-nil, the executor evaluates it
	// via expr.Eval rather than falling back to a schema-key lookup.
	Expr ast.Expression
}

ProjectionItem is a named expression in a Projection operator.

type RemoveLabels

type RemoveLabels struct {
	// NodeVar is the already-bound node variable.
	NodeVar string
	// Labels is the list of labels to remove.
	Labels []string
	// Child is the driving subplan.
	Child LogicalPlan
}

RemoveLabels removes one or more labels from an already-bound node.

func NewRemoveLabels

func NewRemoveLabels(nodeVar string, labels []string, child LogicalPlan) *RemoveLabels

NewRemoveLabels creates a RemoveLabels operator.

func (*RemoveLabels) Children

func (r *RemoveLabels) Children() []LogicalPlan

Children implements LogicalPlan.

func (*RemoveLabels) Vars

func (r *RemoveLabels) Vars() []string

Vars implements LogicalPlan.

type RemoveProperty

type RemoveProperty struct {
	// EntityVar is the already-bound node or relationship variable.
	EntityVar string
	// PropertyKey is the property key to remove.
	PropertyKey string
	// Child is the driving subplan.
	Child LogicalPlan
}

RemoveProperty removes a single property from a node or relationship.

func NewRemoveProperty

func NewRemoveProperty(entityVar, propertyKey string, child LogicalPlan) *RemoveProperty

NewRemoveProperty creates a RemoveProperty operator.

func (*RemoveProperty) Children

func (r *RemoveProperty) Children() []LogicalPlan

Children implements LogicalPlan.

func (*RemoveProperty) Vars

func (r *RemoveProperty) Vars() []string

Vars 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].

func (*RollUpApply) Vars

func (r *RollUpApply) Vars() []string

Vars implements LogicalPlan.

type Selection

type Selection struct {
	// Predicate is the opaque string representation of the filter expression.
	Predicate string
	// PredicateExpr is the parsed AST for the predicate, when available. Nil
	// for legacy or string-only callers. When non-nil, the executor evaluates
	// it via expr.Eval rather than the pass-through stub.
	PredicateExpr ast.Expression
	// Child is the subplan whose rows are filtered.
	Child LogicalPlan
}

Selection filters rows from its child using Predicate. It corresponds to a WHERE clause in the logical plan.

func NewSelection

func NewSelection(predicate string, child LogicalPlan) *Selection

NewSelection creates a Selection operator with a string-only predicate.

func NewSelectionExpr

func NewSelectionExpr(predicate string, predExpr ast.Expression, child LogicalPlan) *Selection

NewSelectionExpr creates a Selection with both the string predicate and its parsed AST. The executor uses PredicateExpr when non-nil, falling back to the pass-through stub otherwise.

func (*Selection) Children

func (s *Selection) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Selection) Vars

func (s *Selection) Vars() []string

Vars implements LogicalPlan. Selection does not introduce new variables; it passes through the child's variables.

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

func (*SemiApply) Vars

func (s *SemiApply) Vars() []string

Vars implements LogicalPlan. Only outer variables are visible downstream.

type SetAllProperties

type SetAllProperties struct {
	// EntityVar is the already-bound node or relationship variable.
	EntityVar string
	// IsReplace selects `=` (true, replace) vs `+=` (false, merge) semantics.
	IsReplace bool
	// SourceVar names a bound node/relationship whose properties are copied.
	// Empty when the source is a literal map or a parameter reference.
	SourceVar string
	// MapLiteral holds the opaque literal-map string (e.g. `{a: 1, b: "x"}`)
	// produced by the AST printer. Empty when the source is a SourceVar or a
	// parameter reference.
	MapLiteral string
	// ParamName holds the `$name` reference text (without the dollar sign)
	// when the source is a parameter. Empty otherwise.
	ParamName string
	// Child is the driving subplan.
	Child LogicalPlan
}

SetAllProperties replaces or merges every property on an already-bound node or relationship per input row. It implements the Cypher SET entity-replace (`SET n = …`) and entity-append (`SET n += …`) forms.

The source side may be one of:

  • A bound entity reference (SourceVar non-empty): copy all of the source entity's properties to the target.
  • A literal map (MapLiteral non-empty): write each key/value pair as parsed by the exec literal-map parser.
  • A query parameter (ParamName non-empty): resolve at exec time.

IsReplace=true models `SET n = …` semantics: every existing property of the target is removed before the source is applied. IsReplace=false models `SET n += …` semantics: existing properties are kept unless overwritten by a same-keyed entry in the source.

In both modes, null values in the source map remove the matching property from the target.

func NewSetAllPropertiesFromEntity

func NewSetAllPropertiesFromEntity(entityVar, sourceVar string, isReplace bool, child LogicalPlan) *SetAllProperties

NewSetAllPropertiesFromEntity creates a SetAllProperties operator copying every property from sourceVar (a bound node or relationship) to entityVar.

func NewSetAllPropertiesFromMap

func NewSetAllPropertiesFromMap(entityVar, mapLiteral string, isReplace bool, child LogicalPlan) *SetAllProperties

NewSetAllPropertiesFromMap creates a SetAllProperties operator writing every key/value pair from a literal map expression to entityVar.

func NewSetAllPropertiesFromParam

func NewSetAllPropertiesFromParam(entityVar, paramName string, isReplace bool, child LogicalPlan) *SetAllProperties

NewSetAllPropertiesFromParam creates a SetAllProperties operator writing every key/value pair from the named query parameter to entityVar.

func (*SetAllProperties) Children

func (s *SetAllProperties) Children() []LogicalPlan

Children implements LogicalPlan.

func (*SetAllProperties) Vars

func (s *SetAllProperties) Vars() []string

Vars implements LogicalPlan. SetAllProperties does not introduce new variables. When a SourceVar is set, it is reported so plan walkers can see the dependency.

type SetLabels

type SetLabels struct {
	// NodeVar is the already-bound node variable.
	NodeVar string
	// Labels is the list of labels to add.
	Labels []string
	// Child is the driving subplan.
	Child LogicalPlan
}

SetLabels adds one or more labels to an already-bound node.

func NewSetLabels

func NewSetLabels(nodeVar string, labels []string, child LogicalPlan) *SetLabels

NewSetLabels creates a SetLabels operator.

func (*SetLabels) Children

func (s *SetLabels) Children() []LogicalPlan

Children implements LogicalPlan.

func (*SetLabels) Vars

func (s *SetLabels) Vars() []string

Vars implements LogicalPlan.

type SetProperty

type SetProperty struct {
	// EntityVar is the already-bound node or relationship variable.
	EntityVar string
	// PropertyKey is the property key to set.
	PropertyKey string
	// Value is the opaque string representation of the new value expression.
	Value string
	// ValueExpr is the parsed AST for the value expression when available.
	// The physical builder uses it to construct a per-row evaluator so that
	// non-literal RHS expressions (variable references, arithmetic, property
	// access, function calls) actually run against each input row instead of
	// silently failing the literal-parser fast path.
	ValueExpr ast.Expression
	// Child is the driving subplan.
	Child LogicalPlan
}

SetProperty sets or updates a single property on a node or relationship.

func NewSetProperty

func NewSetProperty(entityVar, propertyKey, value string, child LogicalPlan) *SetProperty

NewSetProperty creates a SetProperty operator.

func NewSetPropertyExpr

func NewSetPropertyExpr(entityVar, propertyKey, value string, valueExpr ast.Expression, child LogicalPlan) *SetProperty

NewSetPropertyExpr creates a SetProperty operator carrying the parsed AST for the value expression. The exec builder uses it to evaluate non-literal RHS expressions per row.

func (*SetProperty) Children

func (s *SetProperty) Children() []LogicalPlan

Children implements LogicalPlan.

func (*SetProperty) Vars

func (s *SetProperty) Vars() []string

Vars implements LogicalPlan. SetProperty does not introduce new variables.

type Skip

type Skip struct {
	// Count is the number of leading rows to skip. Ignored when
	// CountExpr is non-nil.
	Count int64
	// CountExpr is the parsed AST for the SKIP expression when it is
	// not a literal integer. Nil when Count is the authoritative value.
	CountExpr ast.Expression
	// Child is the subplan whose leading rows are discarded.
	Child LogicalPlan
}

Skip discards the first Count rows from its child's output. See Limit for the CountExpr deferred-resolution contract.

func NewSkip

func NewSkip(count int64, child LogicalPlan) *Skip

NewSkip creates a Skip operator with a literal count.

func NewSkipExpr

func NewSkipExpr(countExpr ast.Expression, child LogicalPlan) *Skip

NewSkipExpr creates a Skip operator whose count is resolved at physical-build time from the given AST expression.

func (*Skip) Children

func (s *Skip) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Skip) Vars

func (s *Skip) Vars() []string

Vars implements LogicalPlan. Skip does not introduce new variables.

type Sort

type Sort struct {
	// SortItems is the ordered list of sort keys.
	SortItems []SortItem
	// Child is the subplan whose rows are sorted.
	Child LogicalPlan
}

Sort orders rows from its child according to SortItems.

func NewSort

func NewSort(items []SortItem, child LogicalPlan) *Sort

NewSort creates a Sort operator.

func (*Sort) Children

func (s *Sort) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Sort) Vars

func (s *Sort) Vars() []string

Vars implements LogicalPlan. Sort does not introduce new variables.

type SortItem

type SortItem struct {
	// Expression is an opaque string representation of the sort key expression.
	Expression string
	// Expr is the original AST expression for the sort key. It is carried
	// alongside Expression so the physical builder can compile an expression
	// evaluator for keys that are not directly present in the output schema
	// (e.g. ORDER BY n.age after RETURN n — n.age is not a projected column
	// but it can be derived by evaluating the expression against the row).
	// May be nil for sort items constructed without access to the AST.
	Expr ast.Expression
	// Descending indicates DESC ordering; false means ASC.
	Descending bool
}

SortItem is a single ORDER BY term in a Sort or Top operator.

type SubqueryCount

type SubqueryCount struct {
	// Inner is the subplan whose row-count is reported by the count.
	Inner LogicalPlan
	// CorrelationVars is the snapshot of outer-scope variable names visible
	// inside the subquery.
	CorrelationVars []string
	// ArgTag is the tag shared with the inner-side Argument leaf.
	ArgTag uint32
}

SubqueryCount is the COUNT { … } counterpart of SubqueryExists. The expression evaluator drives the inner plan per outer row and yields an IntegerValue equal to the exact number of rows the inner plan produced for the seeded correlation bindings (0 when the inner plan is empty).

SubqueryCount is a logical-plan node only by virtue of holding an Inner plan tree; it is not itself wired into the operator pipeline.

func NewSubqueryCount

func NewSubqueryCount(inner LogicalPlan, correlationVars []string) *SubqueryCount

NewSubqueryCount creates a SubqueryCount node with a freshly issued Argument tag.

func NewSubqueryCountWithTag

func NewSubqueryCountWithTag(inner LogicalPlan, correlationVars []string, tag uint32) *SubqueryCount

NewSubqueryCountWithTag creates a SubqueryCount with an explicit tag.

func (*SubqueryCount) Children

func (s *SubqueryCount) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Inner].

func (*SubqueryCount) Vars

func (s *SubqueryCount) Vars() []string

Vars implements LogicalPlan. SubqueryCount itself introduces no new variables in the outer scope: it yields an integer value at evaluation time.

type SubqueryExists

type SubqueryExists struct {
	// Inner is the subplan whose row-count drives the existence check. Its
	// leftmost leaf must be an [Argument] whose Tag equals
	// [SubqueryExists.ArgTag].
	Inner LogicalPlan
	// CorrelationVars is the snapshot of outer-scope variable names that the
	// inner plan may reference at evaluation time. The expression evaluator
	// projects the outer row onto these names before seeding the Argument.
	CorrelationVars []string
	// ArgTag is the tag shared with the inner-side Argument leaf so the
	// physical builder routes the matching exec.Argument instance per outer
	// row.
	ArgTag uint32
}

SubqueryExists is a self-contained IR container for an EXISTS { … } subquery that appears inside an arbitrary expression (e.g. nested in a BinaryOp, a CASE branch, or a RETURN projection item). The node holds the inner logical plan plus the variables the subquery correlates from its lexical outer scope; the expression evaluator drives the inner plan per outer row at evaluation time and yields a BoolValue per openCypher semantics:

  • true when the inner plan produces at least one row for the seeded correlation bindings;
  • false when the inner plan produces zero rows.

Unlike SemiApply, which is a top-level plan operator that filters its outer pipeline by row-count, SubqueryExists is an expression-embedded form used wherever an EXISTS { … } occurs as a sub-expression. The two paths are complementary: the IR translator emits SemiApply whenever an EXISTS is the entire WHERE predicate (so the existence check can short-circuit at the plan level), and emits SubqueryExists for every other occurrence.

SubqueryExists is a logical-plan node only by virtue of holding an Inner plan tree; it is not itself wired into the operator pipeline. The physical builder reaches it through the expression evaluator, not through [buildOperator].

func NewSubqueryExists

func NewSubqueryExists(inner LogicalPlan, correlationVars []string) *SubqueryExists

NewSubqueryExists creates a SubqueryExists node with a freshly issued Argument tag. The caller is responsible for placing an Argument node carrying the same tag at the leftmost leaf of inner.

func NewSubqueryExistsWithTag

func NewSubqueryExistsWithTag(inner LogicalPlan, correlationVars []string, tag uint32) *SubqueryExists

NewSubqueryExistsWithTag creates a SubqueryExists with an explicit tag.

func (*SubqueryExists) Children

func (s *SubqueryExists) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Inner].

func (*SubqueryExists) Vars

func (s *SubqueryExists) Vars() []string

Vars implements LogicalPlan. SubqueryExists itself introduces no new variables in the outer scope: it yields a boolean value at evaluation time.

type Top

type Top struct {
	// SortItems is the ordered list of sort keys.
	SortItems []SortItem
	// Limit is the maximum number of rows to produce.
	Limit int64
	// Child is the subplan whose rows are sorted and truncated.
	Child LogicalPlan
}

Top is a fused ORDER BY … LIMIT operator that sorts and truncates in a single pass, avoiding the need to materialise the full sorted result.

func NewTop

func NewTop(items []SortItem, limit int64, child LogicalPlan) *Top

NewTop creates a Top operator.

func (*Top) Children

func (t *Top) Children() []LogicalPlan

Children implements LogicalPlan.

func (*Top) Vars

func (t *Top) Vars() []string

Vars implements LogicalPlan. Top does not introduce new variables.

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 NewUnion

func NewUnion(left, right LogicalPlan) *Union

NewUnion creates a Union operator.

func (*Union) Children

func (u *Union) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Left, Right].

func (*Union) Vars

func (u *Union) Vars() []string

Vars implements LogicalPlan. Returns the left child's variables (both sides must produce the same schema).

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

func (*UnionAll) Vars

func (u *UnionAll) Vars() []string

Vars implements LogicalPlan.

type Unwind

type Unwind struct {
	// ListExpression is the opaque string representation of the list expression.
	ListExpression string
	// ListExpr is the parsed AST for the list expression, when available. Nil
	// means the expression could not be parsed; callers must fall back to a
	// static empty list. The executor uses ListExpr when non-nil.
	ListExpr ast.Expression
	// ElementVar is the variable name bound to each list element.
	ElementVar string
	// Child is the subplan that provides the context rows. May be nil when
	// UNWIND appears at the start of a query.
	Child LogicalPlan
}

Unwind expands a list-valued expression into one row per element, binding each element to ElementVar. It corresponds to the UNWIND clause.

func NewUnwind

func NewUnwind(listExpression, elementVar string, child LogicalPlan) *Unwind

NewUnwind creates an Unwind operator with a string-only list expression.

func NewUnwindExpr

func NewUnwindExpr(listExpression string, listExpr ast.Expression, elementVar string, child LogicalPlan) *Unwind

NewUnwindExpr creates an Unwind operator with both the string and its parsed AST. The executor uses ListExpr when non-nil, falling back to an empty list.

func (*Unwind) Children

func (u *Unwind) Children() []LogicalPlan

Children implements LogicalPlan. Returns [Child] when Child is non-nil, otherwise nil.

func (*Unwind) Vars

func (u *Unwind) Vars() []string

Vars implements LogicalPlan.

type VarLengthExpand

type VarLengthExpand struct {
	// FromVar is the already-bound source node variable.
	FromVar string
	// RelVar is the variable name bound to the collected path relationships.
	RelVar string
	// RelTypes is the list of allowed relationship types. An empty slice means
	// any type is accepted.
	RelTypes []string
	// Direction is the traversal direction relative to FromVar.
	Direction Direction
	// ToVar is the variable name bound to the destination node.
	ToVar string
	// MinDepth is the minimum number of hops (inclusive, ≥1).
	MinDepth int
	// MaxDepth is the maximum number of hops (inclusive). Zero means unbounded.
	MaxDepth int
	// PathVar, when non-empty, is the named path variable (`p` in
	// `MATCH p=(a)-[*1..3]->(b)`). The physical builder allocates a schema slot
	// for it and emits a PathValue in that column.
	PathVar string
	// ExcludedRelVars lists relationship-variable names already in scope
	// at the time this VLE step is reached whose bound edge must not be
	// traversed. Implements the openCypher no-repeated-relationships rule
	// across distinct rel patterns in the same MATCH (e.g. `MATCH ()-[r]
	// -() MATCH (n)-[*0..1]-()-[r]-()-[*0..1]-(m)` — the two VLE steps
	// must exclude r's edge). The physical builder resolves each name
	// against the current schema; unresolved names are silently dropped
	// (the variable is not yet bound).
	ExcludedRelVars []string
	// Child is the subplan that produces FromVar.
	Child LogicalPlan
}

VarLengthExpand performs a variable-length path expansion between MinDepth and MaxDepth hops. A MaxDepth of zero means unbounded.

func NewVarLengthExpand

func NewVarLengthExpand(fromVar, relVar string, relTypes []string, dir Direction, toVar string, minDepth, maxDepth int, child LogicalPlan) *VarLengthExpand

NewVarLengthExpand creates a VarLengthExpand operator.

func (*VarLengthExpand) Children

func (v *VarLengthExpand) Children() []LogicalPlan

Children implements LogicalPlan.

func (*VarLengthExpand) Vars

func (v *VarLengthExpand) Vars() []string

Vars implements LogicalPlan.

Directories

Path Synopsis
Package rewrite provides a rule-based logical-plan rewrite/optimisation framework for the Cypher IR.
Package rewrite provides a rule-based logical-plan rewrite/optimisation framework for the Cypher IR.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL