#[cfg(feature = "libsql")]
mod libsql;
#[cfg(any(feature = "tokio-postgres", feature = "postgres-sync"))]
mod postgres;
#[cfg(feature = "rusqlite")]
mod rusqlite;
#[cfg(any(feature = "rusqlite", feature = "libsql", feature = "turso"))]
pub(crate) mod sqlite_value;
#[cfg(feature = "turso")]
mod turso;
use core::marker::PhantomData;
use crate::error::DrizzleError;
use crate::prelude::{String, Vec};
use crate::{Cons, Nil};
#[derive(Debug, Clone, Copy, Default)]
pub struct SelectStar;
#[derive(Debug, Clone, Copy, Default)]
pub struct SelectCols<Cols>(PhantomData<Cols>);
#[derive(Debug, Clone, Copy, Default)]
pub struct SelectExpr;
#[derive(Debug, Clone, Copy, Default)]
pub struct SelectAs<R>(PhantomData<R>);
#[derive(Debug, Clone, Copy, Default)]
pub struct Scoped<Marker, Scope>(PhantomData<(Marker, Scope)>);
pub trait SelectRequiredTables {
type RequiredTables;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct ScopeHere;
#[derive(Debug, Clone, Copy, Default)]
pub struct ScopeThere<Prev>(PhantomData<Prev>);
pub trait ScopeContains<Table, Witness> {}
impl<Head, Tail> ScopeContains<Head, ScopeHere> for Cons<Head, Tail> {}
impl<Head, Tail, Table, Witness> ScopeContains<Table, ScopeThere<Witness>> for Cons<Head, Tail> where
Tail: ScopeContains<Table, Witness>
{
}
pub trait ScopeSatisfies<Required, Proof> {}
impl<Scope> ScopeSatisfies<Nil, ()> for Scope {}
impl<Scope, Head, Tail, HeadProof, TailProof>
ScopeSatisfies<Cons<Head, Tail>, (HeadProof, TailProof)> for Scope
where
Scope: ScopeContains<Head, HeadProof> + ScopeSatisfies<Tail, TailProof>,
{
}
pub trait MarkerRequiredTables {
type RequiredTables;
}
impl MarkerRequiredTables for SelectStar {
type RequiredTables = Nil;
}
impl<Cols> MarkerRequiredTables for SelectCols<Cols> {
type RequiredTables = Nil;
}
impl MarkerRequiredTables for SelectExpr {
type RequiredTables = Nil;
}
impl<R> MarkerRequiredTables for SelectAs<R>
where
R: SelectRequiredTables,
{
type RequiredTables = R::RequiredTables;
}
#[diagnostic::on_unimplemented(
message = "selected row requires tables not present in the current query scope",
label = "add .join(...) entries for every table referenced by this selector",
note = "for aliased selectors, use the same alias type in #[from(...)] and .from(...)"
)]
pub trait MarkerScopeValidFor<Proof> {}
impl<M, Scope, Proof> MarkerScopeValidFor<Proof> for Scoped<M, Scope>
where
M: MarkerRequiredTables,
Scope: ScopeSatisfies<M::RequiredTables, Proof>,
{
}
#[doc(hidden)]
pub struct ColumnScope<Table, Witness>(PhantomData<(Table, Witness)>);
#[doc(hidden)]
pub struct OpaqueScope;
#[doc(hidden)]
pub struct BinaryScope<Left, Right>(PhantomData<(Left, Right)>);
#[doc(hidden)]
pub struct WrappedScope<Proof>(PhantomData<Proof>);
#[doc(hidden)]
pub trait ProjectionInScope<Scope, Proof> {}
impl<Lhs, Rhs, Op, D, T, N, Scope, LeftProof, RightProof>
ProjectionInScope<Scope, BinaryScope<LeftProof, RightProof>>
for crate::expr::ColumnBinOp<Lhs, Rhs, Op, D, T, N>
where
Lhs: ProjectionInScope<Scope, LeftProof>,
Rhs: ProjectionInScope<Scope, RightProof>,
{
}
impl<T, D, SQLType, Nullable, Scope, Proof> ProjectionInScope<Scope, WrappedScope<Proof>>
for crate::expr::ColumnNeg<T, D, SQLType, Nullable>
where
T: ProjectionInScope<Scope, Proof>,
{
}
impl<E, Scope, Proof> ProjectionInScope<Scope, WrappedScope<Proof>> for crate::expr::AliasedExpr<E> where
E: ProjectionInScope<Scope, Proof>
{
}
impl<E, Name, Scope, Proof> ProjectionInScope<Scope, WrappedScope<Proof>>
for crate::expr::NamedExpr<E, Name>
where
E: ProjectionInScope<Scope, Proof>,
{
}
macro_rules! impl_scope_opaque {
($($ty:ty),+ $(,)?) => {
$(impl<Scope> ProjectionInScope<Scope, OpaqueScope> for $ty {})+
};
}
impl_scope_opaque!(
bool,
i8,
i16,
i32,
i64,
i128,
isize,
u8,
u16,
u32,
u64,
u128,
usize,
f32,
f64,
String,
&str,
Vec<u8>,
&[u8]
);
impl<T, Scope, Proof> ProjectionInScope<Scope, WrappedScope<Proof>> for Option<T> where
T: ProjectionInScope<Scope, Proof>
{
}
impl<T, Scope, Proof> ProjectionInScope<Scope, WrappedScope<Proof>> for &T where
T: ProjectionInScope<Scope, Proof>
{
}
#[doc(hidden)]
pub trait ProjectionsInScope<Scope, Proof> {}
impl<Scope> ProjectionsInScope<Scope, ()> for Nil {}
impl<Head, Tail, Scope, HeadProof, TailProof> ProjectionsInScope<Scope, (HeadProof, TailProof)>
for Cons<Head, Tail>
where
Head: ProjectionInScope<Scope, HeadProof>,
Tail: ProjectionsInScope<Scope, TailProof>,
{
}
pub trait AggStatus {
type Status;
}
impl<E: crate::expr::HasAggStatus> AggStatus for (E,) {
type Status = E::Status;
}
macro_rules! impl_tuple_agg_status {
($E0:ident; $i0:tt) => {};
($E0:ident, $E1:ident; $i0:tt, $i1:tt) => {
impl<$E0, $E1> AggStatus for ($E0, $E1)
where
$E0: crate::expr::HasAggStatus,
$E1: crate::expr::HasAggStatus,
<$E0 as crate::expr::HasAggStatus>::Status:
crate::expr::CombineAggStatus<<$E1 as crate::expr::HasAggStatus>::Status>,
{
type Status = <<$E0 as crate::expr::HasAggStatus>::Status as
crate::expr::CombineAggStatus<<$E1 as crate::expr::HasAggStatus>::Status>>::Output;
}
};
($E0:ident, $E1:ident, $($rest:ident),+; $i0:tt, $i1:tt, $($ri:tt),+) => {
impl<$E0, $E1, $($rest),+> AggStatus for ($E0, $E1, $($rest),+)
where
$E0: crate::expr::HasAggStatus,
($E1, $($rest),+): AggStatus,
<$E0 as crate::expr::HasAggStatus>::Status:
crate::expr::CombineAggStatus<<($E1, $($rest),+) as AggStatus>::Status>,
{
type Status = <<$E0 as crate::expr::HasAggStatus>::Status as
crate::expr::CombineAggStatus<<($E1, $($rest),+) as AggStatus>::Status>>::Output;
}
};
}
with_col_sizes_8!(impl_tuple_agg_status);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_tuple_agg_status);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_32!(impl_tuple_agg_status);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_col_sizes_64!(impl_tuple_agg_status);
#[cfg(any(feature = "col128", feature = "col200"))]
with_col_sizes_128!(impl_tuple_agg_status);
#[cfg(feature = "col200")]
with_col_sizes_200!(impl_tuple_agg_status);
pub trait IntoGroupBy<'a, V: crate::SQLParam + 'a>: crate::ToSQL<'a, V> {
type Columns;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct PkGroup<Table>(PhantomData<Table>);
macro_rules! impl_into_group_by_tuple {
($T0:ident; $i0:tt) => {};
($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {
impl<'a, V: crate::SQLParam + 'a, $T0, $T1> IntoGroupBy<'a, V> for ($T0, $T1)
where
$T0: crate::ToSQL<'a, V>,
$T1: crate::ToSQL<'a, V>,
{
type Columns = Cons<$T0, Cons<$T1, Nil>>;
}
};
($T0:ident, $T1:ident, $($rest:ident),+; $i0:tt, $i1:tt, $($ri:tt),+) => {
impl<'a, V: crate::SQLParam + 'a, $T0, $T1, $($rest),+> IntoGroupBy<'a, V> for ($T0, $T1, $($rest),+)
where
$T0: crate::ToSQL<'a, V>,
$T1: crate::ToSQL<'a, V>,
$($rest: crate::ToSQL<'a, V>,)+
{
type Columns = impl_into_group_by_tuple!(@cons $T0, $T1, $($rest),+);
}
};
(@cons $T:ident) => { Cons<$T, Nil> };
(@cons $T:ident, $($rest:ident),+) => { Cons<$T, impl_into_group_by_tuple!(@cons $($rest),+)> };
}
with_col_sizes_8!(impl_into_group_by_tuple);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_into_group_by_tuple);
#[diagnostic::on_unimplemented(
message = "non-aggregate column in SELECT is not in GROUP BY",
label = "this column must appear in .group_by(...) or be wrapped in an aggregate function",
note = "when using GROUP BY, every non-aggregate column in SELECT must be listed in GROUP BY, \
unless the group key is the column's table primary key (`.group_by(table.pk)`)"
)]
pub trait ScalarColumnsIn<Grouped, Proof> {}
pub struct AggSkip;
pub struct ScalarCheck<W>(core::marker::PhantomData<W>);
pub struct PkDependent;
impl<E, Grouped, Proof> ScalarColumnsIn<Grouped, (Proof,)> for (E,) where
E: SingleColGroupCheck<Grouped, Proof>
{
}
pub trait SingleColGroupCheck<Grouped, Proof> {}
pub trait GroupByIdentity {
type Identity;
}
impl<E: GroupByIdentity> GroupByIdentity for crate::expr::AliasedExpr<E> {
type Identity = E::Identity;
}
impl<V: crate::SQLParam, T, N, A> GroupByIdentity for crate::expr::SQLExpr<'_, V, T, N, A>
where
T: crate::types::DataType,
N: crate::expr::Nullability,
A: crate::expr::AggregateKind,
{
type Identity = Self;
}
impl<Lhs, Rhs, Op, D, SQLType, Nullable> GroupByIdentity
for crate::expr::ColumnBinOp<Lhs, Rhs, Op, D, SQLType, Nullable>
{
type Identity = Self;
}
impl<T, D, SQLType, Nullable> GroupByIdentity for crate::expr::ColumnNeg<T, D, SQLType, Nullable> {
type Identity = Self;
}
impl<E, Grouped> SingleColGroupCheck<Grouped, AggSkip> for E where
E: crate::expr::HasAggStatus<Status = crate::expr::AllAgg>
{
}
impl<E, Grouped, W> SingleColGroupCheck<Grouped, ScalarCheck<W>> for E
where
E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
Grouped: ScopeContains<E::Identity, W>,
{
}
impl<E, T> SingleColGroupCheck<PkGroup<T>, PkDependent> for E
where
E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
E::Identity: crate::traits::ColumnOf<T>,
{
}
impl<T0, T1, Grouped, P0, P1> ScalarColumnsIn<Grouped, (P0, P1)> for (T0, T1)
where
T0: SingleColGroupCheck<Grouped, P0>,
T1: SingleColGroupCheck<Grouped, P1>,
{
}
macro_rules! impl_scalar_columns_in {
($T0:ident; $i0:tt) => {};
($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {};
($T0:ident, $($rest:ident),+; $i0:tt, $($ri:tt),+) => {
impl<$T0, $($rest),+, Grouped, HeadProof, TailProof>
ScalarColumnsIn<Grouped, (HeadProof, TailProof)>
for ($T0, $($rest),+)
where
$T0: SingleColGroupCheck<Grouped, HeadProof>,
($($rest,)+): ScalarColumnsIn<Grouped, TailProof>,
{}
};
}
with_col_sizes_8!(impl_scalar_columns_in);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_scalar_columns_in);
#[diagnostic::on_unimplemented(
message = "non-aggregate column in SELECT is not in GROUP BY",
label = "add this column to .group_by(...) or wrap it in an aggregate function"
)]
pub trait MarkerAggValidFor<Grouped, Proof = ()> {}
impl<Mk> MarkerAggValidFor<()> for Mk {}
impl<Scope, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>> for Scoped<SelectStar, Scope> {}
impl<Scope, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>> for Scoped<SelectExpr, Scope> {}
impl<Scope, R, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>> for Scoped<SelectAs<R>, Scope> {}
impl<Scope, Cols, Head, Tail, Proof> MarkerAggValidFor<Cons<Head, Tail>, Proof>
for Scoped<SelectCols<Cols>, Scope>
where
Cols: ScalarColumnsIn<Cons<Head, Tail>, Proof>,
{
}
impl<Scope, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectStar, Scope> {}
impl<Scope, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectExpr, Scope> {}
impl<Scope, R, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectAs<R>, Scope> {}
impl<Scope, Cols, T, Proof> MarkerAggValidFor<PkGroup<T>, Proof> for Scoped<SelectCols<Cols>, Scope> where
Cols: ScalarColumnsIn<PkGroup<T>, Proof>
{
}
pub trait RowColumnList<Row: ?Sized> {
type Columns: crate::TypeSet;
}
pub trait SelectedColumnList {
type Columns: crate::TypeSet;
}
#[doc(hidden)]
pub trait SelectedExpressionList {
type Expressions: crate::TypeSet;
}
trait SameType<T> {}
impl<T> SameType<T> for T {}
trait ColumnTypeCompatible<Row: ?Sized, Expected, Actual> {}
impl<Row: ?Sized, T> ColumnTypeCompatible<Row, T, T> for () {}
trait TypeListCompatible<Row: ?Sized, ActualList> {}
impl<Row: ?Sized> TypeListCompatible<Row, Self> for crate::Nil {}
impl<Row: ?Sized, EH, ET, AH, AT> TypeListCompatible<Row, crate::Cons<AH, AT>>
for crate::Cons<EH, ET>
where
(): ColumnTypeCompatible<Row, EH, AH>,
ET: TypeListCompatible<Row, AT>,
{
}
trait SqliteDecodeRow {}
#[cfg(feature = "rusqlite")]
impl SqliteDecodeRow for ::rusqlite::Row<'_> {}
#[cfg(feature = "libsql")]
impl SqliteDecodeRow for ::libsql::Row {}
#[cfg(feature = "turso")]
impl SqliteDecodeRow for ::turso::Row {}
macro_rules! impl_sqlite_integer_decode_compat {
($expected:ty => $($actual:ty),+ $(,)?) => {
$(
impl<Row> ColumnTypeCompatible<Row, $expected, $actual> for ()
where
Row: SqliteDecodeRow,
{
}
)+
};
}
impl_sqlite_integer_decode_compat!(
i64 => i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
);
impl_sqlite_integer_decode_compat!(
Option<i64> =>
Option<i8>,
Option<i16>,
Option<i32>,
Option<isize>,
Option<u8>,
Option<u16>,
Option<u32>,
Option<u64>,
Option<usize>,
Option<bool>
);
macro_rules! impl_row_column_list_one {
($($ty:ty),+ $(,)?) => {
$(
impl<Row: ?Sized> RowColumnList<Row> for $ty {
type Columns = crate::Cons<$ty, crate::Nil>;
}
)+
};
}
impl_row_column_list_one!(
i8,
i16,
i32,
i64,
isize,
u8,
u16,
u32,
u64,
usize,
f32,
f64,
bool,
crate::prelude::String,
crate::prelude::Vec<u8>
);
impl<Row: ?Sized> RowColumnList<Row> for () {
type Columns = crate::Cons<(), crate::Nil>;
}
#[cfg(feature = "uuid")]
impl<Row: ?Sized> RowColumnList<Row> for uuid::Uuid {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "chrono")]
impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDate {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "chrono")]
impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveTime {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "chrono")]
impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDateTime {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "chrono")]
impl<Row: ?Sized> RowColumnList<Row> for chrono::DateTime<chrono::Utc> {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "serde")]
impl<Row: ?Sized> RowColumnList<Row> for serde_json::Value {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "rust-decimal")]
impl<Row: ?Sized> RowColumnList<Row> for rust_decimal::Decimal {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "chrono")]
impl<Row: ?Sized> RowColumnList<Row> for chrono::Duration {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "time")]
impl<Row: ?Sized> RowColumnList<Row> for time::Date {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "time")]
impl<Row: ?Sized> RowColumnList<Row> for time::Time {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "time")]
impl<Row: ?Sized> RowColumnList<Row> for time::PrimitiveDateTime {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "time")]
impl<Row: ?Sized> RowColumnList<Row> for time::OffsetDateTime {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "time")]
impl<Row: ?Sized> RowColumnList<Row> for time::Duration {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "jiff")]
impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Date {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "jiff")]
impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Time {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "jiff")]
impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::DateTime {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "jiff")]
impl<Row: ?Sized> RowColumnList<Row> for jiff::Timestamp {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "cidr")]
impl<Row: ?Sized> RowColumnList<Row> for cidr::IpInet {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "cidr")]
impl<Row: ?Sized> RowColumnList<Row> for cidr::IpCidr {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "geo-types")]
impl<Row: ?Sized> RowColumnList<Row> for geo_types::Point<f64> {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "geo-types")]
impl<Row: ?Sized> RowColumnList<Row> for geo_types::LineString<f64> {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "geo-types")]
impl<Row: ?Sized> RowColumnList<Row> for geo_types::Rect<f64> {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "bit-vec")]
impl<Row: ?Sized> RowColumnList<Row> for bit_vec::BitVec {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "arrayvec")]
impl<Row: ?Sized, const N: usize> RowColumnList<Row> for arrayvec::ArrayString<N> {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "arrayvec")]
impl<Row: ?Sized, T, const N: usize> RowColumnList<Row> for arrayvec::ArrayVec<T, N> {
type Columns = crate::Cons<Self, crate::Nil>;
}
impl<Row: ?Sized> RowColumnList<Row> for compact_str::CompactString {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "bytes")]
impl<Row: ?Sized> RowColumnList<Row> for bytes::Bytes {
type Columns = crate::Cons<Self, crate::Nil>;
}
#[cfg(feature = "bytes")]
impl<Row: ?Sized> RowColumnList<Row> for bytes::BytesMut {
type Columns = crate::Cons<Self, crate::Nil>;
}
impl<Row: ?Sized, A: smallvec::Array> RowColumnList<Row> for smallvec::SmallVec<A> {
type Columns = crate::Cons<Self, crate::Nil>;
}
impl<Row: ?Sized, T> RowColumnList<Row> for Option<T> {
type Columns = crate::Cons<Self, crate::Nil>;
}
macro_rules! impl_rcl_body {
([$A:ident] []) => {
impl<Row: ?Sized, $A: RowColumnList<Row>> RowColumnList<Row> for ($A,) {
type Columns = <$A as RowColumnList<Row>>::Columns;
}
};
([$($all:ident),+] [$($prev:ident),+; $last:ident]) => {
impl<Row: ?Sized, $($all),+> RowColumnList<Row> for ($($all,)+)
where
$last: RowColumnList<Row>,
($($prev,)+): RowColumnList<Row>,
<($($prev,)+) as RowColumnList<Row>>::Columns:
crate::Concat<<$last as RowColumnList<Row>>::Columns>,
{
type Columns = <<($($prev,)+) as RowColumnList<Row>>::Columns as crate::Concat<
<$last as RowColumnList<Row>>::Columns,
>>::Output;
}
};
}
macro_rules! impl_rcl_tuple {
($($T:ident),+) => {
impl_rcl_split!([$($T),+] [] $($T),+);
};
}
macro_rules! impl_rcl_split {
([$A:ident] [] $only:ident) => {
impl_rcl_body!([$A] []);
};
([$($all:ident),+] [$($prev:ident),+] $last:ident) => {
impl_rcl_body!([$($all),+] [$($prev),+; $last]);
};
([$($all:ident),+] [] $head:ident, $($rest:ident),+) => {
impl_rcl_split!([$($all),+] [$head] $($rest),+);
};
([$($all:ident),+] [$($prev:ident),+] $head:ident, $($rest:ident),+) => {
impl_rcl_split!([$($all),+] [$($prev),+, $head] $($rest),+);
};
}
with_type_sizes_8!(impl_rcl_tuple);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_type_sizes_16!(impl_rcl_tuple);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_type_sizes_32!(impl_rcl_tuple);
#[diagnostic::on_unimplemented(
message = "selected shape does not match decode target `{Actual}`",
label = "this decode target is not type-compatible with .select(...) output",
note = "use typed expressions or derive FromRow for explicit remapping when selecting custom expressions"
)]
pub trait MarkerColumnCountValid<Row: ?Sized, Inferred, Actual> {}
#[diagnostic::on_unimplemented(
message = "raw select expressions require explicit typing in strict decode",
label = "`select(sql!(...)).all()/get()` is not allowed in strict mode",
note = "use typed wrappers like `raw_non_null`/`raw_nullable` or derive FromRow"
)]
pub trait StrictDecodeMarker {}
impl StrictDecodeMarker for SelectStar {}
impl<Cols> StrictDecodeMarker for SelectCols<Cols> {}
impl<R> StrictDecodeMarker for SelectAs<R> {}
impl<M, Scope> StrictDecodeMarker for Scoped<M, Scope> where M: StrictDecodeMarker {}
impl<Row: ?Sized, Inferred, Actual> MarkerColumnCountValid<Row, Inferred, Actual> for SelectStar {}
impl<Row: ?Sized, Cols, Inferred, Actual> MarkerColumnCountValid<Row, Inferred, Actual>
for SelectCols<Cols>
where
Cols: SelectedColumnList,
Actual: RowColumnList<Row>,
<Cols as SelectedColumnList>::Columns:
TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
{
}
impl<Row: ?Sized, Inferred, Actual> MarkerColumnCountValid<Row, Inferred, Actual> for SelectExpr where
Inferred: SameType<Actual>
{
}
impl<Row: ?Sized, R, Inferred, Actual> MarkerColumnCountValid<Row, Inferred, Actual>
for SelectAs<R>
{
}
impl<M, Scope, Row: ?Sized, Inferred, Actual> MarkerColumnCountValid<Row, Inferred, Actual>
for Scoped<M, Scope>
where
M: MarkerColumnCountValid<Row, Inferred, Actual>,
{
}
pub trait ScopePush<Joined> {
type Out;
}
impl<M, Scope, Joined> ScopePush<Joined> for Scoped<M, Scope> {
type Out = Scoped<M, Cons<Joined, Scope>>;
}
pub trait DecodeSelectedRef<RowRef, R> {
fn decode(row: RowRef) -> Result<R, DrizzleError>;
}
impl<RowRef, R> DecodeSelectedRef<RowRef, R> for SelectAs<R>
where
R: TryFrom<RowRef>,
<R as TryFrom<RowRef>>::Error: Into<DrizzleError>,
{
fn decode(row: RowRef) -> Result<R, DrizzleError> {
R::try_from(row).map_err(Into::into)
}
}
impl<RowRef, R, M, Scope> DecodeSelectedRef<RowRef, R> for Scoped<M, Scope>
where
M: DecodeSelectedRef<RowRef, R>,
{
fn decode(row: RowRef) -> Result<R, DrizzleError> {
M::decode(row)
}
}
impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectStar
where
RowRef: core::ops::Deref<Target = Row>,
R: FromDrizzleRow<Row>,
{
fn decode(row: RowRef) -> Result<R, DrizzleError> {
R::from_row(&*row)
}
}
impl<RowRef, Row: ?Sized, Cols, R> DecodeSelectedRef<RowRef, R> for SelectCols<Cols>
where
RowRef: core::ops::Deref<Target = Row>,
R: FromDrizzleRow<Row>,
{
fn decode(row: RowRef) -> Result<R, DrizzleError> {
R::from_row(&*row)
}
}
impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectExpr
where
RowRef: core::ops::Deref<Target = Row>,
R: FromDrizzleRow<Row>,
{
fn decode(row: RowRef) -> Result<R, DrizzleError> {
R::from_row(&*row)
}
}
#[diagnostic::on_unimplemented(
message = "cannot deserialize `{Self}` from a database row",
label = "this type does not implement FromDrizzleRow",
note = "derive #[SQLiteFromRow], #[PostgresFromRow], or #[MySQLFromRow]"
)]
pub trait FromDrizzleRow<Row: ?Sized>: Sized {
const COLUMN_COUNT: usize;
fn from_row_at(row: &Row, offset: usize) -> Result<Self, DrizzleError>;
fn from_row(row: &Row) -> Result<Self, DrizzleError> {
Self::from_row_at(row, 0)
}
}
pub trait NullProbeRow<Row: ?Sized>: FromDrizzleRow<Row> {
fn is_null_at(row: &Row, offset: usize) -> Result<bool, DrizzleError>;
}
macro_rules! impl_from_drizzle_row_tuple {
($($T:ident),+; $($idx:tt),+) => {
impl<__Row: ?Sized, $($T: FromDrizzleRow<__Row>),+> FromDrizzleRow<__Row> for ($($T,)+) {
const COLUMN_COUNT: usize = 0 $(+ <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT)+;
#[allow(non_snake_case)]
fn from_row_at(
row: &__Row,
offset: usize,
) -> Result<Self, DrizzleError> {
let mut __off = offset;
$(
let $T = <$T as FromDrizzleRow<__Row>>::from_row_at(row, __off)?;
__off += <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT;
)+
Ok(($($T,)+))
}
}
};
}
with_col_sizes_8!(impl_from_drizzle_row_tuple);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_from_drizzle_row_tuple);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_32!(impl_from_drizzle_row_tuple);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_col_sizes_64!(impl_from_drizzle_row_tuple);
#[cfg(any(feature = "col128", feature = "col200"))]
with_col_sizes_128!(impl_from_drizzle_row_tuple);
#[cfg(feature = "col200")]
with_col_sizes_200!(impl_from_drizzle_row_tuple);
#[diagnostic::on_unimplemented(
message = "SQL type `{Self}` has no default Rust mapping for dialect `{D}`",
label = "this SQL type has no default Rust mapping for this dialect",
note = "enable `chrono` for Date/Time/Timestamp/TimestampTz, `uuid` for Uuid, or `serde` for Json/Jsonb"
)]
pub trait SQLTypeToRust<D> {
type RustType;
}
use crate::dialect::{MySQLDialect, PostgresDialect, SQLiteDialect};
impl<D, T> SQLTypeToRust<D> for crate::types::Array<T>
where
T: crate::types::DataType + SQLTypeToRust<D>,
{
type RustType = crate::prelude::Vec<<T as SQLTypeToRust<D>>::RustType>;
}
impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Integer {
type RustType = i64;
}
impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Text {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Real {
type RustType = f64;
}
impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Blob {
type RustType = crate::prelude::Vec<u8>;
}
impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Numeric {
type RustType = f64;
}
impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Any {
type RustType = crate::prelude::String;
}
macro_rules! impl_mysql_sql_type_to_rust {
($rust:ty => $($sql:ty),+ $(,)?) => {
$(
impl SQLTypeToRust<MySQLDialect> for $sql {
type RustType = $rust;
}
)+
};
}
impl_mysql_sql_type_to_rust!(i8 => drizzle_types::mysql::types::TinyInt);
impl_mysql_sql_type_to_rust!(u8 => drizzle_types::mysql::types::TinyIntUnsigned);
impl_mysql_sql_type_to_rust!(i16 => drizzle_types::mysql::types::SmallInt);
impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::SmallIntUnsigned);
impl_mysql_sql_type_to_rust!(i32 =>
drizzle_types::mysql::types::MediumInt,
drizzle_types::mysql::types::Int,
);
impl_mysql_sql_type_to_rust!(u32 =>
drizzle_types::mysql::types::MediumIntUnsigned,
drizzle_types::mysql::types::IntUnsigned,
);
impl_mysql_sql_type_to_rust!(i64 => drizzle_types::mysql::types::BigInt);
impl_mysql_sql_type_to_rust!(u64 => drizzle_types::mysql::types::BigIntUnsigned);
impl_mysql_sql_type_to_rust!(f32 => drizzle_types::mysql::types::Float);
impl_mysql_sql_type_to_rust!(f64 => drizzle_types::mysql::types::Double);
impl_mysql_sql_type_to_rust!(bool => drizzle_types::mysql::types::Boolean);
impl_mysql_sql_type_to_rust!(crate::prelude::String =>
drizzle_types::mysql::types::Char,
drizzle_types::mysql::types::Varchar,
drizzle_types::mysql::types::TinyText,
drizzle_types::mysql::types::Text,
drizzle_types::mysql::types::MediumText,
drizzle_types::mysql::types::LongText,
drizzle_types::mysql::types::Enum,
drizzle_types::mysql::types::Set,
drizzle_types::mysql::types::Any,
);
impl_mysql_sql_type_to_rust!(crate::prelude::Vec<u8> =>
drizzle_types::mysql::types::Binary,
drizzle_types::mysql::types::Varbinary,
drizzle_types::mysql::types::TinyBlob,
drizzle_types::mysql::types::Blob,
drizzle_types::mysql::types::MediumBlob,
drizzle_types::mysql::types::LongBlob,
drizzle_types::mysql::types::Bit,
);
impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::Year);
#[cfg(feature = "rust-decimal")]
impl_mysql_sql_type_to_rust!(rust_decimal::Decimal => drizzle_types::mysql::types::Decimal);
#[cfg(not(feature = "rust-decimal"))]
impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Decimal);
#[cfg(feature = "serde")]
impl_mysql_sql_type_to_rust!(serde_json::Value => drizzle_types::mysql::types::Json);
#[cfg(not(feature = "serde"))]
impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Json);
#[cfg(feature = "chrono")]
impl_mysql_sql_type_to_rust!(chrono::NaiveDate => drizzle_types::mysql::types::Date);
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl_mysql_sql_type_to_rust!(time::Date => drizzle_types::mysql::types::Date);
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl_mysql_sql_type_to_rust!(jiff::civil::Date => drizzle_types::mysql::types::Date);
#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Date);
impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Time);
#[cfg(feature = "chrono")]
impl_mysql_sql_type_to_rust!(chrono::NaiveDateTime => drizzle_types::mysql::types::DateTime);
#[cfg(feature = "chrono")]
impl_mysql_sql_type_to_rust!(chrono::DateTime<chrono::Utc> => drizzle_types::mysql::types::Timestamp);
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl_mysql_sql_type_to_rust!(time::PrimitiveDateTime => drizzle_types::mysql::types::DateTime);
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl_mysql_sql_type_to_rust!(time::OffsetDateTime => drizzle_types::mysql::types::Timestamp);
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl_mysql_sql_type_to_rust!(jiff::civil::DateTime => drizzle_types::mysql::types::DateTime);
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl_mysql_sql_type_to_rust!(jiff::Timestamp => drizzle_types::mysql::types::Timestamp);
#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
impl_mysql_sql_type_to_rust!(crate::prelude::String =>
drizzle_types::mysql::types::DateTime,
drizzle_types::mysql::types::Timestamp,
);
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int2 {
type RustType = i16;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int4 {
type RustType = i32;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int8 {
type RustType = i64;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float4 {
type RustType = f32;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float8 {
type RustType = f64;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Varchar {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Text {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Char {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Bytea {
type RustType = crate::prelude::Vec<u8>;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Boolean {
type RustType = bool;
}
#[cfg(feature = "rust-decimal")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
type RustType = rust_decimal::Decimal;
}
#[cfg(not(feature = "rust-decimal"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Any {
type RustType = crate::prelude::String;
}
#[cfg(feature = "chrono")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
type RustType = chrono::DateTime<chrono::Utc>;
}
#[cfg(feature = "chrono")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
type RustType = chrono::NaiveDateTime;
}
#[cfg(feature = "chrono")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
type RustType = chrono::NaiveDate;
}
#[cfg(feature = "chrono")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
type RustType = chrono::NaiveTime;
}
#[cfg(feature = "chrono")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timetz {
type RustType = chrono::NaiveTime;
}
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
type RustType = time::OffsetDateTime;
}
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
type RustType = time::PrimitiveDateTime;
}
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
type RustType = time::Date;
}
#[cfg(all(not(feature = "chrono"), feature = "time"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
type RustType = time::Time;
}
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
type RustType = jiff::Timestamp;
}
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
type RustType = jiff::civil::DateTime;
}
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
type RustType = jiff::civil::Date;
}
#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
type RustType = jiff::civil::Time;
}
#[cfg(feature = "uuid")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Uuid {
type RustType = uuid::Uuid;
}
#[cfg(feature = "serde")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Json {
type RustType = serde_json::Value;
}
#[cfg(feature = "serde")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Jsonb {
type RustType = serde_json::Value;
}
#[cfg(feature = "chrono")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
type RustType = chrono::Duration;
}
#[cfg(not(feature = "chrono"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
type RustType = crate::prelude::String;
}
#[cfg(feature = "cidr")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
type RustType = cidr::IpInet;
}
#[cfg(not(feature = "cidr"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
type RustType = crate::prelude::String;
}
#[cfg(feature = "cidr")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
type RustType = cidr::IpCidr;
}
#[cfg(not(feature = "cidr"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr8 {
type RustType = crate::prelude::String;
}
#[cfg(feature = "geo-types")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
type RustType = geo_types::Point<f64>;
}
#[cfg(not(feature = "geo-types"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
type RustType = crate::prelude::String;
}
#[cfg(feature = "geo-types")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
type RustType = geo_types::LineString<f64>;
}
#[cfg(not(feature = "geo-types"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
type RustType = crate::prelude::String;
}
#[cfg(feature = "geo-types")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
type RustType = geo_types::Rect<f64>;
}
#[cfg(not(feature = "geo-types"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
type RustType = crate::prelude::String;
}
#[cfg(feature = "bit-vec")]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
type RustType = bit_vec::BitVec;
}
#[cfg(not(feature = "bit-vec"))]
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Line {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineSegment {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Polygon {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Circle {
type RustType = crate::prelude::String;
}
impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Enum {
type RustType = crate::prelude::String;
}
pub trait WrapNullable<T> {
type Output;
}
impl<T> WrapNullable<T> for crate::expr::NonNull {
type Output = T;
}
impl<T> WrapNullable<T> for crate::expr::Null {
type Output = Option<T>;
}
#[diagnostic::on_unimplemented(
message = "cannot infer Rust type for expression `{Self}`",
label = "use typed expressions or derive FromRow to specify the Rust type",
note = "raw SQL and JSON expressions require explicit type annotation"
)]
pub trait ExprValueType {
type ValueType;
}
impl<T: ExprValueType + ?Sized> ExprValueType for &T {
type ValueType = T::ValueType;
}
impl<V: crate::SQLParam, T, N, A> ExprValueType for crate::expr::SQLExpr<'_, V, T, N, A>
where
T: crate::types::DataType + SQLTypeToRust<V::DialectMarker>,
N: crate::expr::Nullability + WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>,
A: crate::expr::AggregateKind,
{
type ValueType = <N as WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>>::Output;
}
impl<V: crate::SQLParam> ExprValueType for crate::sql::SQL<'_, V> {
type ValueType = ();
}
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a drizzle table",
label = "ensure this type was derived with #[SQLiteTable], #[PostgresTable], or #[MySQLTable]"
)]
pub trait HasSelectModel {
type SelectModel;
const COLUMN_COUNT: usize;
}
impl<T: HasSelectModel + ?Sized> HasSelectModel for &T {
type SelectModel = T::SelectModel;
const COLUMN_COUNT: usize = T::COLUMN_COUNT;
}
#[diagnostic::on_unimplemented(
message = "cannot resolve return type for this query",
label = "the selected columns and table do not produce a known row type"
)]
pub trait ResolveRow<Table> {
type Row;
}
impl<T: HasSelectModel> ResolveRow<T> for SelectStar {
type Row = T::SelectModel;
}
impl<T> ResolveRow<T> for SelectExpr {
type Row = ();
}
impl<R, T> ResolveRow<T> for SelectAs<R>
where
R: SelectAsFrom<T>,
{
type Row = R;
}
impl<M, Scope, T> ResolveRow<T> for Scoped<M, Scope>
where
M: ResolveRow<T>,
{
type Row = M::Row;
}
#[diagnostic::on_unimplemented(
message = "row selector `{Self}` cannot be used with table `{Table}`",
label = "the #[from(...)] table does not match .from(...)",
note = "set #[from(TheTable)] to the same table passed to .from(...)"
)]
pub trait SelectAsFrom<Table> {}
macro_rules! impl_resolve_row_cols {
($($T:ident),+; $($idx:tt),+) => {
impl<__Table, $($T: ExprValueType),+> ResolveRow<__Table> for SelectCols<($($T,)+)> {
type Row = ($(<$T as ExprValueType>::ValueType,)+);
}
};
}
with_col_sizes_8!(impl_resolve_row_cols);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_resolve_row_cols);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_32!(impl_resolve_row_cols);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_col_sizes_64!(impl_resolve_row_cols);
#[cfg(any(feature = "col128", feature = "col200"))]
with_col_sizes_128!(impl_resolve_row_cols);
#[cfg(feature = "col200")]
with_col_sizes_200!(impl_resolve_row_cols);
macro_rules! selected_columns_cons {
() => {
crate::Nil
};
($head:ident $(, $tail:ident)*) => {
crate::Cons<<$head as ExprValueType>::ValueType, selected_columns_cons!($($tail),*)>
};
}
macro_rules! selected_expressions_cons {
() => {
crate::Nil
};
($head:ident $(, $tail:ident)*) => {
crate::Cons<$head, selected_expressions_cons!($($tail),*)>
};
}
macro_rules! impl_selected_column_list_tuple {
($($T:ident),+; $($idx:tt),+) => {
impl<$($T: ExprValueType),+> SelectedColumnList for ($($T,)+) {
type Columns = selected_columns_cons!($($T),+);
}
};
}
macro_rules! impl_selected_expression_list_tuple {
($($T:ident),+; $($idx:tt),+) => {
impl<$($T),+> SelectedExpressionList for ($($T,)+) {
type Expressions = selected_expressions_cons!($($T),+);
}
};
}
with_col_sizes_8!(impl_selected_column_list_tuple);
with_col_sizes_8!(impl_selected_expression_list_tuple);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_selected_column_list_tuple);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_selected_expression_list_tuple);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_32!(impl_selected_column_list_tuple);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_32!(impl_selected_expression_list_tuple);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_col_sizes_64!(impl_selected_column_list_tuple);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_col_sizes_64!(impl_selected_expression_list_tuple);
#[cfg(any(feature = "col128", feature = "col200"))]
with_col_sizes_128!(impl_selected_column_list_tuple);
#[cfg(any(feature = "col128", feature = "col200"))]
with_col_sizes_128!(impl_selected_expression_list_tuple);
#[cfg(feature = "col200")]
with_col_sizes_200!(impl_selected_column_list_tuple);
#[cfg(feature = "col200")]
with_col_sizes_200!(impl_selected_expression_list_tuple);
pub trait AfterJoin<CurrentRow, JoinedTable> {
type NewRow;
}
pub trait AfterLeftJoin<CurrentRow, JoinedTable> {
type NewRow;
}
#[doc(hidden)]
pub trait LeftLateralSelection<Proof = ()>: left_lateral_private::Sealed {}
#[doc(hidden)]
pub trait ColumnInScope<Scope, Proof> {}
impl<Column, Scope, Table, Witness> ColumnInScope<Scope, (Table, Witness)> for Column
where
Column: crate::traits::ColumnOf<Table>,
Scope: ScopeContains<Table, Witness>,
{
}
#[doc(hidden)]
pub trait ColumnsInScope<Scope, Proof> {}
impl<Scope> ColumnsInScope<Scope, ()> for Nil {}
impl<Head, Tail, Scope, HeadProof, TailProof> ColumnsInScope<Scope, (HeadProof, TailProof)>
for Cons<Head, Tail>
where
Head: ColumnInScope<Scope, HeadProof>,
Tail: ColumnsInScope<Scope, TailProof>,
{
}
mod left_lateral_private {
pub trait Sealed {}
impl Sealed for super::SelectStar {}
impl<Scope> Sealed for super::Scoped<super::SelectStar, Scope> {}
impl<Columns, Scope> Sealed for super::Scoped<super::SelectCols<Columns>, Scope> {}
impl<Row, Scope> Sealed for super::Scoped<super::SelectAs<Row>, Scope> {}
}
impl LeftLateralSelection for SelectStar {}
impl<Scope> LeftLateralSelection for Scoped<SelectStar, Scope> {}
impl<Columns, Scope, Proof> LeftLateralSelection<Proof> for Scoped<SelectCols<Columns>, Scope>
where
Columns: SelectedExpressionList,
Columns::Expressions: ColumnsInScope<Scope, Proof>,
{
}
impl<Row, Scope, Proof> LeftLateralSelection<Proof> for Scoped<SelectAs<Row>, Scope> where
Self: MarkerScopeValidFor<Proof>
{
}
pub trait AfterRightJoin<CurrentRow, JoinedTable> {
type NewRow;
}
pub trait AfterFullJoin<CurrentRow, JoinedTable> {
type NewRow;
}
impl<R, T: HasSelectModel> AfterJoin<R, T> for SelectStar {
type NewRow = (R, T::SelectModel);
}
impl<R, T: HasSelectModel> AfterLeftJoin<R, T> for SelectStar {
type NewRow = (R, Option<T::SelectModel>);
}
impl<R, T: HasSelectModel> AfterRightJoin<R, T> for SelectStar {
type NewRow = (Option<R>, T::SelectModel);
}
impl<R, T: HasSelectModel> AfterFullJoin<R, T> for SelectStar {
type NewRow = (Option<R>, Option<T::SelectModel>);
}
impl<Cols, R, T> AfterJoin<R, T> for SelectCols<Cols> {
type NewRow = R;
}
impl<Cols, R, T> AfterLeftJoin<R, T> for SelectCols<Cols> {
type NewRow = R;
}
impl<Cols, R, T> AfterRightJoin<R, T> for SelectCols<Cols> {
type NewRow = R;
}
impl<Cols, R, T> AfterFullJoin<R, T> for SelectCols<Cols> {
type NewRow = R;
}
impl<R, T> AfterJoin<R, T> for SelectExpr {
type NewRow = R;
}
impl<R, T> AfterLeftJoin<R, T> for SelectExpr {
type NewRow = R;
}
impl<R, T> AfterRightJoin<R, T> for SelectExpr {
type NewRow = R;
}
impl<R, T> AfterFullJoin<R, T> for SelectExpr {
type NewRow = R;
}
impl<Row, R, T> AfterJoin<R, T> for SelectAs<Row> {
type NewRow = R;
}
impl<Row, R, T> AfterLeftJoin<R, T> for SelectAs<Row> {
type NewRow = R;
}
impl<Row, R, T> AfterRightJoin<R, T> for SelectAs<Row> {
type NewRow = R;
}
impl<Row, R, T> AfterFullJoin<R, T> for SelectAs<Row> {
type NewRow = R;
}
impl<M, Scope, R, T> AfterJoin<R, T> for Scoped<M, Scope>
where
M: AfterJoin<R, T>,
{
type NewRow = M::NewRow;
}
impl<M, Scope, R, T> AfterLeftJoin<R, T> for Scoped<M, Scope>
where
M: AfterLeftJoin<R, T>,
{
type NewRow = M::NewRow;
}
impl<M, Scope, R, T> AfterRightJoin<R, T> for Scoped<M, Scope>
where
M: AfterRightJoin<R, T>,
{
type NewRow = M::NewRow;
}
impl<M, Scope, R, T> AfterFullJoin<R, T> for Scoped<M, Scope>
where
M: AfterFullJoin<R, T>,
{
type NewRow = M::NewRow;
}
#[diagnostic::on_unimplemented(
message = "`{Self}` cannot be used as a select target",
label = "this type does not implement IntoSelectTarget",
note = "implement IntoSelectTarget or use a column, table, or typed expression"
)]
pub trait IntoSelectTarget {
type Marker;
}
impl<T: IntoSelectTarget + ?Sized> IntoSelectTarget for &T {
type Marker = T::Marker;
}
impl IntoSelectTarget for () {
type Marker = SelectStar;
}
impl<V: crate::SQLParam> IntoSelectTarget for crate::sql::SQL<'_, V> {
type Marker = SelectExpr;
}
impl<V: crate::SQLParam, T, N, A> IntoSelectTarget for crate::expr::SQLExpr<'_, V, T, N, A>
where
T: crate::types::DataType,
N: crate::expr::Nullability,
A: crate::expr::AggregateKind,
{
type Marker = SelectCols<(Self,)>;
}
macro_rules! impl_into_select_target_tuple {
($($T:ident),+; $($idx:tt),+) => {
impl<$($T),+> IntoSelectTarget for ($($T,)+) {
type Marker = SelectCols<($($T,)+)>;
}
};
}
with_col_sizes_8!(impl_into_select_target_tuple);
#[cfg(any(
feature = "col16",
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_16!(impl_into_select_target_tuple);
#[cfg(any(
feature = "col32",
feature = "col64",
feature = "col128",
feature = "col200"
))]
with_col_sizes_32!(impl_into_select_target_tuple);
#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
with_col_sizes_64!(impl_into_select_target_tuple);
#[cfg(any(feature = "col128", feature = "col200"))]
with_col_sizes_128!(impl_into_select_target_tuple);
#[cfg(feature = "col200")]
with_col_sizes_200!(impl_into_select_target_tuple);