// Execute: run a plan's UNION branches and combine their rows (port of // the Rust exec.rs entry points, minus the recognizer kernel dispatch).
package exec import ( ) // Execute runs a plan and returns its rows in output-column order. Every // plan construct the planner produces is executable as of M19, so // execution is infallible once a plan builds. func ( *eval.Ctx, *plan.Plan) ([][]value.Value, error) { installCompileWhere() := runBranch(, .Branches[0]) for , := range .Union { combineUnion(&, runBranch(, .Branches[+1]), ) } return , nil } // installCompileWhere hands the eval-side subquery walk a compiler for // its WHERE filters: eval cannot import compile (compile imports eval), // so the executor -- which reaches both -- bridges them. Idempotent; the // interpreted path stays authoritative under ForceInterp and on // non-native graphs, mirroring compileEval's own gate. func installCompileWhere( *eval.Ctx) { if .CompileWhere != nil || .ForceInterp { return } , := .G.(graph.Native) if ! { return } := .Snapshot() .CompileWhere = func( ast.Expr, map[string]int) func(*eval.Ctx, []value.Value) value.Value { := compile.New(, , , ) return func( *eval.Ctx, []value.Value) value.Value { return .Eval(, , ) } } } // ExecuteProfiled runs the plan while recording how many rows each // operator produces. Segment profiles are pushed branch-major, // segment-minor -- the order the explain renderer walks. PROFILE reports // operator cardinalities, not the result set; each branch's final rows // are discarded (the union combine is not a profiled operator). func ( *eval.Ctx, *plan.Plan) *explain.Profile { installCompileWhere() := &explain.Profile{} for , := range .Branches { := [][]value.Value{nil} for , := range { := explain.SegProf{} = runSegment(, , , &) .Segs = append(.Segs, ) } } return } // runBranch runs one branch's segment pipeline from a single empty seed // row, streaming across every run of boundaries whose upstream projection // is per-row passthrough (rows cross a NEXT without materializing; the // run's final segment materializes as before). func runBranch( *eval.Ctx, []*plan.Segment) [][]value.Value { := [][]value.Value{nil} for := 0; < len(); { // A columnar-aggregate chain fuses whole: the scan segment, its // LET boundaries, and the aggregated boundary run as one typed // pass; a declined chain falls through to the general runs. if [].ColAgg { if , , := tryColumnarAggChain(, , , ); { = += continue } } // An aggregate whose ordering and DISTINCT+LIMIT live on the two // following boundaries fuses to a streamed argmin selection. if , , := tryOrderedDistinctTopK(, , , ); { = += continue } := // Runs never stream INTO a chain head: the fused pass needs its // materialized seed rows. for +1 < len() && streamableBoundary([]) && ![+1].ColAgg { ++ } = runSegmentRun(, [:+1], ) = + 1 } return } // combineUnion folds a later branch's rows into the accumulator. UNION ALL // concatenates; UNION concatenates then dedups the whole accumulated set // keeping first-occurrence order (left-associative). The dedup key matches // DISTINCT's group key, so UNION and RETURN DISTINCT agree on row // identity. func combineUnion( *[][]value.Value, [][]value.Value, ast.UnionKind) { // EXCEPT / INTERSECT: distinct-set semantics (ISO) -- dedup the left // side, then keep rows absent from / present in the right side. if == ast.UnionExcept || == ast.UnionIntersect { := make(map[string]struct{}, len()) var []byte for , := range { = [:0] for , := range { = value.AppendKey(, ) } [string()] = struct{}{} } := make(map[string]struct{}, len(*)) := (*)[:0] for , := range * { = [:0] for , := range { = value.AppendKey(, ) } if , := [string()]; { continue } [string()] = struct{}{} , := [string()] if ( == ast.UnionExcept) != { = append(, ) } } * = return } * = append(*, ...) if != ast.UnionDistinct { return } := make(map[string]struct{}, len(*)) := (*)[:0] var []byte for , := range * { = [:0] for , := range { = value.AppendKey(, ) } if , := [string()]; ! { [string()] = struct{}{} = append(, ) } } * = }