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: StringColumn on the parent row whose value identifies the parent.
foreign_column: StringColumn on the related table that points back at the parent.
foreign_column_type: StringPostgreSQL type of the foreign column, used to cast the bound array.
foreign_schema: StringSchema of the related table.
foreign_table: StringName of the related table.
is_list: boolWhether the relationship yields many rows per parent.
Implementations§
Source§impl EmbedPlan
impl EmbedPlan
Sourcepub fn resolve(
relationship: &Relationship,
schema_cache: &SchemaCache,
) -> Result<Self>
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.
Sourcepub fn children_sql(
&self,
limit: Option<i64>,
columns: &[String],
) -> Result<String>
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.
Sourcepub fn children_grouped_sql(
&self,
limit: Option<i64>,
columns: &[String],
) -> Result<String>
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.
Sourcepub fn embed_expression(
&self,
parent_alias: &str,
child_alias: &str,
inner_select: &str,
limit: Option<i64>,
) -> Result<String>
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§
Auto Trait Implementations§
impl Freeze for EmbedPlan
impl RefUnwindSafe for EmbedPlan
impl Send for EmbedPlan
impl Sync for EmbedPlan
impl Unpin for EmbedPlan
impl UnsafeUnpin for EmbedPlan
impl UnwindSafe for EmbedPlan
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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