// Projection-side IR: the compiled projection (ProjPlan), segments, the // whole Plan, the pre-segment stage specs, and the plan-error helper.
package plan import ( ) // BoundReturn is one projected column. type BoundReturn struct { Expr ast.Expr Name string IsAgg bool } // PostProj is one post-aggregation scalar projection: output column Col is // computed by Expr (rewritten to read hidden __agg{k} slots) after the // groups finalize. type PostProj struct { Col int Expr ast.Expr } // ProjPlan is a compiled projection (a With boundary or the final RETURN). type ProjPlan struct { Returns []BoundReturn Distinct bool Aggregated bool // GroupIdx are the non-aggregate output columns (the group key). GroupIdx []int Aggs []AggCol // Post are the nested-aggregate scalar wrappers; NHidden counts the // hidden accumulator slots feeding them (per-group rows are sized // len(Returns)+NHidden, truncated back after Post runs). Post []PostProj NHidden int OrderBy []ast.SortItem Skip *uint64 Limit *uint64 Columns []string } // Segment is one pipeline stage run: the stages in order, then the // projection. Output columns feed the next segment. type Segment struct { Stages []Stage RowWidth int Slots map[string]int Proj ProjPlan // PostWhere filters projected rows (references output columns) -- the // projection boundary's WHERE. PostWhere ast.Expr // ColAgg marks a columnar-aggregate candidate (colagg.go): the // executor may fuse the scan, filters, and aggregation into one // typed column pass, falling back to the general chain when any // expression declines classification. ColAgg bool } // Plan is a compiled query: one segment pipeline per UNION branch, the // combinators between them, and the output column names (identical across // branches, validated at plan time). type Plan struct { Branches [][]*Segment Union []ast.UnionKind Columns []string // Alt is a sibling plan identical to this one except that a single // auto-parameterized anchor tie (both endpoints unbound param seeks, // whose real degrees the planner cannot see) is oriented the opposite // way. It is a FULL second planning pass, so every rewrite/recognizer // pass ran over it too -- never a spare op chain hidden inside a stage. // The cached executor resolves both anchors from the now-bound params // and runs whichever seeds from the lower-degree end; nil when the query // has no qualifying tie (the common case). Alt itself never carries an // Alt. Alt *Plan // Ties is how many auto-parameterized anchor ties the primary pass // collected. Alt covers the first; a count above one means the rest // stayed on the static fallback (the measurement for whether a fuller // choice mechanism would ever fire). Ties int } // specKind discriminates a stageSpec. type specKind uint8 const ( specMatch specKind = iota specShortest specCall specUnwind specCallSubquery ) // stageSpec is one clause accumulated before its segment is built (at the // next projection boundary). type stageSpec struct { kind specKind // specMatch / specShortest pattern *ast.Pattern where ast.Expr optional bool pathVar string // named-path bind ("" none) acyclic bool // ACYCLIC path mode (specMatch only) walk bool // REPEATABLE ELEMENTS: no rel uniqueness in this clause // scope identifies the source MATCH clause for relationship // uniqueness: comma patterns share it; planner splits inherit it. scope uint32 // specShortest all bool weight *ast.CostSpec // specCall proc string args []ast.Expr yields []ast.YieldItem // specUnwind list ast.Expr varName string // specCallSubquery query *ast.Query imports []string } // planErrf is a plan-stage error (wrapped onto ErrPlan by the root package). func planErrf( string, ...any) error { return &semantics.Error{Kind: semantics.KindPlan, Msg: fmt.Sprintf(, ...)} } // bindErrf is a bind-stage error surfaced during planning (unknown // variable, UNION column mismatch, aggregate misuse). func bindErrf( string, ...any) error { return &semantics.Error{Kind: semantics.KindBind, Msg: fmt.Sprintf(, ...)} }