Skip to main content

Inspecting Plans

db.query() hides the logical plan, but the stages are public, so you can stop after planning, look at what the optimizer produced, change it, and only then execute.

Get the plan for a query

buildPlan translates one AST node into a plan of algebra operators and runs the optimizer on it:

const ast = db.parse('SELECT a FROM t ORDER BY a');
const queryPlan = db.buildPlan(ast.at(-1));

queryPlan is the root of an operator tree. Every operator exposes getChildren() for quick traversal, and both AST nodes and plan operators implement the visitor pattern when you need something more structured than a walk.

Read a plan diagram

The Showcase demo draws the plan for whatever you type. The root is the final query, the leaves are data sources, and nodes are colored by the language that produced them. That is how you can see a cross-language query become one tree. Tuple operators also show their schema in grey brackets.

The edges carry information too:

  • Solid: the child is created once, with its parent.
  • Dashed: the child is recreated repeatedly during the parent's life, once per incoming row.

Plan visualization example

In SELECT x + 3 AS xplusthree FROM table1 above, the TupleSource table1 is built once (solid), while the Calculation for x + 3 is re-evaluated per row (dashed) and points at the attribute it produces. The formal name for that distinction is vertical vs. horizontal inputs.

Rewrite a plan before executing it

A plan is a mutable object tree, so a one-off change needs no visitor. This walks the whole tree and flips every ORDER BY direction:

import * as plan from '@dortdb/core/plan';

const stack = [queryPlan];
while (stack.length) {
const current = stack.pop();
stack.push(...current.getChildren());
if (current instanceof plan.OrderBy) {
for (const o of current.orders) {
o.ascending = !o.ascending;
}
}
}

const result = db.executePlan(queryPlan);

For a rewrite you want applied to every query rather than one, write an optimizer rule instead.

Experiment first

The Showcase lets you toggle and reorder individual optimizer rules and watch the plan change. It is the fastest way to see what a rule does before you rely on it. See Optimization.