Skip to main content

Capability

Struct Capability 

Source
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: bool

When true, the database uses a SQL-based query language and the planner will emit QuerySql operations.

§storage_types: StorageTypes

Column storage types supported by the database.

§schema_mutations: SchemaMutations

What 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: bool

SQL: supports update statements in CTE queries.

§select_for_update: bool

SQL: Supports row-level locking. If false, then the driver is expected to serializable transaction-level isolation.

§returning_from_mutation: bool

SQL: Mysql doesn’t support returning clauses from insert / update queries

§primary_key_ne_predicate: bool

DynamoDB does not support != predicates on the primary key.

§auto_increment: bool

Whether the database has an auto increment modifier for integer columns.

§native_varchar: bool

Whether 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: bool

Whether the database has native support for Timestamp types.

§native_date: bool

Whether the database has native support for Date types.

§native_time: bool

Whether the database has native support for Time types.

§native_datetime: bool

Whether the database has native support for DateTime types.

§native_enum: bool

Whether the database supports native enum types.

  • PostgreSQL: trueCREATE TYPE ... AS ENUM
  • MySQL: true — inline ENUM('a', 'b') column type
  • SQLite: false — uses TEXT + CHECK constraint
  • DynamoDB: false — plain string attribute
§named_enum_types: bool

Whether 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: trueCREATE TYPE <name> AS ENUM (...)
  • MySQL: false — inline ENUM('a', 'b') on the column
  • SQLite: false
  • DynamoDB: false
§native_decimal: bool

Whether the database has native support for Decimal types.

§bigdecimal_implemented: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

The 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: bool

The 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: bool

Whether 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: bool

Whether 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: bool

Whether 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: bool

Whether the driver supports atomic in-place removal of every element equal to a given value from a Vec<scalar> field (stmt::remove).

  • PostgreSQL text[]: truearray_remove(col, v).
  • MySQL / SQLite JSON: false — no value-removal operator.
  • DynamoDB List: false — no value-removal on Lists.
§vec_pop: bool

Whether 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: falseUpdateExpression indices must be literal integers, so the last index cannot be expressed in one statement.
§vec_remove_at: bool

Whether 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

Source

pub const SQLITE: Self

SQLite capabilities.

Source

pub const POSTGRESQL: Self

PostgreSQL capabilities

Source

pub const MYSQL: Self

MySQL capabilities

Source

pub const DYNAMODB: Self

DynamoDB capabilities

Source

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.

Source

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.

Source

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.

Trait Implementations§

Source§

impl Debug for Capability

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> 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, 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.