Skip to main content

Node

Enum Node 

Source
pub enum Node {
Show 13 variants Get { catalog: StrRef, schema: StrRef, table: StrRef, alias: StrRef, index: u32, columns: Slice, }, Dummy, Values { index: u32, columns: Slice, rows: Slice, }, TableFunction { index: u32, function: StrRef, args: Slice, columns: Slice, }, Filter { input: NodeRef, predicate: ExprRef, }, Project { input: NodeRef, index: u32, exprs: Slice, names: Slice, }, Aggregate { input: NodeRef, index: u32, groups: Slice, aggregates: Slice, }, Sort { input: NodeRef, keys: Slice, }, Limit { input: NodeRef, count: Option<u64>, offset: u64, }, Distinct { input: NodeRef, on: Slice, }, Join { left: NodeRef, right: NodeRef, kind: JoinKind, conditions: Slice, }, CrossProduct { left: NodeRef, right: NodeRef, }, SetOp { left: NodeRef, right: NodeRef, kind: SetOpKind, all: bool, index: u32, },
}
Expand description

One logical operator.

Children are the inputs, in the order Node::children returns them, which is the order they print in and the order the reader expects.

Variants§

§

Get

A base table scan.

The projection is in columns, so a scan of two columns of a 105-column table is a two column scan in the plan and not a filter over a wide one. spec/09-optimizer.md section 9.2 calls projection pushdown the difference between 20 GB and 200 MB on ClickBench, and this is the field it pushes into.

Fields

§catalog: StrRef

The catalog name.

§schema: StrRef

The schema name.

§table: StrRef

The table name.

§alias: StrRef

The alias the query used, which is what an error message should say.

§index: u32

The table index that this scan’s columns bind against.

§columns: Slice

The projected columns with their types, into the field pool.

§

Dummy

One row and no columns.

What SELECT 1 sits on top of. Not an empty result: an empty result produces no rows and SELECT 1 produces one, and conflating them is how a scalar subquery starts returning nothing instead of null.

§

Values

Literal rows.

Every row has the same length as columns, which Plan::validate checks, because a ragged VALUES is a wrong answer rather than a crash.

Fields

§index: u32

The table index that these columns bind against.

§columns: Slice

The output columns with their types, into the field pool.

§rows: Slice

The rows, into the row pool, each row a slice of the expression list pool.

§

TableFunction

A function call where a table goes, such as range(10).

The arguments are expressions rather than numbers, because range(2 + 3) is a legal call and folding it here would mean the plan could not be printed back as what was written. They cannot refer to a column: a table function that sees the row on its left is LATERAL, which is a different node and is not here yet.

A separate node from Node::Values even though range(3) and VALUES (0), (1), (2) produce the same rows, because the one that produces three million rows should be three numbers in the plan rather than three million expressions in it.

Fields

§index: u32

The table index that this call’s columns bind against.

§function: StrRef

Which function, as its own canonical name.

§args: Slice

The arguments, into the expression list pool.

§columns: Slice

The produced columns with their types, into the field pool.

§

Filter

A predicate over the input, keeping the rows where it is true.

True, not “not false”. A null predicate drops the row, which is SQL’s rule and is the difference between WHERE and CHECK.

Fields

§input: NodeRef

The input.

§predicate: ExprRef

The predicate, which has to be BOOLEAN.

§

Project

A projection, producing a new set of columns from the input’s.

Fields

§input: NodeRef

The input.

§index: u32

The table index the produced columns bind against.

§exprs: Slice

The expressions, into the expression list pool.

§names: Slice

One output name per expression, into the name list pool.

Names are carried through the whole plan rather than attached at the root, because the thing a person reads a plan dump to answer is usually which column this is, and a dump with the names stripped out answers that with a number.

§

Aggregate

A grouped or ungrouped aggregation.

The output is the group expressions followed by the aggregates, in that order, and that is what a binding into index means. An ungrouped aggregate has an empty groups and still produces exactly one row, including over an empty input.

Fields

§input: NodeRef

The input.

§index: u32

The table index the produced columns bind against.

§groups: Slice

The group expressions, into the expression list pool.

§aggregates: Slice

The aggregate expressions, into the expression list pool. Every element is an Expr::Aggregate and this is the only place one may appear.

§

Sort

An ordering.

Fields

§input: NodeRef

The input.

§keys: Slice

The keys in priority order, into the sort key pool.

§

Limit

A row count limit and an offset.

Both are constants. LIMIT over an expression is legal SQL and DuckDB evaluates it before the plan runs, so by the time it is here it is a number or the query did not bind.

Fields

§input: NodeRef

The input.

§count: Option<u64>

How many rows to emit, or all of them.

§offset: u64

How many rows to skip first.

§

Distinct

Duplicate elimination, over the whole row or over named expressions.

Fields

§input: NodeRef

The input.

§on: Slice

The DISTINCT ON expressions, into the expression list pool. Empty means the whole row, which is plain DISTINCT.

§

Join

A join with a condition.

Fields

§left: NodeRef

The left input.

§right: NodeRef

The right input.

§kind: JoinKind

Which join.

§conditions: Slice

The conditions, into the expression list pool, combined with AND. Empty is a join with no condition, which for an inner join is a cross product and for an outer join is not.

§

CrossProduct

An unconditional cross product.

Separate from a Node::Join with no conditions because join ordering treats them differently: a cross product has no edge in the join graph and section 9.4’s dynamic program enumerates connected subgraphs.

Fields

§left: NodeRef

The left input.

§right: NodeRef

The right input.

§

SetOp

UNION, EXCEPT or INTERSECT.

Fields

§left: NodeRef

The left input.

§right: NodeRef

The right input.

§kind: SetOpKind

Which operation.

§all: bool

Whether duplicates are kept.

§index: u32

The table index the produced columns bind against, since the output is neither side’s columns.

Implementations§

Source§

impl Node

Source

pub fn keyword(&self) -> &'static str

The keyword this operator prints as, which is also what the reader dispatches on.

Source

pub fn children(&self) -> [Option<NodeRef>; 2]

The inputs, in printing order.

Two slots rather than a Vec, because no logical operator in this set has three inputs and the printer walks this on every node of every dump. A caller wants node.children().into_iter().flatten().

Source

pub fn arity(&self) -> usize

How many inputs this operator takes.

Source

pub fn table_index(&self) -> Option<u32>

The table index this operator introduces, if it introduces one.

Trait Implementations§

Source§

impl Clone for Node

Source§

fn clone(&self) -> Node

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Node

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Node

Source§

impl PartialEq for Node

Source§

fn eq(&self, other: &Node) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Node

Auto Trait Implementations§

§

impl Freeze for Node

§

impl RefUnwindSafe for Node

§

impl Send for Node

§

impl Sync for Node

§

impl Unpin for Node

§

impl UnsafeUnpin for Node

§

impl UnwindSafe for Node

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.