package gql

Import Path
	github.com/freeeve/gochickpeas/gql (on go.dev)

Dependency Relation
	imports 20 packages, and imported by one package

Involved Source Files PlanCache: a size-bounded LRU cache of auto-parameterized query plans. Two layers share one lock. An exact-string fast path (L1) skips parse + plan on a verbatim repeat; a template index (L2) lets queries differing only in lifted constants share one compiled plan. L1 entries own the plans; a template entry dies when its last L1 variant is evicted (the Go refcount standing in for the Rust engine's Arc/Weak split). Both layers hold the TEMPLATE plan -- planned after auto- parameterization, where every cost probe abstains on parameter slots -- so a cached plan is value-independent by construction. It may differ in SHAPE (never in results) from the literal-probed plan an uncached Run builds for the same text; this mirrors the Rust engine's query_cached composition, trading the best-effort literal plan for zero double planning and cross-literal sharing. Eviction is least-recently-used past a configurable byte budget. The byte estimate counts each L1 entry's key, parameters, and a per-plan estimate; a plan shared by several literal variants is charged once per variant -- a deliberate over-count, so the true footprint stays under the bound. The implicit per-snapshot plan cache behind Run/RunWithParams: library callers get template caching (skip parse + plan on repeats) with no setup, per the census verdict -- every measured flip is timing-neutral and the flip-aware bypass routes structurally flipped templates through sighted planning, so the cached path does no harm. The registry keys caches by WEAK snapshot pointers with a GC cleanup, so dropping a snapshot drops its cache; a cache never outlives (or pins) its snapshot. Callers wanting the literal-planned path explicitly -- benchmarks separating cold from warm, plan-shape experiments that mutate planner thresholds between runs -- use RunUncached. Package gql is a read-only GQL query engine over an immutable chickpeas.Snapshot -- the Go port of the rustychickpeas-cypher engine with an ISO GQL (read subset) surface. Pipeline: parse -> desugar -> bind -> plan -> execute, returning Rows. The public entry points: Run/RunWithParams execute a GQL query over an engine snapshot; Explain renders the plan. Pipeline: parse -> desugar -> plan (cost-based) -> execute, mapping each stage's typed error onto the package sentinels. Plan-flip detection for the cache: a template planned blind (constants lifted to parameters) can choose a structurally different operator tree than value-sighted planning would -- exact scan cardinalities, resolved anchor degrees, and rewrite gates priced from those exacts all go blind under auto-parameterization, and a flipped plan can be arbitrarily worse (the census measured one 17.5x allocation regression). The cache detects the flip once, when a template is first planned, by also planning the literal text and comparing the trees value-blind; a flipped template is marked so execution routes through sighted planning instead of the cached tree. Non-flipped templates -- the overwhelming majority -- keep the full cache win. Prepared: a parsed, auto-parameterized, and planned query, ready to execute repeatedly without re-incurring parse/plan cost -- the unit the plan cache holds, exposed directly for callers managing their own reuse. The result surface: Rows, an iterator of named-column Row values. The executor materializes the result set and Rows streams it from the buffer (same contract as the Rust engine's lazy Rows).
Package-Level Type Names (total 4)
/* sort by: | */
PlanCache is a size-bounded cache of auto-parameterized plans, safe for concurrent use. Hold one per long-lived snapshot: a cached plan's cost choices reflect the statistics of the snapshot its template was first planned against (executing against another snapshot is correct, possibly suboptimal). Bytes is the approximate resident bytes currently charged. IsEmpty reports whether no live template plan is cached. Len is the number of distinct templates with a live plan. MaxBytes is the current byte budget. Run executes a GQL query through the cache. RunWithParams executes a GQL query through the cache with explicit $name parameter values. Results are identical to the uncached RunWithParams. SetMaxBytes changes the budget, evicting immediately if over it. func DefaultCacheFor(g *chickpeas.Snapshot) *PlanCache func NewPlanCache(maxBytes int) *PlanCache
Prepared is a compiled query. The plan is auto-parameterized (its inline constants are lifted and stored), so it is value-independent by construction; its cost-based choices reflect the statistics of the snapshot it was prepared against -- executing against another snapshot is legal and correct, possibly suboptimal. An EXPLAIN/PROFILE query prepares too: Execute then returns the rendered plan. Columns is the output column names the plan produces, in order. Execute runs the prepared plan against g with explicit $name parameter values (an unsupplied parameter reads as null); the stored lifted constants rebind automatically. For an EXPLAIN/PROFILE query this returns the rendered plan instead. The adaptive anchor choice runs here exactly as on the cached path: a statement prepared once and executed many times with different parameter values is the canonical parameter-sniffing shape, so the value-resolved sibling choice matters MOST on this path. func Prepare(g *chickpeas.Snapshot, query string) (*Prepared, error)
Row is one result row: named columns mapped to values. The column slice is shared across every row of a result. Columns is the output column names, in order. Get returns the value of column name; ok is false when absent. GetAt returns the value at output position i; ok is false out of range. Values is the row's values in output-column order. func (*Rows).Next() (Row, bool) func (*Rows).NextBatch(n int) []Row
Rows iterates a query's result rows. All iterates the remaining rows (range-over-func). Columns is the output column names, in order. Next pulls the next row; ok is false when the result is exhausted. NextBatch pulls up to n rows (fewer if the result is exhausted). func Run(g *chickpeas.Snapshot, query string) (*Rows, error) func RunUncached(g *chickpeas.Snapshot, query string) (*Rows, error) func RunUncachedWithParams(g *chickpeas.Snapshot, query string, params map[string]value.Value) (*Rows, error) func RunWithParams(g *chickpeas.Snapshot, query string, params map[string]value.Value) (*Rows, error) func (*PlanCache).Run(g *chickpeas.Snapshot, query string) (*Rows, error) func (*PlanCache).RunWithParams(g *chickpeas.Snapshot, query string, params map[string]value.Value) (*Rows, error) func (*Prepared).Execute(g *chickpeas.Snapshot, params map[string]value.Value) (*Rows, error)
Package-Level Functions (total 9)
DefaultCacheFor returns the snapshot's implicit plan cache, creating it on first use (DefaultCacheBytes budget). Run and RunWithParams route through it; sharing the same cache with explicit PlanCache calls is fine but unnecessary.
Explain renders the query's plan (with cardinality estimates and anchor notes) without executing it.
ExplainCanonical renders the query's plan as a stable, canonical shape string for golden plan-regression snapshots: operator order, scan sources, hop patterns, the recognizers that fired, and the chosen anchor -- with the volatile parts (wall-clock planning time, the numeric estimates, the anchor note's magnitudes) excluded. Unlike Explain the output is deterministic across plannings, so a diff between two commits is a review prompt that a planner change moved the plan, invisible to a row-level differential.
NewPlanCache is an empty cache bounded to maxBytes of approximate resident memory (LRU eviction past the bound); maxBytes <= 0 means DefaultCacheBytes.
Prepare parses, desugars, auto-parameterizes, and plans query once against g's statistics.
Run executes a GQL query over the snapshot, through the snapshot's implicit plan cache (see DefaultCacheFor): repeats skip parse + plan, results are identical to the uncached path by the -cached-parity contract, and structurally flipped templates route through sighted planning. Use RunUncached for the always-literal-planned path.
RunUncached executes a GQL query with literal-sighted planning on every call, bypassing the implicit plan cache -- the cold path, for benchmarks separating cold from warm and for callers that mutate planner behavior between runs.
RunUncachedWithParams is RunUncached with explicit $name parameter values.
RunWithParams is Run with explicit $name parameter values. An unsupplied parameter reads as null.
Package-Level Variables (total 4)
ErrBind marks a semantic error (unknown variable, bad reference).
ErrEval marks a runtime evaluation error.
ErrParse marks a syntax error from the parser.
ErrPlan marks a planning error (unsupported construct, bad plan input).
Package-Level Constants (only one)
DefaultCacheBytes is the default budget: 128 MiB of approximate resident plan + key + parameter bytes.