pub trait TableSource:
DataSource
+ Clone
+ 'static {
type Column<Type>: ColumnLike<Type> + Clone
where Type: ColumnType;
type AnyType: ColumnType;
type Value: Clone + Send + Sync + 'static;
type Id: Send + Sync + Clone + Hash + Eq + 'static;
type Source: TableSourceSpec;
type Condition: Clone + Send + Sync + 'static;
Show 27 methods
// Required methods
fn create_column<Type: ColumnType>(&self, name: &str) -> Self::Column<Type>;
fn to_any_column<Type: ColumnType>(
&self,
column: Self::Column<Type>,
) -> Self::Column<Self::AnyType>;
fn convert_any_column<Type: ColumnType>(
&self,
any_column: Self::Column<Self::AnyType>,
) -> Option<Self::Column<Type>>;
fn expr(
&self,
template: impl Into<String>,
parameters: Vec<ExpressiveEnum<Self::Value>>,
) -> Expression<Self::Value>;
fn search_table_condition<E>(
&self,
table: &Table<Self, E>,
search_value: &str,
) -> Self::Condition
where E: Entity<Self::Value>,
Self: Sized;
fn list_table_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<IndexMap<Self::Id, Record<Self::Value>>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<Option<Record<Self::Value>>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn get_table_some_value<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<Option<(Self::Id, Record<Self::Value>)>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_table_count<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_table_sum<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn get_table_max<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn get_table_min<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn insert_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn replace_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn patch_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
partial: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn delete_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn delete_table_all_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn insert_table_return_id_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
record: &'life2 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Self::Id>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn related_in_condition<SourceE: Entity<Self::Value> + 'static>(
&self,
target_field: &str,
source_table: &Table<Self, SourceE>,
source_column: &str,
) -> Self::Condition
where Self: Sized;
fn column_table_values_expr<'a, E, Type: ColumnType>(
&'a self,
table: &Table<Self, E>,
column: &Self::Column<Type>,
) -> AssociatedExpression<'a, Self, Self::Value, Vec<Type>>
where E: Entity<Self::Value> + 'static,
Self: ExprDataSource<Self::Value> + Sized;
// Provided methods
fn eq_condition(field: &str, value: &str) -> Result<Self::Condition> { ... }
fn eq_value_condition(
&self,
field: &str,
value: Self::Value,
) -> Result<Self::Condition> { ... }
fn coerce_reference_value(&self, value: Self::Value) -> Self::Value { ... }
fn stream_table_values<'a, E>(
&'a self,
table: &Table<Self, E>,
) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + 'a>>
where E: Entity<Self::Value> + 'a,
Self: Sized { ... }
fn related_correlated_condition(
&self,
target_table: &str,
target_field: &str,
source_table: &str,
source_column: &str,
) -> Self::Condition { ... }
fn supports_traversal(&self) -> bool { ... }
fn traversal_path_expr(
&self,
hops: &[&str],
column: &str,
) -> Option<Expression<Self::Value>> { ... }
}Expand description
Trait for table data sources that defines column type separate from execution TableSource represents a data source that can create and manage tables
Required Associated Types§
type Column<Type>: ColumnLike<Type> + Clone where Type: ColumnType
type AnyType: ColumnType
type Value: Clone + Send + Sync + 'static
type Id: Send + Sync + Clone + Hash + Eq + 'static
Sourcetype Source: TableSourceSpec
type Source: TableSourceSpec
How this backend names its source. Most backends use String;
SQL/SurrealDB backends use SelectSource<Self::Select> so a table can
be sourced from an arbitrary sub-SELECT. See crate::source.
Required Methods§
Sourcefn create_column<Type: ColumnType>(&self, name: &str) -> Self::Column<Type>
fn create_column<Type: ColumnType>(&self, name: &str) -> Self::Column<Type>
Create a new column with the given name
Sourcefn to_any_column<Type: ColumnType>(
&self,
column: Self::Column<Type>,
) -> Self::Column<Self::AnyType>
fn to_any_column<Type: ColumnType>( &self, column: Self::Column<Type>, ) -> Self::Column<Self::AnyType>
Convert a typed column to type-erased column
Sourcefn convert_any_column<Type: ColumnType>(
&self,
any_column: Self::Column<Self::AnyType>,
) -> Option<Self::Column<Type>>
fn convert_any_column<Type: ColumnType>( &self, any_column: Self::Column<Self::AnyType>, ) -> Option<Self::Column<Type>>
Attempt to convert a type-erased column back to typed column
Sourcefn expr(
&self,
template: impl Into<String>,
parameters: Vec<ExpressiveEnum<Self::Value>>,
) -> Expression<Self::Value>
fn expr( &self, template: impl Into<String>, parameters: Vec<ExpressiveEnum<Self::Value>>, ) -> Expression<Self::Value>
Create an expression from a template and parameters, similar to Expression::new
Sourcefn search_table_condition<E>(
&self,
table: &Table<Self, E>,
search_value: &str,
) -> Self::Condition
fn search_table_condition<E>( &self, table: &Table<Self, E>, search_value: &str, ) -> Self::Condition
Create a search condition matching search_value across the table’s
searchable fields. This is a server-side capability — it pushes the
match down to the backend’s query engine.
Different vendors implement search differently:
- SQL:
field LIKE '%value%'(returns Expression) - SurrealDB:
field CONTAINS 'value'(returns Expression) - MongoDB:
{ field: { $regex: 'value' } }(returns MongoCondition)
Contract for backends that cannot search server-side (e.g. CSV, redb):
return a condition that yields an ErrorKind::Unsupported error when it is
resolved — never a silent match-all (which leaks every row as if filtered)
and never a panic. Searching loaded/in-memory data is the Lens/Diorama
layer’s responsibility, not the backend’s.
Sourcefn list_table_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<IndexMap<Self::Id, Record<Self::Value>>>> + Send + 'async_trait>>
fn list_table_values<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<IndexMap<Self::Id, Record<Self::Value>>>> + Send + 'async_trait>>
Get all data from a table as Record values with IDs (for ReadableValueSet implementation)
Sourcefn get_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<Option<Record<Self::Value>>>> + Send + 'async_trait>>
fn get_table_value<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, ) -> Pin<Box<dyn Future<Output = Result<Option<Record<Self::Value>>>> + Send + 'async_trait>>
Get a single record by ID as Record value (for ReadableValueSet implementation).
Returns Ok(None) when no record exists with the given ID.
Sourcefn get_table_some_value<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<Option<(Self::Id, Record<Self::Value>)>>> + Send + 'async_trait>>
fn get_table_some_value<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<Option<(Self::Id, Record<Self::Value>)>>> + Send + 'async_trait>>
Get some data from a table as Record value with ID (for ReadableValueSet implementation)
Sourcefn get_table_count<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'async_trait>>
fn get_table_count<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'async_trait>>
Get count of records in the table
Sourcefn get_table_sum<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
fn get_table_sum<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, column: &'life2 Self::Column<Self::AnyType>, ) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
Get sum of a column in the table (returns native value type)
Sourcefn get_table_max<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
fn get_table_max<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, column: &'life2 Self::Column<Self::AnyType>, ) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
Get maximum value of a column in the table (returns native value type)
Sourcefn get_table_min<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
fn get_table_min<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, column: &'life2 Self::Column<Self::AnyType>, ) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
Get minimum value of a column in the table (returns native value type)
Sourcefn insert_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn insert_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, record: &'life3 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Insert a record as Record value (for WritableValueSet implementation)
Sourcefn replace_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn replace_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, record: &'life3 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Replace a record as Record value (for WritableValueSet implementation)
Sourcefn patch_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
partial: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn patch_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, partial: &'life3 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Patch a record as Record value (for WritableValueSet implementation)
Sourcefn delete_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
fn delete_table_value<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
Delete a record by ID (for WritableValueSet implementation)
Sourcefn delete_table_all_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
fn delete_table_all_values<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
Delete all records (for WritableValueSet implementation)
Sourcefn insert_table_return_id_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
record: &'life2 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Self::Id>> + Send + 'async_trait>>
fn insert_table_return_id_value<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, record: &'life2 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Self::Id>> + Send + 'async_trait>>
Insert a record and return generated ID (for InsertableValueSet implementation)
Build a condition for “target_field IN (values of source_column from source_table)”.
Used by the relationship traversal system (get_ref_as) to filter
a target table by foreign key values from a source table.
Each backend implements this natively:
- SQL backends build a subquery:
"id" IN (SELECT "bakery_id" FROM "client" WHERE ...) - MongoDB builds a deferred
{ field: { "$in": [...] } }document - CSV fetches values in memory and builds an IN condition
Sourcefn column_table_values_expr<'a, E, Type: ColumnType>(
&'a self,
table: &Table<Self, E>,
column: &Self::Column<Type>,
) -> AssociatedExpression<'a, Self, Self::Value, Vec<Type>>
fn column_table_values_expr<'a, E, Type: ColumnType>( &'a self, table: &Table<Self, E>, column: &Self::Column<Type>, ) -> AssociatedExpression<'a, Self, Self::Value, Vec<Type>>
Return an associated expression that, when resolved, yields all values of the given typed column from this table (respecting current conditions).
For query-language backends, this can be a subquery expression.
For simple backends (CSV), this uses a DeferredFn that loads data
and extracts the column values at execution time.
The returned AssociatedExpression can be:
- Executed directly:
.get().await -> Result<Vec<Type>> - Composed into expressions: used via
Expressivetrait inin_()conditions
let fk_col = source.get_column::<String>("bakery_id").unwrap();
let fk_values = source.data_source().column_table_values_expr(&source, &fk_col);
// Execute: let ids = fk_values.get().await?;
// Or compose: target.add_condition(target["id"].in_((fk_values)));Provided Methods§
Sourcefn eq_condition(field: &str, value: &str) -> Result<Self::Condition>
fn eq_condition(field: &str, value: &str) -> Result<Self::Condition>
Build a textual field == value condition.
Generic UIs (e.g. CLI argument parsers) only have strings on
hand, so they need a way to construct a Self::Condition without
knowing the backend’s native expression type. Backends that
don’t support raw text filtering can leave the default, which
returns an error.
Sourcefn eq_value_condition(
&self,
field: &str,
value: Self::Value,
) -> Result<Self::Condition>
fn eq_value_condition( &self, field: &str, value: Self::Value, ) -> Result<Self::Condition>
Build a field == value condition with a typed Self::Value.
Sibling of TableSource::eq_condition for the case where the caller already
has a native-typed value in hand (e.g. Reference::resolve_from_row
pulling a join value out of a Record<Self::Value>). Avoids going
through string serialization and avoids the Expression → T::Condition
coercion that some document backends only support via a panic stub.
Backends that participate in row-based reference traversal override; the default returns an error so existing impls compile.
Sourcefn coerce_reference_value(&self, value: Self::Value) -> Self::Value
fn coerce_reference_value(&self, value: Self::Value) -> Self::Value
Coerce a reference join value into the backend’s native id form.
Reference traversal (resolve_from_row) reads the join value raw out
of the parent row and uses it for both the narrowing eq-condition and
the target’s insert invariant. On scalar-FK backends any value compares
as-is, so the default is identity. Backends with a richer id type
override: SurrealDB re-tags a "table:key" string — a record id that
round-tripped through JSON or a script — back into a record id, so the
condition renders a record literal (and an inserted child stores a
link), not a quoted string that matches nothing.
Sourcefn stream_table_values<'a, E>(
&'a self,
table: &Table<Self, E>,
) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + 'a>>
fn stream_table_values<'a, E>( &'a self, table: &Table<Self, E>, ) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + 'a>>
Stream all records from a table as (Id, Record) pairs.
Default implementation wraps list_table_values into a stream.
Backends with native streaming (e.g. REST APIs with pagination)
can override this to yield records incrementally.
Build a correlated condition: target_table.target_field = source_table.source_column.
Used by get_subquery_as / get_subquery_erased for embedding correlated
subqueries inside SELECT expressions (e.g.
(SELECT COUNT(*) FROM order WHERE order.client_id = client.id)), and by
the generic implicit-reference lowering. SQL and SurrealDB backends
produce table-qualified equality; backends without correlated subqueries
leave the default (which panics — they must also keep
supports_traversal false).
Sourcefn supports_traversal(&self) -> bool
fn supports_traversal(&self) -> bool
Whether this backend can lower a dotted active column
("country.name") into its own query — a nested correlated subquery for
SQL, a native idiom path for SurrealDB. Backends that can build neither
(e.g. MongoDB, CSV, REST) leave the default false, and
Table::with_active_columns
rejects dotted names against them at build time rather than at fetch time.
Sourcefn traversal_path_expr(
&self,
hops: &[&str],
column: &str,
) -> Option<Expression<Self::Value>>
fn traversal_path_expr( &self, hops: &[&str], column: &str, ) -> Option<Expression<Self::Value>>
Build a backend-native path expression for a dotted active column, tried before the generic correlated-subquery chain.
hops holds each traversed relation’s foreign-key/link field (not
its registry name — a relation named owner over a link field client
must lower to client.…), and column the final field. The default
returns None, so backends fall back to the generic chain built on
related_correlated_condition.
SurrealDB overrides this to emit an idiom path (batch.golf_course.name,
each segment escaped separately); multi-hop comes for free. The returned
expression is unaliased — select() aliases it to the dotted name.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".