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.
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.
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.