Skip to main content

EmbedPlan

Struct EmbedPlan 

Source
pub struct EmbedPlan {
    pub local_column: String,
    pub foreign_column: String,
    pub foreign_column_type: String,
    pub foreign_schema: String,
    pub foreign_table: String,
    pub is_list: bool,
}
Expand description

Everything needed to fetch one relationship’s rows for a set of parents.

Fields§

§local_column: String

Column on the parent row whose value identifies the parent.

§foreign_column: String

Column on the related table that points back at the parent.

§foreign_column_type: String

PostgreSQL type of the foreign column, used to cast the bound array.

§foreign_schema: String

Schema of the related table.

§foreign_table: String

Name of the related table.

§is_list: bool

Whether the relationship yields many rows per parent.

Implementations§

Source§

impl EmbedPlan

Source

pub fn resolve( relationship: &Relationship, schema_cache: &SchemaCache, ) -> Result<Self>

Resolve a relationship into an embed plan.

Returns an error for relationships this cannot express yet, rather than silently omitting the embedded data.

Source

pub fn children_sql( &self, limit: Option<i64>, columns: &[String], ) -> Result<String>

SQL that fetches every related row for the given parent key values.

The keys are bound as a single text array and cast to the foreign column’s type, so the column itself is never wrapped in a cast and an index on it remains usable. limit bounds the rows per query, not per parent.

columns is the set of columns the client asked for. An empty set means every column. Projecting here rather than discarding columns after the fact matters: an unprojected column is read from the heap, serialised to JSON by PostgreSQL, sent over the socket and parsed, before being thrown away. The join column is always included even when it was not requested, because grouping needs it; the caller strips it afterwards.

Source

pub fn children_grouped_sql( &self, limit: Option<i64>, columns: &[String], ) -> Result<String>

SQL that fetches related rows already grouped by their join key.

One row comes back per distinct key: the key itself and a JSON array of that key’s children. Grouping in PostgreSQL rather than in this process removes a per-child-row JSON parse, the per-row hash insert, and the clone of each group onto its parent.

The key is returned as JSON rather than cast to text, so it is rendered by the same code that renders the parents’ keys. Casting to text in SQL would agree for integers and uuids and disagree for a NUMERIC join column, where PostgreSQL and serde_json format differently.

limit still bounds the rows scanned, not the rows per parent, so it is applied to the inner select exactly as the ungrouped form does.

Source

pub fn embed_expression( &self, parent_alias: &str, child_alias: &str, inner_select: &str, limit: Option<i64>, ) -> Result<String>

A correlated subselect that yields this relationship as one JSON column.

This is the single-query form of embedding: instead of fetching parents, collecting their keys and issuing a second query, the relationship is attached to the parent query as an expression, so PostgreSQL builds the array while it already has the parent row.

inner_select is the child’s SELECT list, which the caller assembles – its columns, plus any deeper relationship expressions built by calling this again. Only the caller knows the shape of its own selection tree, so the recursion lives there and the SQL assembly lives here.

Parent columns are deliberately left alone: they stay ordinary typed columns and are converted to JSON by the same code as an unembedded request, so embedding does not change how a NUMERIC or a timestamp is rendered. Only the relationship column arrives as JSON, which is what the separate child query already returned.

Trait Implementations§

Source§

impl Clone for EmbedPlan

Source§

fn clone(&self) -> EmbedPlan

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 EmbedPlan

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more