pub struct Capability {Show 35 fields
pub sql: bool,
pub storage_types: StorageTypes,
pub schema_mutations: SchemaMutations,
pub cte_with_update: bool,
pub select_for_update: bool,
pub returning_from_mutation: bool,
pub primary_key_ne_predicate: bool,
pub auto_increment: bool,
pub native_varchar: bool,
pub native_timestamp: bool,
pub native_date: bool,
pub native_time: bool,
pub native_datetime: bool,
pub native_enum: bool,
pub named_enum_types: bool,
pub native_decimal: bool,
pub bigdecimal_implemented: bool,
pub decimal_arbitrary_precision: bool,
pub index_or_predicate: bool,
pub native_starts_with: bool,
pub native_like: bool,
pub native_ilike: bool,
pub scan: bool,
pub scan_supports_sort: bool,
pub test_connection_pool: bool,
pub transaction_lock_mode: bool,
pub backward_pagination: bool,
pub bind_list_param: bool,
pub predicate_match_any: bool,
pub native_array: bool,
pub vec_scalar: bool,
pub native_array_set_predicates: bool,
pub vec_remove: bool,
pub vec_pop: bool,
pub vec_remove_at: bool,
}Expand description
Describes what a database driver supports.
The query planner reads these flags to decide which Operation
variants to generate. For example, a SQL driver sets sql: true and
receives QuerySql operations, while DynamoDB sets sql: false and
receives key-value operations like GetByKey and QueryPk.
Pre-built configurations are available as associated constants:
SQLITE, POSTGRESQL,
MYSQL, and DYNAMODB.
§Examples
use toasty_core::driver::Capability;
let cap = &Capability::SQLITE;
assert!(cap.sql);
assert!(cap.returning_from_mutation);
assert!(!cap.select_for_update);Fields§
§sql: boolWhen true, the database uses a SQL-based query language and the
planner will emit QuerySql operations.
storage_types: StorageTypesColumn storage types supported by the database.
schema_mutations: SchemaMutationsWhat the database is able to change about its own schema. See
SchemaMutations for the individual fields; the migration
generator branches on them to choose between an in-place
ALTER COLUMN and a table rebuild, and between one combined
alter statement and several single-property ones.
cte_with_update: boolSQL: supports update statements in CTE queries.
select_for_update: boolSQL: Supports row-level locking. If false, then the driver is expected to serializable transaction-level isolation.
returning_from_mutation: boolSQL: Mysql doesn’t support returning clauses from insert / update queries
primary_key_ne_predicate: boolDynamoDB does not support != predicates on the primary key.
auto_increment: boolWhether the database has an auto increment modifier for integer columns.
native_varchar: boolWhether the database supports VARCHAR(n) column types natively.
Must be consistent with StorageTypes::varchar: when true,
varchar must be Some; when false, varchar must be None.
Use Capability::validate to check this invariant.
native_timestamp: boolWhether the database has native support for Timestamp types.
native_date: boolWhether the database has native support for Date types.
native_time: boolWhether the database has native support for Time types.
native_datetime: boolWhether the database has native support for DateTime types.
native_enum: boolWhether the database supports native enum types.
- PostgreSQL:
true—CREATE TYPE ... AS ENUM - MySQL:
true— inlineENUM('a', 'b')column type - SQLite:
false— usesTEXT+CHECKconstraint - DynamoDB:
false— plain string attribute
named_enum_types: boolWhether enum types are standalone named objects requiring separate DDL.
When true, migrations must emit CREATE TYPE / ALTER TYPE for enum
types. When false, enum definitions are inline in column types.
- PostgreSQL:
true—CREATE TYPE <name> AS ENUM (...) - MySQL:
false— inlineENUM('a', 'b')on the column - SQLite:
false - DynamoDB:
false
native_decimal: boolWhether the database has native support for Decimal types.
bigdecimal_implemented: boolWhether BigDecimal driver support is implemented. TODO: Remove this flag when PostgreSQL BigDecimal support is implemented. Currently only MySQL has implemented BigDecimal driver support.
decimal_arbitrary_precision: boolWhether the database’s decimal type supports arbitrary precision. When false, the decimal type requires fixed precision and scale to be specified upfront.
- PostgreSQL: true (NUMERIC supports arbitrary precision)
- MySQL: false (DECIMAL requires fixed precision/scale)
- SQLite/DynamoDB: false (no native decimal support, stored as TEXT)
index_or_predicate: boolWhether OR is supported in index key conditions (e.g. DynamoDB KeyConditionExpression). DynamoDB: false. All other backends: true (SQL backends never use index key conditions).
native_starts_with: boolWhether the database has a native prefix-match operator that does not
require LIKE-style escaping. When true, starts_with is left in the
AST and the driver renders it natively (DynamoDB’s begins_with(),
PostgreSQL’s ^@). When false, the lowering rewrites it to a
LIKE expression — which requires native_like to be true.
native_like: boolWhether the database has a native LIKE expression. When false,
Expr::Like cannot be sent to the driver; starts_with lowering
will not produce one.
native_ilike: boolWhether the database has a native case-insensitive LIKE operator
(ILIKE). Only PostgreSQL has one.
Toasty does not emulate ILIKE on backends that lack it: .ilike()
is a pass-through to the database’s own operator. When native_ilike
is false, the query-verify pass rejects a case-insensitive
Expr::Like with an
unsupported_feature error rather
than silently degrading to plain LIKE, whose case behavior differs.
Implies native_like.
scan: boolWhether the driver can answer queries that don’t match any primary key or index — i.e. supports unindexed full-table reads.
SQL drivers set this to true: unindexed queries go through
QuerySql, so the SQL engine handles
them transparently. DynamoDB also sets this to true; the planner
emits Operation::Scan for the unindexed
case. A hypothetical pure key-value store with no full-scan capability
would set this to false.
scan_supports_sort: boolWhether scan operations support ordering results.
SQL drivers do not use Operation::Scan, so this is true for them
(ordering is handled inside QuerySql). DynamoDB’s Scan API returns
items in an arbitrary order with no server-side sort, so this is false
for DynamoDB. When false, the planner rejects queries that combine a
scan path with ORDER BY.
test_connection_pool: boolWhether to test connection pool behavior.
TODO: We only need this for the connection_per_clone.rs test, come up with a better way.
transaction_lock_mode: boolWhether the driver honors non-Default
TransactionMode variants
(Immediate, Exclusive). Currently true only for SQLite, which
maps them to BEGIN IMMEDIATE / BEGIN EXCLUSIVE. Drivers that
leave this false reject non-Default modes with
Error::unsupported_feature.
backward_pagination: boolWhether the backend can walk a paginated query in reverse from a cursor.
Gates the prev_cursor field on a Page returned to user code.
When true, the executor extracts a previous-page cursor from the
first row of every page (see apply_sql_pagination in
toasty/src/engine/exec/exec_statement.rs). When false, the
executor leaves prev_cursor as None, so
Page::has_prev() returns false and Page::prev(&db) resolves
to Ok(None) without issuing a query. Paginate::before(cursor)
itself is not rejected — users who already hold a cursor can walk
backwards explicitly — but a driver that returns false is
declaring that it has no way to produce such a cursor.
Drivers should set this to true when the backend can answer a
query equivalent to “rows ordered by K, descending from K = c,
limited to N” — i.e. the same ORDER BY clause reversed plus a
strict inequality on the cursor key. SQL backends meet this
trivially. DynamoDB does not: a Query with ScanIndexForward = false returns rows in the opposite direction but cannot be
rooted at an arbitrary client-supplied cursor without an extra
KeyConditionExpression, and Scan has no order guarantee at
all.
bind_list_param: boolThe driver’s bind layer accepts a single parameter whose value is
Value::List(items) and type is Type::List(elem), sending it as
one protocol-level parameter (not N separate scalars).
Property of the driver bind impl, not the SQL dialect.
predicate_match_any: boolThe SQL dialect parses expr <op> ANY(<array>) and expr <op> ALL(<array>)
as predicates against an array-valued operand.
Property of the dialect, not the bind layer.
native_array: boolWhether the database can store a Vec<scalar> model field as a native
array column (e.g. PostgreSQL text[], int8[]).
When true, schema build maps Type::List(elem) to db::Type::List(elem)
and the driver’s bind layer accepts Value::List(items) as a single
array-valued parameter.
When false, Vec<T> model fields use whatever fallback the backend
provides (JSON column on MySQL/SQLite, native List L on DynamoDB).
See Self::vec_scalar for the schema-build gate.
vec_scalar: boolWhether the driver supports Vec<scalar> model fields, by whatever
representation (native typed array column, JSON column, key-value
list attribute, …). Used by the schema builder as the gate for
accepting stmt::Type::List(_) fields.
native_array_set_predicates: boolWhether the driver natively renders IsSuperset / Intersects array
predicates over an arbitrary right-hand-side expression.
SQL drivers set this to true: each dialect has a single operator
(@> on PostgreSQL, JSON_CONTAINS on MySQL, a json_each
subquery on SQLite) that takes the rhs as a bound expression
regardless of its shape.
DynamoDB sets this to false: it has no equivalent operator and
emulates the predicates by emitting one contains(path, vN) clause
per rhs element, which requires the rhs to be a concrete list of
values at filter-construction time. The capability check rejects
any other rhs shape before the driver is invoked.
vec_remove: boolWhether the driver supports atomic in-place removal of every element
equal to a given value from a Vec<scalar> field (stmt::remove).
- PostgreSQL
text[]:true—array_remove(col, v). - MySQL / SQLite JSON:
false— no value-removal operator. - DynamoDB List:
false— no value-removal on Lists.
vec_pop: boolWhether the driver supports atomic in-place removal of the last
element of a Vec<scalar> field (stmt::pop).
- PostgreSQL:
true— array slicing. - MySQL / SQLite:
false. - DynamoDB:
false—UpdateExpressionindices must be literal integers, so the last index cannot be expressed in one statement.
vec_remove_at: boolWhether the driver supports atomic in-place removal of an element at a
given index from a Vec<scalar> field (stmt::remove_at).
- PostgreSQL:
true— array slicing. - MySQL / SQLite:
false. - DynamoDB:
false.
Implementations§
Source§impl Capability
impl Capability
Sourcepub const POSTGRESQL: Self
pub const POSTGRESQL: Self
PostgreSQL capabilities
Sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Validates the consistency of the capability configuration.
This performs sanity checks to ensure the capability fields are
internally consistent. For example, if native_varchar is true,
then storage_types.varchar must be Some, and vice versa.
Returns an error if any inconsistencies are found.
Sourcepub fn default_string_max_length(&self) -> Option<u64>
pub fn default_string_max_length(&self) -> Option<u64>
Returns the default string length limit for this database.
This is useful for tests and applications that need to respect database-specific string length constraints.
Sourcepub fn native_type_for(&self, ty: &Type) -> Type
pub fn native_type_for(&self, ty: &Type) -> Type
Returns the native database type for an application-level type.
If the database supports the type natively, returns the same type. Otherwise, returns the bridge/storage type that the application type maps to in this database.
This uses the existing db::Type::bridge_type() method to determine
the appropriate bridge type based on the database’s storage capabilities.