Documentation
¶
Overview ¶
Package query's physical_plan.go declares the Volcano-model physical operator interface and 16 concrete operator implementations (C3.0 extraction).
Status: PARTIAL. C3.0 lifts the operator types + execution logic from origin/archive/gemini-bulk-2026-05-13^3 with no consumers. The existing Step-based Executor (executor.go + executor_steps.go) keeps serving the /v1/cypher endpoint; this file's operators run only when wired by C4 (planner) + C5 (parser additions) in later PRs.
Deferred:
- CallOperator (CALL ... YIELD) — references procedureRegistry, which lives in procedures.go (C6 territory). To preserve the per-PR discipline, it lands alongside C6 rather than dragging C6 forward.
- Operator-level unit tests — deferred to C3.1 (mirroring the C1.0 + C1.1 split that surfaced a real navigation bug in the btree archive).
Each operator carries `otel.Tracer("query").Start(...)` spans on Open (and on Next where loop hot-paths warrant it) per the audit's S7 verdict. The acceptance bar of "OTEL spans visible in pkg/telemetry/ exporter integration test" cannot be met because pkg/telemetry does not yet exist in the tree; surface added so a future telemetry extraction can wire to it.
Operator families split into sibling files:
- physical_ops_scan.go — NodeScanOperator, IndexSeekOperator, ExpandOperator, OptionalMatchOperator
- physical_ops_mutate.go — CreateOperator, SetOperator, DeleteOperator, RemoveOperator, MergeOperator
- physical_ops_project.go — FilterOperator, ProjectOperator, UnwindOperator, UnionOperator, AggregateOperator
- physical_ops_join.go — NestedLoopJoinOperator, HashJoinOperator
- physical_ops_call.go — CallOperator
Package query's planner.go translates a Query AST into a tree of PhysicalOperators (C4.0 extraction + C4.1 q.Call reinstate). Consumes C3.0's operator types + C3.1's CallOperator.
Status: PARTIAL. The planner runs only when wired by a planner-driven executor path; the existing Step-based Executor (executor.go + executor_steps.go) keeps serving /v1/cypher. C5 (parser CALL/YIELD) + C3.1 (CallOperator) + this file's q.Call block now form the full AST → operator translation for CALL ... YIELD; execution requires C6's procedure bodies (Decision-6-gated in NEXT_STEPS_2026-05-13.md).
Deferred:
- Planner-level unit tests — deferred (mirroring the C1.0/C1.1 and C3.0/C3.1 splits). The q.Call reinstate in C4.1 specifically should get a planner test that confirms a parsed CALL query produces a plan tree containing CallOperator at the right position.
Several archive comments are preserved verbatim: "Simplified" on the OPTIONAL MATCH path, "for the spike" on the linear-expansion comment, "redundant but safe" on isWhereConsumedByIndex. These are honest spike markers — left intact to keep the lift surgical; cleanup belongs in a follow-up once tests anchor the contract.
Package query — procedure registry + procedure bodies for Cypher CALL ... YIELD.
History:
- C3.1 (PR #175): registry SKELETON (Procedure type, empty map, RegisterProcedure exported func) so CallOperator could compile.
- C6 (this file): registers the first real procedure, algo.shortestPath, by wiring to pkg/algorithms.ShortestPathForTenant. Per Decision 6 = B (NEXT_STEPS_2026-05-13.md, resolved 2026-05-13), the algorithm takes storage.Storage (interface) so the procedure passes graph through without type assertion.
Future procedures:
- gnn.messagePass — skipped; pkg/gnn doesn't exist on OSS (Subset 🟢 audit note carries forward).
- llm.generate — dropped; pkg/intelligence doesn't exist on OSS (Decision 4 retired 2026-05-13 by package absence).
- Backend-specific procedures may register via RegisterProcedure at init.
Index ¶
- Constants
- Variables
- func Collect(stream *ResultStream) ([]*storage.Node, error)
- func Count(stream *ResultStream) (int, error)
- func RegisterFunction(name string, fn QueryFunc)
- func RegisterProcedure(name string, proc Procedure)
- func SanitizeQuery(query string) (string, error)
- func ValidateQueryTimeout(timeout time.Duration) time.Duration
- func ValidateTaskTimeout(timeout time.Duration) time.Duration
- func ValidateTimeout(timeout time.Duration, config TimeoutConfig) time.Duration
- func ValidateTraversalOptions(opts *TraversalOptions) error
- func WithDefaultDepth(depth int) int
- type AggregateOperator
- type AggregationComputer
- func (ac *AggregationComputer) ComputeAggregates(ctx *ExecutionContext, returnItems []*ReturnItem) map[string]any
- func (ac *AggregationComputer) ComputeGroupedAggregates(ctx *ExecutionContext, returnItems []*ReturnItem, ...) []map[string]any
- func (ac *AggregationComputer) ExtractValue(val storage.Value) any
- type ArithmeticExpression
- type Assignment
- type BatchProcessor
- type BinaryExpression
- type BindingSet
- type CallClause
- type CallOperator
- type CaseExpression
- type CaseWhen
- type CreateClause
- type CreateOperator
- type CreateStep
- type DeleteClause
- type DeleteOperator
- type DeleteStep
- type Direction
- type ExecutionContext
- type ExecutionPlan
- type ExecutionStep
- type Executor
- func (e *Executor) Execute(query *Query) (*ResultSet, error)
- func (e *Executor) ExecuteWithContext(ctx context.Context, query *Query) (*ResultSet, error)
- func (e *Executor) ExecuteWithOptions(ctx context.Context, query *Query, opts PathOptions) (result *ResultSet, err error)
- func (e *Executor) ExecuteWithParams(query *Query, params map[string]any) (*ResultSet, error)
- func (e *Executor) ExecuteWithParamsContext(ctx context.Context, query *Query, params map[string]any) (*ResultSet, error)
- func (e *Executor) ExecuteWithText(queryText string, query *Query) (*ResultSet, error)
- func (e *Executor) SetQueryTimeout(timeout time.Duration)
- func (e *Executor) SetSearchIndex(idx *search.FullTextIndex)
- func (e *Executor) SetVectorSearch(similarityFn VectorSimilarityFunc, searchFn VectorSearchFunc, ...)
- type ExpandFilter
- type ExpandOperator
- type Expansion
- type Expression
- type FilterOperator
- type FilterStep
- type FunctionCallExpression
- type GetNodeFunc
- type HasVectorIndexFunc
- type HashJoinOperator
- type IndexLookupStep
- type IndexSeekOperator
- type Lexer
- type LiteralExpression
- type MatchClause
- type MatchStep
- type MergeClause
- type MergeOperator
- type MergeStep
- type NestedLoopJoinOperator
- type NodePattern
- type NodeScanOperator
- type Notice
- type OptimizationHint
- type Optimizer
- type OptionalMatchClause
- type OptionalMatchOperator
- type OptionalMatchStep
- type OrderByItem
- type ParallelAggregation
- type ParallelPathFinder
- type ParallelPipeline
- type ParallelTraversal
- type ParameterExpression
- type ParameterRef
- type Parser
- type Path
- type PathOptions
- type PathSemantics
- type Pattern
- type PhysicalOperator
- type PipelineStage
- type Planner
- type Procedure
- type ProjectOperator
- type PropertyExpression
- type Query
- type QueryCache
- type QueryFunc
- type QueryPipeline
- func (qp *QueryPipeline) AddStage(stage PipelineStage) *QueryPipeline
- func (qp *QueryPipeline) Execute(input *ResultStream) *ResultStream
- func (qp *QueryPipeline) Filter(predicate func(*storage.Node) bool) *QueryPipeline
- func (qp *QueryPipeline) Map(transform func(*storage.Node) *storage.Node) *QueryPipeline
- type QueryStatistics
- type RelationshipPattern
- type RemoveClause
- type RemoveItem
- type RemoveOperator
- type RemoveStep
- type ResultSet
- type ResultStream
- type ReturnClause
- type ReturnItem
- type ReturnStep
- type SetClause
- type SetOperator
- type SetStep
- type StepDescriber
- type StepProfile
- type StreamingQuery
- type Task
- type TaskResult
- type TimeoutConfig
- type Token
- type TokenType
- type TraversalError
- type TraversalOptions
- type TraversalResult
- type Traverser
- func (t *Traverser) BFS(opts TraversalOptions) (*TraversalResult, error)
- func (t *Traverser) DFS(opts TraversalOptions) (*TraversalResult, error)
- func (t *Traverser) FindAllPaths(fromID, toID uint64, maxDepth int, edgeTypes []string) ([]Path, error)
- func (t *Traverser) FindAllPathsWithPredicate(fromID, toID uint64, maxDepth int, edgeTypes []string, ...) ([]Path, error)
- func (t *Traverser) FindShortestPath(fromID, toID uint64, edgeTypes []string) (Path, error)
- func (t *Traverser) FindShortestPathWithPredicate(fromID, toID uint64, edgeTypes []string, ...) (Path, error)
- func (t *Traverser) GetNeighborhood(nodeID uint64, hops int, direction Direction) ([]*storage.Node, error)
- type UnaryExpression
- type UnionClause
- type UnionOperator
- type UnwindClause
- type UnwindOperator
- type UnwindStep
- type VectorSearchFunc
- type VectorSearchResult
- type VectorSearchStep
- type VectorSimilarityFunc
- type WhereClause
- type WithClause
- type WorkerPool
- type WorkerPoolStats
Constants ¶
const ( // DefaultQueryTimeout is the default timeout for query execution DefaultQueryTimeout = 30 * time.Second // MaxQueryTimeout is the maximum allowed query timeout MaxQueryTimeout = 5 * time.Minute )
const ( // MaxCartesianProductResults limits the maximum size of cartesian product // to prevent memory exhaustion from queries like MATCH (a), (b), (c) MaxCartesianProductResults = 100000 // MaxIntermediateResults limits intermediate results during query execution MaxIntermediateResults = 1000000 )
const ( // MinStreamBufferSize is the minimum buffer size to prevent deadlocks MinStreamBufferSize = 10 // DefaultStreamBufferSize is used when no size is specified DefaultStreamBufferSize = 100 )
const ( // DefaultMaxTraversalDepth is used when MaxDepth is not specified or is 0 DefaultMaxTraversalDepth = 10 // MaxAllowedTraversalDepth is the absolute maximum to prevent stack overflow in DFS // and memory exhaustion in BFS MaxAllowedTraversalDepth = 100 // MinTraversalDepth is the minimum valid depth (0 means only start node) MinTraversalDepth = 0 // DefaultMaxResults is used when MaxResults is not specified or is 0 DefaultMaxResults = 10000 // MaxAllowedResults is the absolute maximum to prevent memory exhaustion MaxAllowedResults = 1000000 )
Traversal depth limits to prevent resource exhaustion
const ( // DefaultTaskTimeout is the default timeout for individual task execution DefaultTaskTimeout = 30 * time.Second // MinTaskTimeout is the minimum allowed task timeout MinTaskTimeout = 1 * time.Second )
const (
// MaxQueryLength is the maximum allowed query length (10KB)
MaxQueryLength = 10000
)
const NoticePlainDeleteDetach = "plain-delete-detach"
NoticePlainDeleteDetach is the Code of the deprecation notice a plain DELETE records when it removes relationships the query did not name.
Variables ¶
var ErrDistinctNodesMinHops = errors.New("DistinctNodes semantics do not support MinHops above 1")
ErrDistinctNodesMinHops reports that DistinctNodes was combined with a MinHops of 2 or more, which the engine refuses rather than answers wrongly.
With one shared visited set a node is admitted at its minimum depth and never re-enters the queue. A node whose minimum depth is 1 is therefore admitted at depth 1, falls outside a [2, n] window, and never reappears at depth 2 — even when a genuine simple path of length 2 exists. The mode would drop rows that AllSimplePaths returns, and drop them silently. A loud refusal is the honest answer, and it costs nothing for MinHops of 0 or 1: the start node sits at depth 0 and every other admitted node sits at depth 1 or deeper, so no row can be lost there.
var ErrInvalidMaxResults = fmt.Errorf("MaxResults must be non-negative")
ErrInvalidMaxResults is returned when MaxResults is negative
var ErrInvalidTraversalDepth = fmt.Errorf("traversal depth out of valid range [%d, %d]", MinTraversalDepth, MaxAllowedTraversalDepth)
ErrInvalidTraversalDepth is returned when depth is out of valid range
var ErrTraversalTruncated = fmt.Errorf("traversal stopped at an engine limit; the result is incomplete")
ErrTraversalTruncated reports that a traversal stopped at an engine limit rather than because it ran out of graph.
It travels BESIDE the results, never instead of them: a caller gets what was found plus this error, and a nil error is the positive assertion that the answer is complete. That is ADR 0003's enumeration rule extended to traversal, and it exists because the alternative is a limit that acts and does not tell the caller — an answer to a question nobody asked, indistinguishable from an answer to the one they did.
var ErrUnknownPathSemantics = errors.New("unknown PathSemantics value")
ErrUnknownPathSemantics reports a PathSemantics value the engine does not know. Reading an unrecognised value as the default would run a traversal the caller did not ask for and say nothing about it.
Functions ¶
func Collect ¶
func Collect(stream *ResultStream) ([]*storage.Node, error)
Collect collects all results from a stream into a slice
func RegisterFunction ¶
RegisterFunction registers a named function for use in queries
func RegisterProcedure ¶
RegisterProcedure adds a procedure to the registry. Exported so external packages can register procedures (e.g. enterprise plugin loader, test fixtures) without requiring direct map access.
func SanitizeQuery ¶
SanitizeQuery validates and sanitizes a query string for security It checks for: - Maximum length (DoS prevention) - Dangerous patterns (XSS, SQL injection, code injection) - Empty/whitespace-only queries - Normalizes whitespace
func ValidateQueryTimeout ¶
ValidateQueryTimeout is a convenience function for validating query timeouts.
func ValidateTaskTimeout ¶
ValidateTaskTimeout is a convenience function for validating task timeouts.
func ValidateTimeout ¶
func ValidateTimeout(timeout time.Duration, config TimeoutConfig) time.Duration
ValidateTimeout validates and normalizes a timeout duration. Returns the default if timeout is <= 0. Returns min if timeout is less than min (when min > 0). Returns max if timeout exceeds max (when max > 0).
func ValidateTraversalOptions ¶
func ValidateTraversalOptions(opts *TraversalOptions) error
ValidateTraversalOptions validates and normalizes traversal options. Returns an error if options are invalid. Note: MaxDepth=0 is valid and means "only return the start node".
func WithDefaultDepth ¶
WithDefaultDepth returns the depth or DefaultMaxTraversalDepth if depth is <= 0. Use this when you want to apply a default for unspecified depths.
Types ¶
type AggregateOperator ¶
type AggregateOperator struct {
Input PhysicalOperator
Items []*ReturnItem
// contains filtered or unexported fields
}
AggregateOperator performs grouped aggregations.
func (*AggregateOperator) Close ¶
func (o *AggregateOperator) Close(ctx *ExecutionContext) error
func (*AggregateOperator) Next ¶
func (o *AggregateOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*AggregateOperator) Open ¶
func (o *AggregateOperator) Open(ctx *ExecutionContext) error
type AggregationComputer ¶
type AggregationComputer struct{}
AggregationComputer handles aggregate function computation
func (*AggregationComputer) ComputeAggregates ¶
func (ac *AggregationComputer) ComputeAggregates(ctx *ExecutionContext, returnItems []*ReturnItem) map[string]any
ComputeAggregates computes all aggregate functions in the return clause
func (*AggregationComputer) ComputeGroupedAggregates ¶
func (ac *AggregationComputer) ComputeGroupedAggregates(ctx *ExecutionContext, returnItems []*ReturnItem, groupByExprs []*PropertyExpression) []map[string]any
ComputeGroupedAggregates computes aggregates for each group
func (*AggregationComputer) ExtractValue ¶
func (ac *AggregationComputer) ExtractValue(val storage.Value) any
ExtractValue extracts the actual value from storage.Value
type ArithmeticExpression ¶
type ArithmeticExpression struct {
Left Expression
Operator string // "+", "-", "*", "/", "%"
Right Expression
}
ArithmeticExpression represents binary arithmetic: +, -, *, /, % Uses the dual-eval pattern: EvalValue returns the computed value, Eval coerces to bool for WHERE context.
type Assignment ¶
type Assignment struct {
Variable string
Property string
Value any // literal value (used when ValueExpr is nil)
ValueExpr Expression // expression RHS (takes precedence over Value when non-nil)
}
Assignment represents a property assignment
type BatchProcessor ¶
type BatchProcessor struct {
// contains filtered or unexported fields
}
BatchProcessor processes query results in batches
func NewBatchProcessor ¶
func NewBatchProcessor(batchSize int, processor func([]*storage.Node) error) *BatchProcessor
NewBatchProcessor creates a batch processor
func (*BatchProcessor) Process ¶
func (bp *BatchProcessor) Process(stream *ResultStream) error
Process processes a result stream in batches
type BinaryExpression ¶
type BinaryExpression struct {
Left Expression
Operator string
Right Expression
}
BinaryExpression represents binary operations (AND, OR, =, <, >, etc.)
type BindingSet ¶
type BindingSet struct {
// contains filtered or unexported fields
}
BindingSet represents a set of variable bindings
type CallClause ¶
type CallClause struct {
ProcedureName string
Arguments []Expression
YieldItems []string // Variables to bind from result
}
CallClause represents a procedure call (e.g. CALL algo.shortestPath(...))
type CallOperator ¶
type CallOperator struct {
Input PhysicalOperator
ProcedureName string
Arguments []Expression
YieldItems []string // Variables to bind from result
// contains filtered or unexported fields
}
CallOperator executes a procedure call (e.g., algorithm). Procedure dispatch goes through procedureRegistry (pkg/query/procedures.go). C3.1 lands the operator + skeleton registry; C6 registers actual procedures once Decision 6 (S1↔algorithms storage-type wiring) is resolved.
func (*CallOperator) Close ¶
func (o *CallOperator) Close(ctx *ExecutionContext) error
func (*CallOperator) Next ¶
func (o *CallOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*CallOperator) Open ¶
func (o *CallOperator) Open(ctx *ExecutionContext) error
type CaseExpression ¶
type CaseExpression struct {
Operand Expression // non-nil for simple CASE, nil for searched CASE
WhenClauses []CaseWhen
ElseResult Expression // nil if no ELSE
}
CaseExpression represents a CASE expression (both searched and simple forms)
type CaseWhen ¶
type CaseWhen struct {
Condition Expression // bool condition (searched) or comparison value (simple)
Result Expression
}
CaseWhen represents a single WHEN/THEN branch
type CreateClause ¶
type CreateClause struct {
Patterns []*Pattern
}
CreateClause represents node/relationship creation
type CreateOperator ¶
type CreateOperator struct {
Input PhysicalOperator
Patterns []*Pattern
// contains filtered or unexported fields
}
CreateOperator handles node and relationship creation.
func (*CreateOperator) Close ¶
func (o *CreateOperator) Close(ctx *ExecutionContext) error
func (*CreateOperator) Next ¶
func (o *CreateOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*CreateOperator) Open ¶
func (o *CreateOperator) Open(ctx *ExecutionContext) error
type CreateStep ¶
type CreateStep struct {
// contains filtered or unexported fields
}
CreateStep executes a CREATE clause
func (*CreateStep) Execute ¶
func (cs *CreateStep) Execute(ctx *ExecutionContext) error
func (*CreateStep) StepDetail ¶
func (cs *CreateStep) StepDetail() string
func (*CreateStep) StepName ¶
func (cs *CreateStep) StepName() string
type DeleteClause ¶
type DeleteClause struct {
Variables []string
Detach bool // DETACH DELETE removes relationships too
}
DeleteClause represents deletion
type DeleteOperator ¶
type DeleteOperator struct {
Input PhysicalOperator
Variables []string
Detach bool
}
DeleteOperator handles node and edge deletion.
func (*DeleteOperator) Close ¶
func (o *DeleteOperator) Close(ctx *ExecutionContext) error
func (*DeleteOperator) Next ¶
func (o *DeleteOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*DeleteOperator) Open ¶
func (o *DeleteOperator) Open(ctx *ExecutionContext) error
type DeleteStep ¶
type DeleteStep struct {
// contains filtered or unexported fields
}
DeleteStep executes a DELETE clause
func (*DeleteStep) Execute ¶
func (ds *DeleteStep) Execute(ctx *ExecutionContext) error
Execute collects every node and edge the rows bind before deleting any of them. One entity can appear in many rows, and a node delete cascades to its edges, so deleting row by row either deletes twice or deletes an edge its node already took with it; both surface as a spurious "not found" after the delete has happened. Edges go first for the same reason.
func (*DeleteStep) StepDetail ¶
func (ds *DeleteStep) StepDetail() string
func (*DeleteStep) StepName ¶
func (ds *DeleteStep) StepName() string
type ExecutionContext ¶
type ExecutionContext struct {
// contains filtered or unexported fields
}
ExecutionContext holds execution state.
Audit A6c-query (2026-05-08): tenantID is read once from the request context at construction time and snapshotted here. Subsequent step executions read ec.tenantID directly rather than parsing the context per call. Step authors must use the *ForTenant graph methods with this tenantID — pre-fix, every executor step called tenant-blind storage methods regardless of the JWT-derived tenant on r.Context().
func (*ExecutionContext) CheckCancellation ¶
func (ec *ExecutionContext) CheckCancellation() error
CheckCancellation returns an error if the context is cancelled
func (*ExecutionContext) IsCancelled ¶
func (ec *ExecutionContext) IsCancelled() bool
IsCancelled checks if the execution context has been cancelled
type ExecutionPlan ¶
type ExecutionPlan struct {
Steps []ExecutionStep
}
ExecutionPlan represents a query execution plan
type ExecutionStep ¶
type ExecutionStep interface {
Execute(ctx *ExecutionContext) error
}
ExecutionStep represents a single step in execution
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor executes parsed queries against a graph
func NewExecutor ¶
func NewExecutor(graph *storage.GraphStorage) *Executor
NewExecutor creates a new query executor
func NewExecutorWithTimeout ¶
func NewExecutorWithTimeout(graph *storage.GraphStorage, timeout time.Duration) *Executor
NewExecutorWithTimeout creates a new query executor with custom timeout
func (*Executor) Execute ¶
Execute executes a query and returns results. Includes panic recovery to prevent server crashes from malformed queries. Uses the default query timeout.
func (*Executor) ExecuteWithContext ¶
ExecuteWithContext executes a query with context for cancellation and timeout support. Includes panic recovery to prevent server crashes from malformed queries.
It is ExecuteWithOptions with the zero PathOptions, which is today's traversal behaviour. Callers that want the node-visited mode or an expansion-time filter call ExecuteWithOptions directly.
func (*Executor) ExecuteWithOptions ¶ added in v1.4.0
func (e *Executor) ExecuteWithOptions(ctx context.Context, query *Query, opts PathOptions) (result *ResultSet, err error)
ExecuteWithOptions executes a query with per-call variable-length traversal policy. See PathOptions.
The policy is a parameter rather than Executor state because pkg/api shares one Executor across every request: a field there would change every tenant's rows and would race with a query already running.
NOTE: ExecuteWithText does not pass through here. It reads and fills the plan cache and calls executePlan directly, so it always runs the zero PathOptions. A caller that wants the options parses first and calls this, giving up the plan cache.
func (*Executor) ExecuteWithParams ¶
ExecuteWithParams executes a parameterized query. Parameters are provided as a map and injected into the query before execution. ParameterRef values in property maps are resolved to actual values, and parameters are made available in bindings as "$name" keys.
func (*Executor) ExecuteWithParamsContext ¶ added in v0.5.0
func (e *Executor) ExecuteWithParamsContext(ctx context.Context, query *Query, params map[string]any) (*ResultSet, error)
ExecuteWithParamsContext is ExecuteWithParams that honours a caller-supplied context (timeout / cancellation). The HTTP query handler uses this so that parameterized queries get both parameter substitution AND the request timeout — calling ExecuteWithContext directly drops req.Parameters and stores the literal "&{name}" instead of the value (#237).
func (*Executor) ExecuteWithText ¶
ExecuteWithText executes a query from text and uses query caching
func (*Executor) SetQueryTimeout ¶
SetQueryTimeout sets the query timeout
func (*Executor) SetSearchIndex ¶
func (e *Executor) SetSearchIndex(idx *search.FullTextIndex)
SetSearchIndex configures full-text search for use in queries. Registers the search() function that captures the index via closure.
func (*Executor) SetVectorSearch ¶
func (e *Executor) SetVectorSearch( similarityFn VectorSimilarityFunc, searchFn VectorSearchFunc, hasIndexFn HasVectorIndexFunc, getNodeFn GetNodeFunc, )
SetVectorSearch wires up vector similarity and HNSW search for use in queries. Follows the same closure pattern as SetSearchIndex for full-text search.
type ExpandFilter ¶ added in v1.4.0
ExpandFilter reports whether the traversal may enter To.
A false return prunes the candidate: To is not bound, is not queued, and is never expanded, so To's own neighbours are never read from storage. To itself IS read once, because the filter receives the loaded node.
The filter runs once per examined edge, and a rejection is not remembered: the filter may read Depth and Edge, so "rejected here" does not mean "rejected everywhere", and marking a rejected node visited would be wrong.
Two limits on where it runs, both deliberate:
It reaches variable-length patterns only. A single-hop pattern takes the fixed path and is never offered to the filter — including [:T*1..1], which carries star syntax but is one hop. A single hop has no subtree to prune, so a filter there would only repeat a WHERE clause.
At the engine depth cap the traversal consults the filter about a candidate it will NOT enter, to decide whether the answer is incomplete. A candidate the filter rejects costs the caller nothing, so it must not raise ErrTraversalTruncated. A filter that records what it is offered sees these calls.
It runs on the query goroutine, under the query timeout, holding no storage lock. A slow filter is indistinguishable from a slow query. A panic inside it is recovered by ExecuteWithOptions and returned as a query error.
This shape diverges from TraversalOptions.Predicate and EdgePredicate (traversal_types.go) on purpose. Those are two functions for one decision, neither carries depth, and the node predicate cannot see the edge that brought it. Copying them here would lock in those limits.
type ExpandOperator ¶
type ExpandOperator struct {
Input PhysicalOperator
SourceVar string
TargetVar string
EdgeVar string
EdgeType string
Direction Direction // Use local query.Direction
// contains filtered or unexported fields
}
ExpandOperator expands from a source node along edges of a specific type.
func (*ExpandOperator) Close ¶
func (o *ExpandOperator) Close(ctx *ExecutionContext) error
func (*ExpandOperator) Next ¶
func (o *ExpandOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*ExpandOperator) Open ¶
func (o *ExpandOperator) Open(ctx *ExecutionContext) error
type Expansion ¶ added in v1.4.0
type Expansion struct {
From *storage.Node // the frontier node being expanded
Edge *storage.Edge // the edge under consideration
To *storage.Node // the candidate node at the far end
Depth int // the depth To would occupy (From's depth plus one)
}
Expansion describes one candidate step, offered to an ExpandFilter before the traversal enters it.
It is a struct rather than a parameter list so that a later field is a compatible change. It carries all four values on purpose: To is the decision subject, Edge lets a rule depend on how the node was reached (which the pattern cannot express, because getEdges filters on one type only), From lets a rule compare the two ends, and Depth lets a rule tighten with distance without lowering MaxHops globally.
type Expression ¶
type Expression interface {
Eval(context map[string]any) (bool, error)
EvalValue(context map[string]any) (any, error)
}
Expression is an interface for all expression types. EvalValue returns the raw evaluation result (used for projection, SET RHS, CALL args); Eval coerces to bool (used for WHERE / AND / OR / comparison). All concrete implementations satisfy both — the dual-eval pattern.
type FilterOperator ¶
type FilterOperator struct {
Input PhysicalOperator
Expression Expression // Use existing Expression interface if available
}
FilterOperator filters rows based on a predicate.
func (*FilterOperator) Close ¶
func (o *FilterOperator) Close(ctx *ExecutionContext) error
func (*FilterOperator) Next ¶
func (o *FilterOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*FilterOperator) Open ¶
func (o *FilterOperator) Open(ctx *ExecutionContext) error
type FilterStep ¶
type FilterStep struct {
// contains filtered or unexported fields
}
FilterStep executes a WHERE clause
func (*FilterStep) Execute ¶
func (fs *FilterStep) Execute(ctx *ExecutionContext) error
func (*FilterStep) StepDetail ¶
func (fs *FilterStep) StepDetail() string
func (*FilterStep) StepName ¶
func (fs *FilterStep) StepName() string
type FunctionCallExpression ¶
type FunctionCallExpression struct {
Name string
Args []Expression
}
FunctionCallExpression represents a function call (e.g., toLower(n.name))
type GetNodeFunc ¶
GetNodeFunc fetches a node by ID (avoids importing storage in step types).
type HasVectorIndexFunc ¶
HasVectorIndexFunc checks whether a vector index exists for a property.
type HashJoinOperator ¶
type HashJoinOperator struct {
Left PhysicalOperator
Right PhysicalOperator
Var string // The common variable to join on
// contains filtered or unexported fields
}
HashJoinOperator performs an efficient equijoin using an in-memory hash table. Build phase: buffers Right input into a hash map. Probe phase: streams Left input and probes the map.
func (*HashJoinOperator) Close ¶
func (o *HashJoinOperator) Close(ctx *ExecutionContext) error
func (*HashJoinOperator) Next ¶
func (o *HashJoinOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*HashJoinOperator) Open ¶
func (o *HashJoinOperator) Open(ctx *ExecutionContext) error
type IndexLookupStep ¶
type IndexLookupStep struct {
// contains filtered or unexported fields
}
IndexLookupStep uses a property index for efficient node lookup This replaces a full scan when the optimizer detects an indexable equality condition
func (*IndexLookupStep) Execute ¶
func (ils *IndexLookupStep) Execute(ctx *ExecutionContext) error
func (*IndexLookupStep) StepDetail ¶
func (ils *IndexLookupStep) StepDetail() string
func (*IndexLookupStep) StepName ¶
func (ils *IndexLookupStep) StepName() string
type IndexSeekOperator ¶
type IndexSeekOperator struct {
Variable string
PropertyKey string
Value storage.Value
// contains filtered or unexported fields
}
IndexSeekOperator uses a property index to find nodes.
func (*IndexSeekOperator) Close ¶
func (o *IndexSeekOperator) Close(ctx *ExecutionContext) error
func (*IndexSeekOperator) Next ¶
func (o *IndexSeekOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*IndexSeekOperator) Open ¶
func (o *IndexSeekOperator) Open(ctx *ExecutionContext) error
type Lexer ¶
type Lexer struct {
// contains filtered or unexported fields
}
Lexer tokenizes a query string
type LiteralExpression ¶
type LiteralExpression struct {
Value any
}
LiteralExpression represents a literal value
type MatchClause ¶
type MatchClause struct {
Patterns []*Pattern
}
MatchClause represents a MATCH pattern
type MatchStep ¶
type MatchStep struct {
// contains filtered or unexported fields
}
MatchStep executes a MATCH clause
func (*MatchStep) Execute ¶
func (ms *MatchStep) Execute(ctx *ExecutionContext) error
func (*MatchStep) StepDetail ¶
type MergeClause ¶
MergeClause represents a MERGE operation (match-or-create)
type MergeOperator ¶
type MergeOperator struct {
Input PhysicalOperator
Pattern *Pattern
OnMatch *SetClause
OnCreate *SetClause
}
MergeOperator handles match-or-create logic.
func (*MergeOperator) Close ¶
func (o *MergeOperator) Close(ctx *ExecutionContext) error
func (*MergeOperator) Next ¶
func (o *MergeOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*MergeOperator) Open ¶
func (o *MergeOperator) Open(ctx *ExecutionContext) error
type MergeStep ¶
type MergeStep struct {
// contains filtered or unexported fields
}
MergeStep executes a MERGE clause (match-or-create)
func (*MergeStep) Execute ¶
func (ms *MergeStep) Execute(ctx *ExecutionContext) error
Execute decides match-or-create for each row on its own, from that row's bindings, in row order, so a later row sees what an earlier row created.
A pattern that uses none of the row's variables gets the same answer for every row: the first row matches or creates, and every later row matches that result. Deciding it once keeps the openCypher outcome (ON CREATE for the first row, ON MATCH after) without a full scan for every row.
func (*MergeStep) StepDetail ¶
type NestedLoopJoinOperator ¶
type NestedLoopJoinOperator struct {
Left PhysicalOperator
Right PhysicalOperator
// contains filtered or unexported fields
}
NestedLoopJoinOperator performs a nested loop join (Cartesian product) of two input streams. It buffers the Right input in memory.
func (*NestedLoopJoinOperator) Close ¶
func (o *NestedLoopJoinOperator) Close(ctx *ExecutionContext) error
func (*NestedLoopJoinOperator) Next ¶
func (o *NestedLoopJoinOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*NestedLoopJoinOperator) Open ¶
func (o *NestedLoopJoinOperator) Open(ctx *ExecutionContext) error
type NodePattern ¶
NodePattern represents a node in a pattern
type NodeScanOperator ¶
type NodeScanOperator struct {
Variable string
Label string
// contains filtered or unexported fields
}
NodeScanOperator scans all nodes with a given label (or all nodes if label is empty).
func (*NodeScanOperator) Close ¶
func (o *NodeScanOperator) Close(ctx *ExecutionContext) error
func (*NodeScanOperator) Next ¶
func (o *NodeScanOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*NodeScanOperator) Open ¶
func (o *NodeScanOperator) Open(ctx *ExecutionContext) error
type Notice ¶ added in v1.7.0
Notice is a non-fatal message about how a query ran. Code is a stable identifier a caller can match on; Message is for people and may change.
type OptimizationHint ¶
type OptimizationHint struct {
Type string // "index_available", "filter_early", "join_reorder"
Description string
EstimatedGain float64 // Estimated speedup multiplier
}
OptimizationHint provides hints about potential optimizations
type Optimizer ¶
type Optimizer struct {
// contains filtered or unexported fields
}
Optimizer optimizes query execution plans
func NewOptimizer ¶
func NewOptimizer(graph *storage.GraphStorage) *Optimizer
NewOptimizer creates a new query optimizer
func (*Optimizer) AnalyzeQuery ¶
func (o *Optimizer) AnalyzeQuery(query *Query) []OptimizationHint
AnalyzeQuery analyzes a query and suggests optimizations
func (*Optimizer) EstimateCost ¶
func (o *Optimizer) EstimateCost(pattern *MatchClause) float64
EstimateCost estimates the cost of executing a match pattern
func (*Optimizer) Optimize ¶
func (o *Optimizer) Optimize(plan *ExecutionPlan, query *Query) *ExecutionPlan
Optimize optimizes an execution plan
type OptionalMatchClause ¶
type OptionalMatchClause struct {
Patterns []*Pattern
Where *WhereClause // WHERE scoped to this optional match
}
OptionalMatchClause represents an OPTIONAL MATCH pattern with left-outer-join semantics
type OptionalMatchOperator ¶
type OptionalMatchOperator struct {
Input PhysicalOperator
Pattern *Pattern
// contains filtered or unexported fields
}
OptionalMatchOperator implements left-outer-join semantics.
func (*OptionalMatchOperator) Close ¶
func (o *OptionalMatchOperator) Close(ctx *ExecutionContext) error
func (*OptionalMatchOperator) Next ¶
func (o *OptionalMatchOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*OptionalMatchOperator) Open ¶
func (o *OptionalMatchOperator) Open(ctx *ExecutionContext) error
type OptionalMatchStep ¶
type OptionalMatchStep struct {
// contains filtered or unexported fields
}
OptionalMatchStep executes an OPTIONAL MATCH clause with left-outer-join semantics. When no match is found, variables from the pattern are set to nil (null propagation).
func (*OptionalMatchStep) Execute ¶
func (oms *OptionalMatchStep) Execute(ctx *ExecutionContext) error
func (*OptionalMatchStep) StepDetail ¶
func (oms *OptionalMatchStep) StepDetail() string
func (*OptionalMatchStep) StepName ¶
func (oms *OptionalMatchStep) StepName() string
type OrderByItem ¶
type OrderByItem struct {
Expression *PropertyExpression
ValueExpr Expression // broader expression (takes precedence when non-nil)
Ascending bool
}
OrderByItem represents ordering specification
type ParallelAggregation ¶
type ParallelAggregation struct {
// contains filtered or unexported fields
}
ParallelAggregation performs parallel aggregation operations
func NewParallelAggregation ¶
func NewParallelAggregation(graph *storage.GraphStorage) *ParallelAggregation
NewParallelAggregation creates a parallel aggregation engine
func (*ParallelAggregation) AggregateProperty ¶
func (pa *ParallelAggregation) AggregateProperty( ctx context.Context, propertyKey string, aggregateFunc func(values []any) any, ) (any, error)
AggregateProperty performs parallel property aggregation
Concurrent Safety: 1. Divides node ID range among workers for parallel scanning 2. Each worker builds independent value slice (no shared state) 3. Workers send value slices to buffered channel (size = numWorkers) 4. Main goroutine aggregates after all workers complete
Concurrent Edge Cases: 1. Workers may encounter deleted nodes - silently skipped (continue on error) 2. Workers may encounter nodes without the property - only existing values collected 3. No synchronization needed between workers - non-overlapping ID ranges 4. Final aggregation happens sequentially after parallel collection
func (*ParallelAggregation) CountNodesByLabel ¶
CountNodesByLabel counts nodes with a label in parallel
Concurrent Safety: 1. Divides node ID range among workers for parallel scanning 2. Each worker has independent count accumulator (no shared state) 3. Workers send results to buffered channel (size = numWorkers) 4. Main goroutine waits via WaitGroup before closing channels
Concurrent Edge Cases: 1. Workers may encounter deleted nodes - silently skipped (continue on error) 2. No synchronization needed between workers - non-overlapping ID ranges 3. Channel buffer prevents workers from blocking on result send
type ParallelPathFinder ¶
type ParallelPathFinder struct {
// contains filtered or unexported fields
}
ParallelPathFinder finds paths in parallel
func NewParallelPathFinder ¶
func NewParallelPathFinder(graph *storage.GraphStorage) *ParallelPathFinder
NewParallelPathFinder creates a parallel path finder
func (*ParallelPathFinder) FindAllPaths ¶
func (ppf *ParallelPathFinder) FindAllPaths( ctx context.Context, pairs [][2]uint64, maxDepth int, ) ([][]uint64, error)
FindAllPaths finds all paths between multiple pairs of nodes in parallel
Concurrent Safety: 1. Each pair is processed by independent goroutine 2. Semaphore limits concurrent path searches to NumCPU() 3. Each path search maintains independent visited map (no shared state) 4. Results collected via buffered channel after all workers complete
Concurrent Edge Cases: 1. Semaphore prevents goroutine explosion when processing many pairs 2. Path search may fail (no path found) - returns nil, continues processing others 3. Goroutines may complete in any order - results order not preserved 4. All goroutines complete before returning (WaitGroup ensures this)
type ParallelPipeline ¶
type ParallelPipeline struct {
// contains filtered or unexported fields
}
ParallelPipeline executes pipeline stages in parallel
func NewParallelPipeline ¶
func NewParallelPipeline(workers int) *ParallelPipeline
NewParallelPipeline creates a parallel pipeline
func (*ParallelPipeline) AddStage ¶
func (pp *ParallelPipeline) AddStage(stage PipelineStage) *ParallelPipeline
AddStage adds a stage to the pipeline
func (*ParallelPipeline) Execute ¶
func (pp *ParallelPipeline) Execute(input *ResultStream) *ResultStream
Execute executes the pipeline with parallel workers
type ParallelTraversal ¶
type ParallelTraversal struct {
// contains filtered or unexported fields
}
ParallelTraversal performs parallel BFS traversal
func NewParallelTraversal ¶
func NewParallelTraversal(graph *storage.GraphStorage, startIDs []uint64, maxDepth int) *ParallelTraversal
NewParallelTraversal creates a parallel traversal query
func (*ParallelTraversal) Execute ¶
Execute performs parallel traversal from multiple starting nodes
Concurrent Safety: 1. Uses sync.Map for thread-safe visited tracking across workers 2. Multiple goroutines traverse different branches simultaneously 3. Results channel has buffer to reduce blocking 4. Workers coordinate via WaitGroup for proper shutdown 5. Error channel uses select/default to prevent blocking on error reporting 6. Context is propagated to all spawned goroutines for cancellation
Concurrent Edge Cases: 1. Multiple workers may discover same node - sync.Map.LoadOrStore handles this 2. Result channel may fill up - select/default prevents goroutine leaks 3. One worker error doesn't stop others - they continue until WaitGroup completes 4. Channel close is synchronized with WaitGroup to prevent send-on-closed-channel 5. Context cancellation propagates to all child goroutines spawned by traverseFrom
type ParameterExpression ¶
type ParameterExpression struct {
Name string // "name" from $name
}
ParameterExpression represents a query parameter reference ($name) in expressions
type ParameterRef ¶
type ParameterRef struct {
Name string // "name" from $name
}
ParameterRef represents a parameter reference in property maps ({name: $name})
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser builds an AST from tokens
type PathOptions ¶ added in v1.4.0
type PathOptions struct {
Semantics PathSemantics
Expand ExpandFilter
}
PathOptions carries per-call traversal policy for variable-length patterns.
The zero value is today's behaviour exactly: AllSimplePaths with no filter. The two fields are orthogonal — Expand applies under both semantics, and Semantics works with a nil filter.
The options are per call rather than per Executor because pkg/api shares one Executor across every request, so a process-wide switch would change every tenant's rows. They are not on *Query either: that struct is what the parser produces, and a Go closure is not syntax.
type PathSemantics ¶ added in v1.4.0
type PathSemantics int
PathSemantics selects how a variable-length pattern segment enumerates.
The zero value is today's behaviour. That is deliberate and load-bearing: PathOptions{} must mean "unchanged" on every execution path, so a caller who does not opt in keeps its rows by construction rather than by a conditional somewhere in the traversal.
const ( // AllSimplePaths is the zero value: every distinct simple path within // [MinHops, MaxHops] produces a binding. A node reachable by twenty routes // produces twenty rows, and the traversal expands it twenty times. AllSimplePaths PathSemantics = iota // DistinctNodes admits each node at most once, so a node reachable by // twenty routes produces one row. Cost grows with the number of nodes and // edges in the reachable subgraph rather than with the number of routes // through it, which is the difference between O(N+E) and O(b^d). // // The relationship variable is bound to the BFS discovery path. A // breadth-first traversal that admits each node once admits it at its // minimum depth, so that path is A shortest path in edge count. It is not // THE shortest path: when several paths tie on length the winner is decided // by storage adjacency order, which pkg/storage does not specify. Do not // depend on which one comes back. // // "Once" is scoped to one start node, not to one query. matchPath calls the // traversal once per start node, so MATCH (a:Root)-[:LINK*]->(b:Sink) with // three :Root nodes can return b three times, once per a. Each row is a // distinct (a, b) binding, so that is the correct reading — a query-wide // set would silently merge rows across different a bindings. // // MinHops of 2 or more is refused in this mode, before the query reads any // data. See ErrDistinctNodesMinHops. DistinctNodes )
type Pattern ¶
type Pattern struct {
Nodes []*NodePattern
Relationships []*RelationshipPattern
}
Pattern represents a graph pattern to match
type PhysicalOperator ¶
type PhysicalOperator interface {
// Open initializes the operator and its children.
Open(ctx *ExecutionContext) error
// Next returns the next row (BindingSet) from the operator.
// Returns (nil, nil) when the result set is exhausted.
Next(ctx *ExecutionContext) (*BindingSet, error)
// Close releases any resources held by the operator.
Close(ctx *ExecutionContext) error
}
PhysicalOperator is the interface for physical query operators (Volcano model).
type PipelineStage ¶
PipelineStage represents a stage in a query pipeline
type Planner ¶
type Planner struct {
// contains filtered or unexported fields
}
Planner translates a Query AST into a tree of PhysicalOperators.
func NewPlanner ¶
NewPlanner creates a new query planner.
func (*Planner) PlanSub ¶
func (p *Planner) PlanSub(ctx context.Context, q *Query, input PhysicalOperator) (PhysicalOperator, error)
PlanSub creates an execution plan, potentially with an existing input source.
type Procedure ¶
type Procedure func(ctx context.Context, graph storage.Storage, tenantID string, args []any) ([]map[string]any, error)
Procedure is the function signature for a Cypher procedure callable via `CALL procedure_name(args) YIELD items`. The storage.Storage interface argument is intentionally the S1-narrowed type; algorithms exposed as procedures take the interface (per Decision 6 = B).
type ProjectOperator ¶
type ProjectOperator struct {
Input PhysicalOperator
Items []*ReturnItem
}
ProjectOperator transforms rows into the final result format.
func (*ProjectOperator) Close ¶
func (o *ProjectOperator) Close(ctx *ExecutionContext) error
func (*ProjectOperator) Next ¶
func (o *ProjectOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*ProjectOperator) Open ¶
func (o *ProjectOperator) Open(ctx *ExecutionContext) error
type PropertyExpression ¶
PropertyExpression represents property access (e.g., n.name)
type Query ¶
type Query struct {
Match *MatchClause
Where *WhereClause
Return *ReturnClause
Create *CreateClause
Delete *DeleteClause
Set *SetClause
Remove *RemoveClause
Unwind *UnwindClause
Merges []*MergeClause // in text order; each runs on the rows the one before it left
With *WithClause
OptionalMatches []*OptionalMatchClause
Union *UnionClause
UnionNext *Query // For UNION chaining
Next *Query // For WITH chaining
Call *CallClause
Limit int
Skip int
Explain bool
Profile bool
// InitialBindings are injected by WITH clause chaining
InitialBindings []*BindingSet
}
Query represents a complete query statement
type QueryCache ¶
type QueryCache struct {
// contains filtered or unexported fields
}
QueryCache caches compiled/optimized queries
func (*QueryCache) Get ¶
func (qc *QueryCache) Get(queryText string) (*ExecutionPlan, bool)
Get retrieves a cached plan
func (*QueryCache) GetTopQueries ¶
func (qc *QueryCache) GetTopQueries(limit int) []*QueryStatistics
GetTopQueries returns most frequently executed queries
func (*QueryCache) Put ¶
func (qc *QueryCache) Put(queryText string, plan *ExecutionPlan)
Put stores a plan in cache
func (*QueryCache) RecordExecution ¶
func (qc *QueryCache) RecordExecution(queryText string, executionTimeMicros int64, optimized bool)
RecordExecution records query execution statistics
type QueryFunc ¶
QueryFunc is a function callable from within a query
func GetFunction ¶
GetFunction retrieves a registered function by name (case-insensitive)
type QueryPipeline ¶
type QueryPipeline struct {
// contains filtered or unexported fields
}
QueryPipeline chains multiple processing stages
func NewQueryPipeline ¶
func NewQueryPipeline() *QueryPipeline
NewQueryPipeline creates a new query pipeline
func (*QueryPipeline) AddStage ¶
func (qp *QueryPipeline) AddStage(stage PipelineStage) *QueryPipeline
AddStage adds a processing stage
func (*QueryPipeline) Execute ¶
func (qp *QueryPipeline) Execute(input *ResultStream) *ResultStream
Execute executes the pipeline on a stream
func (*QueryPipeline) Filter ¶
func (qp *QueryPipeline) Filter(predicate func(*storage.Node) bool) *QueryPipeline
Filter adds a filter stage
func (*QueryPipeline) Map ¶
func (qp *QueryPipeline) Map(transform func(*storage.Node) *storage.Node) *QueryPipeline
Map adds a transformation stage
type QueryStatistics ¶
type QueryStatistics struct {
QueryText string
ExecutionCount int
TotalExecutionTime int64 // microseconds
AvgExecutionTime int64
LastOptimized bool
}
QueryStatistics tracks query execution statistics
type RelationshipPattern ¶
type RelationshipPattern struct {
Variable string
Type string
Direction Direction
Properties map[string]any
From *NodePattern
To *NodePattern
MinHops int // For variable-length paths
MaxHops int
}
RelationshipPattern represents a relationship in a pattern
type RemoveClause ¶
type RemoveClause struct {
Items []*RemoveItem
}
RemoveClause represents property or label removal
type RemoveItem ¶
RemoveItem represents a single property or label to remove
type RemoveOperator ¶
type RemoveOperator struct {
Input PhysicalOperator
Items []*RemoveItem
}
RemoveOperator handles property removal.
func (*RemoveOperator) Close ¶
func (o *RemoveOperator) Close(ctx *ExecutionContext) error
func (*RemoveOperator) Next ¶
func (o *RemoveOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*RemoveOperator) Open ¶
func (o *RemoveOperator) Open(ctx *ExecutionContext) error
type RemoveStep ¶
type RemoveStep struct {
// contains filtered or unexported fields
}
RemoveStep executes a REMOVE clause — removes properties from nodes and edges
func (*RemoveStep) Execute ¶
func (rs *RemoveStep) Execute(ctx *ExecutionContext) error
func (*RemoveStep) StepDetail ¶
func (rs *RemoveStep) StepDetail() string
func (*RemoveStep) StepName ¶
func (rs *RemoveStep) StepName() string
type ResultSet ¶
type ResultSet struct {
Columns []string
Rows []map[string]any
Count int
Profile []StepProfile // Populated when PROFILE is used
// Notices are non-fatal messages about how the query ran, such as a
// deprecated form it used. The query still succeeded; REST /query maps a
// deprecation notice's Code to a response header.
Notices []Notice
}
ResultSet represents query results
type ResultStream ¶
type ResultStream struct {
// contains filtered or unexported fields
}
ResultStream provides streaming query results
func NewResultStream ¶
func NewResultStream(bufferSize int) *ResultStream
NewResultStream creates a new result stream. Enforces a minimum buffer size to prevent deadlocks with unbuffered channels.
func (*ResultStream) Next ¶
func (rs *ResultStream) Next() (*storage.Node, error)
Next returns the next result or error
func (*ResultStream) Send ¶
func (rs *ResultStream) Send(node *storage.Node) bool
Send sends a result to the stream
func (*ResultStream) SendError ¶
func (rs *ResultStream) SendError(err error)
SendError sends an error and closes the stream
type ReturnClause ¶
type ReturnClause struct {
Items []*ReturnItem
Distinct bool
OrderBy []*OrderByItem
GroupBy []*PropertyExpression
Ascending bool
}
ReturnClause represents what to return
type ReturnItem ¶
type ReturnItem struct {
Expression *PropertyExpression
ValueExpr Expression // Broader type for function calls; if non-nil, takes precedence
Alias string
Aggregate string // COUNT, SUM, AVG, MIN, MAX, COLLECT
}
ReturnItem represents a single return item
type ReturnStep ¶
type ReturnStep struct {
// contains filtered or unexported fields
}
ReturnStep executes a RETURN clause
func (*ReturnStep) Execute ¶
func (rs *ReturnStep) Execute(ctx *ExecutionContext) error
func (*ReturnStep) StepDetail ¶
func (rs *ReturnStep) StepDetail() string
func (*ReturnStep) StepName ¶
func (rs *ReturnStep) StepName() string
type SetClause ¶
type SetClause struct {
Assignments []*Assignment
}
SetClause represents property updates
type SetOperator ¶
type SetOperator struct {
Input PhysicalOperator
Assignments []*Assignment
}
SetOperator handles property updates.
func (*SetOperator) Close ¶
func (o *SetOperator) Close(ctx *ExecutionContext) error
func (*SetOperator) Next ¶
func (o *SetOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*SetOperator) Open ¶
func (o *SetOperator) Open(ctx *ExecutionContext) error
type SetStep ¶
type SetStep struct {
// contains filtered or unexported fields
}
SetStep executes a SET clause
func (*SetStep) Execute ¶
func (ss *SetStep) Execute(ctx *ExecutionContext) error
func (*SetStep) StepDetail ¶
type StepDescriber ¶
StepDescriber provides human-readable descriptions of execution steps
type StepProfile ¶
StepProfile holds profiling data for a single execution step
type StreamingQuery ¶
type StreamingQuery struct {
// contains filtered or unexported fields
}
StreamingQuery executes queries with streaming results
func NewStreamingQuery ¶
func NewStreamingQuery(graph *storage.GraphStorage) *StreamingQuery
NewStreamingQuery creates a streaming query executor
func (*StreamingQuery) StreamNodes ¶
func (sq *StreamingQuery) StreamNodes( filter func(*storage.Node) bool, ) *ResultStream
StreamNodes streams all nodes matching a filter
func (*StreamingQuery) StreamTraversal ¶
func (sq *StreamingQuery) StreamTraversal( startID uint64, maxDepth int, ) *ResultStream
StreamTraversal streams nodes discovered during traversal
type Task ¶
type Task interface {
Execute(graph *storage.GraphStorage) (any, error)
ID() string
}
Task represents a unit of work
type TaskResult ¶
type TaskResult struct {
TaskID string
Result any
Error error
TimedOut bool // True if task was cancelled due to timeout
Duration time.Duration // How long the task took
}
TaskResult contains the result of a task execution
type TimeoutConfig ¶
type TimeoutConfig struct {
Min time.Duration // Minimum allowed timeout (0 means no minimum)
Max time.Duration // Maximum allowed timeout (0 means no maximum)
Default time.Duration // Default timeout when value is invalid
}
TimeoutConfig defines the bounds for timeout validation.
func DefaultQueryTimeoutConfig ¶
func DefaultQueryTimeoutConfig() TimeoutConfig
DefaultQueryTimeoutConfig returns the standard config for query timeouts.
func DefaultTaskTimeoutConfig ¶
func DefaultTaskTimeoutConfig() TimeoutConfig
DefaultTaskTimeoutConfig returns the standard config for task timeouts.
type TokenType ¶
type TokenType int
TokenType represents the type of a token
const ( // Special tokens TokenEOF TokenType = iota TokenError // Keywords TokenMatch TokenWhere TokenReturn TokenCreate TokenDelete TokenDetach TokenSet TokenWith TokenLimit TokenSkip TokenOrder TokenOrderBy // BY keyword TokenAsc TokenDesc TokenDistinct TokenAs TokenAnd TokenOr TokenNot TokenGroup TokenBy TokenExplain TokenProfile TokenUnwind TokenMerge TokenOn TokenOptional TokenCase TokenWhen TokenThen TokenElse TokenEnd TokenUnion TokenAll TokenIs TokenIn TokenRemove TokenStarts TokenEnds TokenContains TokenCall TokenYield // Identifiers and literals TokenParameter // $name TokenIdentifier TokenString TokenNumber TokenTrue TokenFalse TokenNull // Operators TokenEquals // = TokenNotEquals // !=, <> TokenLessThan // < TokenGreaterThan // > TokenLessEquals // <= TokenGreaterEquals // >= TokenPlus // + TokenMinus // - TokenStar // * TokenSlash // / TokenPercent // % TokenDot // . TokenColon // : TokenComma // , TokenSemicolon // ; // Delimiters TokenLeftParen // ( TokenRightParen // ) TokenLeftBracket // [ TokenRightBracket // ] TokenLeftBrace // { TokenRightBrace // } // Relationship arrows TokenArrowLeft // <- TokenArrowRight // -> TokenArrowBoth // - )
type TraversalError ¶
TraversalError records an error encountered during traversal
func (TraversalError) Error ¶
func (te TraversalError) Error() string
type TraversalOptions ¶
type TraversalOptions struct {
StartNodeID uint64
Direction Direction
EdgeTypes []string // Filter by edge types (empty = all types)
MaxDepth int // Maximum traversal depth
// MaxResults bounds the nodes returned. LEAVE IT AT ZERO unless you
// intend to detect saturation yourself.
//
// Zero carries two meanings at once, and that is the trap. It means
// "apply DefaultMaxResults", and it also means "I did not choose this
// bound, so tell me if you hit it". BFS and DFS report ErrTraversalTruncated
// only for a bound the ENGINE chose, because a caller who names a limit and
// reaches it received exactly what was requested.
//
// So naming a bound BUYS SILENCE. The careful-looking move — set it
// explicitly rather than rely on a default — is the one that switches the
// signal off. Two independent designs made that move before this comment
// existed: GetNeighborhood in this package passed DefaultMaxResults by
// name and suppressed the signal for every one of its callers, and a
// downstream consumer wrote the same rule into its specification from the
// constants alone, without seeing GetNeighborhood. Neither was careless.
//
// If you genuinely need a bound for memory, name it AND check saturation
// yourself. The engine will not do it for you once you have named one.
MaxResults int // Maximum nodes to return
Predicate func(*storage.Node) bool // Node filter function
EdgePredicate func(*storage.Edge) bool // Edge filter function (for temporal/property filtering)
FailOnMissing bool // If true, return error on first missing node; if false, track and continue
}
TraversalOptions configures graph traversal
type TraversalResult ¶
type TraversalResult struct {
Nodes []*storage.Node
Paths []Path
SkippedIDs []uint64 // Node IDs that were skipped due to errors
Errors []TraversalError // Errors encountered during traversal
}
TraversalResult contains the results of a traversal
type Traverser ¶
type Traverser struct {
// contains filtered or unexported fields
}
Traverser performs graph traversals
func NewTraverser ¶
func NewTraverser(storage *storage.GraphStorage) *Traverser
NewTraverser creates a new traverser
func (*Traverser) BFS ¶
func (t *Traverser) BFS(opts TraversalOptions) (*TraversalResult, error)
BFS performs breadth-first search traversal
func (*Traverser) DFS ¶
func (t *Traverser) DFS(opts TraversalOptions) (*TraversalResult, error)
DFS performs depth-first search traversal
func (*Traverser) FindAllPaths ¶
func (t *Traverser) FindAllPaths(fromID, toID uint64, maxDepth int, edgeTypes []string) ([]Path, error)
FindAllPaths finds all paths between two nodes up to maxDepth
func (*Traverser) FindAllPathsWithPredicate ¶
func (t *Traverser) FindAllPathsWithPredicate(fromID, toID uint64, maxDepth int, edgeTypes []string, edgePredicate func(*storage.Edge) bool) ([]Path, error)
FindAllPathsWithPredicate finds all paths with optional edge filtering
func (*Traverser) FindShortestPath ¶
FindShortestPath finds the shortest path between two nodes (BFS-based)
type UnaryExpression ¶
type UnaryExpression struct {
Operator string // "NOT", "-"
Operand Expression
}
UnaryExpression represents unary operators: NOT, -
type UnionClause ¶
type UnionClause struct {
All bool // true = UNION ALL (keep duplicates), false = UNION (deduplicate)
}
UnionClause represents a UNION between query segments
type UnionOperator ¶
type UnionOperator struct {
Left PhysicalOperator
Right PhysicalOperator
All bool // If false, deduplicate
// contains filtered or unexported fields
}
UnionOperator combines results from two query segments.
func (*UnionOperator) Close ¶
func (o *UnionOperator) Close(ctx *ExecutionContext) error
func (*UnionOperator) Next ¶
func (o *UnionOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*UnionOperator) Open ¶
func (o *UnionOperator) Open(ctx *ExecutionContext) error
type UnwindClause ¶
type UnwindClause struct {
Expression *PropertyExpression
Alias string
}
UnwindClause represents an UNWIND operation
type UnwindOperator ¶
type UnwindOperator struct {
Input PhysicalOperator
Expression *PropertyExpression
Alias string
// contains filtered or unexported fields
}
UnwindOperator expands list values into individual rows.
func (*UnwindOperator) Close ¶
func (o *UnwindOperator) Close(ctx *ExecutionContext) error
func (*UnwindOperator) Next ¶
func (o *UnwindOperator) Next(ctx *ExecutionContext) (*BindingSet, error)
func (*UnwindOperator) Open ¶
func (o *UnwindOperator) Open(ctx *ExecutionContext) error
type UnwindStep ¶
type UnwindStep struct {
// contains filtered or unexported fields
}
UnwindStep executes an UNWIND clause - expands list values into individual bindings
func (*UnwindStep) Execute ¶
func (us *UnwindStep) Execute(ctx *ExecutionContext) error
func (*UnwindStep) StepDetail ¶
func (us *UnwindStep) StepDetail() string
func (*UnwindStep) StepName ¶
func (us *UnwindStep) StepName() string
type VectorSearchFunc ¶
type VectorSearchFunc func(propertyName string, query []float32, k, ef int) ([]VectorSearchResult, error)
VectorSearchFunc performs HNSW k-NN search on a named vector index.
type VectorSearchResult ¶
VectorSearchResult mirrors vector.SearchResult without importing pkg/vector.
type VectorSearchStep ¶
type VectorSearchStep struct {
// contains filtered or unexported fields
}
VectorSearchStep performs HNSW-accelerated pre-filtering. Inserted by the optimizer before MatchStep to pre-bind a variable to nodes whose embeddings are similar to a query vector.
func (*VectorSearchStep) Execute ¶
func (vs *VectorSearchStep) Execute(ctx *ExecutionContext) error
func (*VectorSearchStep) StepDetail ¶
func (vs *VectorSearchStep) StepDetail() string
func (*VectorSearchStep) StepName ¶
func (vs *VectorSearchStep) StepName() string
type VectorSimilarityFunc ¶
VectorSimilarityFunc computes similarity between two vectors. Returns a float64 score (e.g., cosine similarity in [-1, 1]).
type WhereClause ¶
type WhereClause struct {
Expression Expression
}
WhereClause represents filtering conditions
type WithClause ¶
type WithClause struct {
Items []*ReturnItem
Where *WhereClause
}
WithClause represents a WITH projection between query segments
type WorkerPool ¶
type WorkerPool struct {
// contains filtered or unexported fields
}
WorkerPool manages a pool of worker goroutines for parallel query execution
func NewWorkerPool ¶
func NewWorkerPool(workers int) *WorkerPool
NewWorkerPool creates a worker pool with specified number of workers
func NewWorkerPoolWithTimeout ¶
func NewWorkerPoolWithTimeout(workers int, taskTimeout time.Duration) *WorkerPool
NewWorkerPoolWithTimeout creates a worker pool with custom task timeout
func (*WorkerPool) DetailedStats ¶
func (wp *WorkerPool) DetailedStats() WorkerPoolStats
DetailedStats returns detailed pool statistics
func (*WorkerPool) Results ¶
func (wp *WorkerPool) Results() <-chan TaskResult
Results returns the results channel
func (*WorkerPool) Start ¶
func (wp *WorkerPool) Start(graph *storage.GraphStorage)
Start starts the worker pool
func (*WorkerPool) Stats ¶
func (wp *WorkerPool) Stats() (processed, active int64)
Stats returns pool statistics
func (*WorkerPool) Submit ¶
func (wp *WorkerPool) Submit(task Task) error
Submit submits a task for execution
Source Files
¶
- aggregation.go
- aggregation_functions.go
- aggregation_grouping.go
- ast.go
- ast_arithmetic.go
- ast_eval.go
- ast_expressions.go
- executor.go
- executor_explain.go
- executor_plan.go
- executor_results.go
- executor_steps.go
- executor_vector_step.go
- functions.go
- functions_numeric.go
- functions_schema.go
- functions_search.go
- functions_string.go
- functions_vector.go
- lexer.go
- lexer_types.go
- match_executor.go
- match_helpers.go
- match_node.go
- match_path.go
- optimizer.go
- parallel_aggregation.go
- parallel_pathfinder.go
- parallel_traversal.go
- parser.go
- parser_clauses.go
- parser_expressions.go
- parser_patterns.go
- parser_properties.go
- path_options.go
- physical_ops_call.go
- physical_ops_join.go
- physical_ops_mutate.go
- physical_ops_project.go
- physical_ops_scan.go
- physical_plan.go
- planner.go
- post_processor.go
- procedures.go
- property_target.go
- sanitizer.go
- stream.go
- stream_pipeline.go
- stream_query.go
- stream_types.go
- timeout.go
- traversal_bfs.go
- traversal_dfs.go
- traversal_paths.go
- traversal_types.go
- workerpool.go