1#[cfg(feature = "libsql")]
33mod libsql;
34#[cfg(any(feature = "tokio-postgres", feature = "postgres-sync"))]
35mod postgres;
36#[cfg(feature = "rusqlite")]
37mod rusqlite;
38#[cfg(any(feature = "rusqlite", feature = "libsql", feature = "turso"))]
42pub(crate) mod sqlite_value;
43#[cfg(feature = "turso")]
44mod turso;
45
46use core::marker::PhantomData;
47
48use crate::error::DrizzleError;
49use crate::{Cons, Nil};
50
51#[derive(Debug, Clone, Copy, Default)]
58pub struct SelectStar;
59
60#[derive(Debug, Clone, Copy, Default)]
63pub struct SelectCols<Cols>(PhantomData<Cols>);
64
65#[derive(Debug, Clone, Copy, Default)]
68pub struct SelectExpr;
69
70#[derive(Debug, Clone, Copy, Default)]
73pub struct SelectAs<R>(PhantomData<R>);
74
75pub use crate::scope::{
76 HasScope, OuterJoined, ScopeContains, ScopeEntry, ScopeHere, ScopeThere, Scoped,
77};
78
79pub trait MarkerScopeValidFor<Proof> {}
153
154impl<Scope, Used, Proof> MarkerScopeValidFor<Proof> for Scoped<SelectStar, Scope, Used> where
155 Used: SourcesIn<Nil, Proof>
156{
157}
158
159impl<Scope, Used, Proof> MarkerScopeValidFor<Proof> for Scoped<SelectExpr, Scope, Used> where
160 Used: SourcesIn<Nil, Proof>
161{
162}
163
164impl<R, Scope, Used, UsedProof, FieldsProof> MarkerScopeValidFor<(UsedProof, FieldsProof)>
165 for Scoped<SelectAs<R>, Scope, Used>
166where
167 Used: SourcesIn<Nil, UsedProof>,
168 R: SelectTableFields,
169 R::TableFields: TableFieldsIn<Scope, FieldsProof>,
170{
171}
172
173impl<Cols, Scope, Used, UsedProof, ColsProof> MarkerScopeValidFor<(UsedProof, ColsProof)>
174 for Scoped<SelectCols<Cols>, Scope, Used>
175where
176 Used: SourcesIn<Nil, UsedProof>,
177 Cols: SelectedExpressionList,
178 Cols::Expressions: ProjectionIn<Scope, ColsProof>,
179{
180}
181
182use crate::scope::SourcesIn;
183
184#[doc(hidden)]
191#[derive(Debug, Clone, Copy, Default)]
192pub struct MaybeNull<T>(PhantomData<T>);
193
194#[doc(hidden)]
199pub trait ProjectionIn<Scope, Proof> {
200 type Columns: crate::TypeSet;
202}
203
204impl<Scope> ProjectionIn<Scope, ()> for Nil {
205 type Columns = Self;
206}
207
208impl<Head, Tail, Scope, HeadProof, TailProof> ProjectionIn<Scope, (HeadProof, TailProof)>
209 for Cons<Head, Tail>
210where
211 Head: crate::expr::ExprSources + ExprValueType,
212 Head::Sources: SourcesIn<Scope, HeadProof>,
213 Tail: ProjectionIn<Scope, TailProof>,
214{
215 type Columns = Cons<
216 <<Head::Sources as SourcesIn<Scope, HeadProof>>::Nullable as crate::expr::Nullability>::Decoded<
217 Head::ValueType,
218 >,
219 Tail::Columns,
220 >;
221}
222
223pub trait SelectTableFields {
230 type TableFields;
232}
233
234#[derive(Debug, Clone, Copy, Default)]
236pub struct TableFields<Source, Fields>(PhantomData<(Source, Fields)>);
237
238#[doc(hidden)]
242#[diagnostic::on_unimplemented(
243 message = "a field read from the nullable side of an outer join must be an `Option`",
244 label = "LEFT/RIGHT/FULL JOIN can return NULL for every column of this table",
245 note = "change the field type to `Option<_>`, or use an inner join"
246)]
247pub trait FieldsAcceptNullability<Nullable> {}
248
249impl<Fields> FieldsAcceptNullability<crate::expr::NonNull> for Fields {}
250
251impl FieldsAcceptNullability<crate::expr::Null> for Nil {}
252
253impl<T, Tail> FieldsAcceptNullability<crate::expr::Null> for Cons<Option<T>, Tail> where
254 Tail: FieldsAcceptNullability<crate::expr::Null>
255{
256}
257
258#[doc(hidden)]
260pub trait TableFieldsIn<Scope, Proof> {}
261
262impl<Scope> TableFieldsIn<Scope, ()> for Nil {}
263
264impl<Source, Fields, Tail, Scope, Witness, TailProof> TableFieldsIn<Scope, (Witness, TailProof)>
265 for Cons<TableFields<Source, Fields>, Tail>
266where
267 Source: ScopeEntry,
268 Scope: ScopeContains<Source::Key, Witness>,
269 Fields: FieldsAcceptNullability<<Scope as ScopeContains<Source::Key, Witness>>::Nullable>,
270 Tail: TableFieldsIn<Scope, TailProof>,
271{
272}
273
274pub trait AggStatus {
283 type Status;
285}
286
287impl<E: crate::expr::HasAggStatus> AggStatus for (E,) {
289 type Status = E::Status;
290}
291
292macro_rules! impl_tuple_agg_status {
297 ($E0:ident; $i0:tt) => {};
299 ($E0:ident, $E1:ident; $i0:tt, $i1:tt) => {
301 impl<$E0, $E1> AggStatus for ($E0, $E1)
302 where
303 $E0: crate::expr::HasAggStatus,
304 $E1: crate::expr::HasAggStatus,
305 <$E0 as crate::expr::HasAggStatus>::Status:
306 crate::expr::CombineAggStatus<<$E1 as crate::expr::HasAggStatus>::Status>,
307 {
308 type Status = <<$E0 as crate::expr::HasAggStatus>::Status as
309 crate::expr::CombineAggStatus<<$E1 as crate::expr::HasAggStatus>::Status>>::Output;
310 }
311 };
312 ($E0:ident, $E1:ident, $($rest:ident),+; $i0:tt, $i1:tt, $($ri:tt),+) => {
314 impl<$E0, $E1, $($rest),+> AggStatus for ($E0, $E1, $($rest),+)
315 where
316 $E0: crate::expr::HasAggStatus,
317 ($E1, $($rest),+): AggStatus,
318 <$E0 as crate::expr::HasAggStatus>::Status:
319 crate::expr::CombineAggStatus<<($E1, $($rest),+) as AggStatus>::Status>,
320 {
321 type Status = <<$E0 as crate::expr::HasAggStatus>::Status as
322 crate::expr::CombineAggStatus<<($E1, $($rest),+) as AggStatus>::Status>>::Output;
323 }
324 };
325}
326
327with_col_sizes_8!(impl_tuple_agg_status);
328
329#[cfg(any(
330 feature = "col16",
331 feature = "col32",
332 feature = "col64",
333 feature = "col128",
334 feature = "col200"
335))]
336with_col_sizes_16!(impl_tuple_agg_status);
337
338#[cfg(any(
339 feature = "col32",
340 feature = "col64",
341 feature = "col128",
342 feature = "col200"
343))]
344with_col_sizes_32!(impl_tuple_agg_status);
345
346#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
347with_col_sizes_64!(impl_tuple_agg_status);
348
349#[cfg(any(feature = "col128", feature = "col200"))]
350with_col_sizes_128!(impl_tuple_agg_status);
351
352#[cfg(feature = "col200")]
353with_col_sizes_200!(impl_tuple_agg_status);
354
355pub trait IntoGroupBy<'a, V: crate::SQLParam + 'a>:
366 crate::ToSQL<'a, V> + crate::expr::ExprSources
367{
368 type Columns;
371}
372
373#[derive(Debug, Clone, Copy, Default)]
388pub struct PkGroup<Table>(PhantomData<Table>);
389
390macro_rules! impl_into_group_by_tuple {
392 ($T0:ident; $i0:tt) => {};
394 ($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {
396 impl<'a, V: crate::SQLParam + 'a, $T0, $T1> IntoGroupBy<'a, V> for ($T0, $T1)
397 where
398 $T0: crate::ToSQL<'a, V> + crate::expr::ExprSources,
399 $T1: crate::ToSQL<'a, V> + crate::expr::ExprSources,
400 {
401 type Columns = Cons<$T0, Cons<$T1, Nil>>;
402 }
403 };
404 ($T0:ident, $T1:ident, $($rest:ident),+; $i0:tt, $i1:tt, $($ri:tt),+) => {
406 impl<'a, V: crate::SQLParam + 'a, $T0, $T1, $($rest),+> IntoGroupBy<'a, V> for ($T0, $T1, $($rest),+)
407 where
408 $T0: crate::ToSQL<'a, V> + crate::expr::ExprSources,
409 $T1: crate::ToSQL<'a, V> + crate::expr::ExprSources,
410 $($rest: crate::ToSQL<'a, V> + crate::expr::ExprSources,)+
411 {
412 type Columns = impl_into_group_by_tuple!(@cons $T0, $T1, $($rest),+);
413 }
414 };
415 (@cons $T:ident) => { Cons<$T, Nil> };
417 (@cons $T:ident, $($rest:ident),+) => { Cons<$T, impl_into_group_by_tuple!(@cons $($rest),+)> };
418}
419
420with_col_sizes_8!(impl_into_group_by_tuple);
421
422#[cfg(any(
423 feature = "col16",
424 feature = "col32",
425 feature = "col64",
426 feature = "col128",
427 feature = "col200"
428))]
429with_col_sizes_16!(impl_into_group_by_tuple);
430
431#[diagnostic::on_unimplemented(
441 message = "non-aggregate column in SELECT is not in GROUP BY",
442 label = "this column must appear in .group_by(...) or be wrapped in an aggregate function",
443 note = "when using GROUP BY, every non-aggregate column in SELECT must be listed in GROUP BY, \
444 unless the group key is the column's table primary key (`.group_by(table.pk)`)"
445)]
446pub trait ScalarColumnsIn<Grouped, Proof> {}
447
448pub struct AggSkip;
450
451pub struct ScalarCheck<W>(core::marker::PhantomData<W>);
454
455pub struct PkDependent;
458
459impl<E, Grouped, Proof> ScalarColumnsIn<Grouped, (Proof,)> for (E,) where
461 E: SingleColGroupCheck<Grouped, Proof>
462{
463}
464
465pub trait SingleColGroupCheck<Grouped, Proof> {}
468
469pub trait GroupByIdentity {
474 type Identity;
476}
477
478impl<E: GroupByIdentity> GroupByIdentity for crate::expr::AliasedExpr<E> {
483 type Identity = E::Identity;
484}
485
486impl<V: crate::SQLParam, T, N, A, S> GroupByIdentity for crate::expr::SQLExpr<'_, V, T, N, A, S>
488where
489 T: crate::types::DataType,
490 N: crate::expr::Nullability,
491 A: crate::expr::AggregateKind,
492{
493 type Identity = Self;
494}
495
496impl<Lhs, Rhs, Op, D, SQLType, Nullable> GroupByIdentity
498 for crate::expr::ColumnBinOp<Lhs, Rhs, Op, D, SQLType, Nullable>
499{
500 type Identity = Self;
501}
502
503impl<T, D, SQLType, Nullable> GroupByIdentity for crate::expr::ColumnNeg<T, D, SQLType, Nullable> {
505 type Identity = Self;
506}
507
508impl<E, Grouped> SingleColGroupCheck<Grouped, AggSkip> for E where
510 E: crate::expr::HasAggStatus<Status = crate::expr::AllAgg>
511{
512}
513
514impl<E, Grouped, W> SingleColGroupCheck<Grouped, ScalarCheck<W>> for E
516where
517 E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
518 Grouped: crate::scope::ListContains<E::Identity, W>,
519{
520}
521
522impl<E, T> SingleColGroupCheck<PkGroup<T>, PkDependent> for E
527where
528 E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
529 E::Identity: crate::traits::ColumnOf<T>,
530{
531}
532
533impl<T0, T1, Grouped, P0, P1> ScalarColumnsIn<Grouped, (P0, P1)> for (T0, T1)
538where
539 T0: SingleColGroupCheck<Grouped, P0>,
540 T1: SingleColGroupCheck<Grouped, P1>,
541{
542}
543
544macro_rules! impl_scalar_columns_in {
546 ($T0:ident; $i0:tt) => {};
548 ($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {};
550 ($T0:ident, $($rest:ident),+; $i0:tt, $($ri:tt),+) => {
552 impl<$T0, $($rest),+, Grouped, HeadProof, TailProof>
553 ScalarColumnsIn<Grouped, (HeadProof, TailProof)>
554 for ($T0, $($rest),+)
555 where
556 $T0: SingleColGroupCheck<Grouped, HeadProof>,
557 ($($rest,)+): ScalarColumnsIn<Grouped, TailProof>,
558 {}
559 };
560}
561
562with_col_sizes_8!(impl_scalar_columns_in);
563
564#[cfg(any(
565 feature = "col16",
566 feature = "col32",
567 feature = "col64",
568 feature = "col128",
569 feature = "col200"
570))]
571with_col_sizes_16!(impl_scalar_columns_in);
572
573#[diagnostic::on_unimplemented(
588 message = "non-aggregate column in SELECT is not in GROUP BY",
589 label = "add this column to .group_by(...) or wrap it in an aggregate function"
590)]
591pub trait MarkerAggValidFor<Grouped, Proof = ()> {}
592
593impl<Mk> MarkerAggValidFor<()> for Mk {}
595
596impl<Scope, Used, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
598 for Scoped<SelectStar, Scope, Used>
599{
600}
601
602impl<Scope, Used, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
604 for Scoped<SelectExpr, Scope, Used>
605{
606}
607
608impl<Scope, Used, R, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
610 for Scoped<SelectAs<R>, Scope, Used>
611{
612}
613
614impl<Scope, Used, Cols, Head, Tail, Proof> MarkerAggValidFor<Cons<Head, Tail>, Proof>
616 for Scoped<SelectCols<Cols>, Scope, Used>
617where
618 Cols: ScalarColumnsIn<Cons<Head, Tail>, Proof>,
619{
620}
621
622impl<Scope, Used, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectStar, Scope, Used> {}
626
627impl<Scope, Used, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectExpr, Scope, Used> {}
628
629impl<Scope, Used, R, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectAs<R>, Scope, Used> {}
630
631impl<Scope, Used, Cols, T, Proof> MarkerAggValidFor<PkGroup<T>, Proof>
632 for Scoped<SelectCols<Cols>, Scope, Used>
633where
634 Cols: ScalarColumnsIn<PkGroup<T>, Proof>,
635{
636}
637
638pub trait RowColumnList<Row: ?Sized> {
647 type Columns: crate::TypeSet;
649}
650
651pub trait SelectedColumnList {
653 type Columns: crate::TypeSet;
655}
656
657#[doc(hidden)]
663pub trait SelectedExpressionList {
664 type Expressions: crate::TypeSet;
665}
666
667trait SameType<T> {}
668impl<T> SameType<T> for T {}
669
670#[diagnostic::on_unimplemented(
671 message = "selected column decodes as `{Expected}`, but the decode target uses `{Actual}`",
672 label = "the decode target does not match the selected columns",
673 note = "a selected `MaybeNull<T>` can be NULL (an outer join or a nullable operand) \
674 and must be decoded as `Option<T>`"
675)]
676trait ColumnTypeCompatible<Row: ?Sized, Expected, Actual> {}
677
678impl<Row: ?Sized, T> ColumnTypeCompatible<Row, T, T> for () {}
679
680impl<Row: ?Sized, Expected, Actual> ColumnTypeCompatible<Row, MaybeNull<Expected>, Option<Actual>>
684 for ()
685where
686 (): MaybeNullCompatible<Row, Expected, Actual>,
687{
688}
689
690trait MaybeNullCompatible<Row: ?Sized, Expected, Actual> {}
693
694impl<Row: ?Sized, T> MaybeNullCompatible<Row, T, T> for () {}
695
696impl<Row: ?Sized, T> MaybeNullCompatible<Row, Option<T>, T> for () {}
697
698trait TypeListCompatible<Row: ?Sized, ActualList> {}
699
700impl<Row: ?Sized> TypeListCompatible<Row, Self> for crate::Nil {}
701
702impl<Row: ?Sized, EH, ET, AH, AT> TypeListCompatible<Row, crate::Cons<AH, AT>>
703 for crate::Cons<EH, ET>
704where
705 (): ColumnTypeCompatible<Row, EH, AH>,
706 ET: TypeListCompatible<Row, AT>,
707{
708}
709
710trait SqliteDecodeRow {}
711
712#[cfg(feature = "rusqlite")]
713impl SqliteDecodeRow for ::rusqlite::Row<'_> {}
714
715#[cfg(feature = "libsql")]
716impl SqliteDecodeRow for ::libsql::Row {}
717
718#[cfg(feature = "turso")]
719impl SqliteDecodeRow for ::turso::Row {}
720
721macro_rules! impl_sqlite_integer_decode_compat {
722 ($expected:ty => $($actual:ty),+ $(,)?) => {
723 $(
724 impl<Row> ColumnTypeCompatible<Row, $expected, $actual> for ()
725 where
726 Row: SqliteDecodeRow,
727 {
728 }
729 )+
730 };
731}
732
733impl_sqlite_integer_decode_compat!(
734 i64 => i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
735);
736
737macro_rules! impl_sqlite_join_nullable_integer_decode_compat {
738 ($($actual:ty),+ $(,)?) => {
739 $(
740 impl<Row> MaybeNullCompatible<Row, i64, $actual> for ()
741 where
742 Row: SqliteDecodeRow,
743 {
744 }
745
746 impl<Row> MaybeNullCompatible<Row, Option<i64>, $actual> for ()
747 where
748 Row: SqliteDecodeRow,
749 {
750 }
751 )+
752 };
753}
754
755impl_sqlite_join_nullable_integer_decode_compat!(
756 i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
757);
758
759impl_sqlite_integer_decode_compat!(
760 Option<i64> =>
761 Option<i8>,
762 Option<i16>,
763 Option<i32>,
764 Option<isize>,
765 Option<u8>,
766 Option<u16>,
767 Option<u32>,
768 Option<u64>,
769 Option<usize>,
770 Option<bool>
771);
772
773macro_rules! impl_row_column_list_one {
774 ($($ty:ty),+ $(,)?) => {
775 $(
776 impl<Row: ?Sized> RowColumnList<Row> for $ty {
777 type Columns = crate::Cons<$ty, crate::Nil>;
778 }
779 )+
780 };
781}
782
783impl_row_column_list_one!(
784 i8,
785 i16,
786 i32,
787 i64,
788 isize,
789 u8,
790 u16,
791 u32,
792 u64,
793 usize,
794 f32,
795 f64,
796 bool,
797 crate::prelude::String,
798 crate::prelude::Vec<u8>
799);
800
801impl<Row: ?Sized> RowColumnList<Row> for () {
802 type Columns = crate::Cons<(), crate::Nil>;
803}
804
805#[cfg(feature = "uuid")]
806impl<Row: ?Sized> RowColumnList<Row> for uuid::Uuid {
807 type Columns = crate::Cons<Self, crate::Nil>;
808}
809
810#[cfg(feature = "chrono")]
811impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDate {
812 type Columns = crate::Cons<Self, crate::Nil>;
813}
814
815#[cfg(feature = "chrono")]
816impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveTime {
817 type Columns = crate::Cons<Self, crate::Nil>;
818}
819
820#[cfg(feature = "chrono")]
821impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDateTime {
822 type Columns = crate::Cons<Self, crate::Nil>;
823}
824
825#[cfg(feature = "chrono")]
826impl<Row: ?Sized> RowColumnList<Row> for chrono::DateTime<chrono::Utc> {
827 type Columns = crate::Cons<Self, crate::Nil>;
828}
829
830#[cfg(feature = "serde")]
831impl<Row: ?Sized> RowColumnList<Row> for serde_json::Value {
832 type Columns = crate::Cons<Self, crate::Nil>;
833}
834
835#[cfg(feature = "rust-decimal")]
836impl<Row: ?Sized> RowColumnList<Row> for rust_decimal::Decimal {
837 type Columns = crate::Cons<Self, crate::Nil>;
838}
839
840#[cfg(feature = "chrono")]
841impl<Row: ?Sized> RowColumnList<Row> for chrono::Duration {
842 type Columns = crate::Cons<Self, crate::Nil>;
843}
844
845#[cfg(feature = "time")]
846impl<Row: ?Sized> RowColumnList<Row> for time::Date {
847 type Columns = crate::Cons<Self, crate::Nil>;
848}
849
850#[cfg(feature = "time")]
851impl<Row: ?Sized> RowColumnList<Row> for time::Time {
852 type Columns = crate::Cons<Self, crate::Nil>;
853}
854
855#[cfg(feature = "time")]
856impl<Row: ?Sized> RowColumnList<Row> for time::PrimitiveDateTime {
857 type Columns = crate::Cons<Self, crate::Nil>;
858}
859
860#[cfg(feature = "time")]
861impl<Row: ?Sized> RowColumnList<Row> for time::OffsetDateTime {
862 type Columns = crate::Cons<Self, crate::Nil>;
863}
864
865#[cfg(feature = "time")]
866impl<Row: ?Sized> RowColumnList<Row> for time::Duration {
867 type Columns = crate::Cons<Self, crate::Nil>;
868}
869
870#[cfg(feature = "jiff")]
871impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Date {
872 type Columns = crate::Cons<Self, crate::Nil>;
873}
874
875#[cfg(feature = "jiff")]
876impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Time {
877 type Columns = crate::Cons<Self, crate::Nil>;
878}
879
880#[cfg(feature = "jiff")]
881impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::DateTime {
882 type Columns = crate::Cons<Self, crate::Nil>;
883}
884
885#[cfg(feature = "jiff")]
886impl<Row: ?Sized> RowColumnList<Row> for jiff::Timestamp {
887 type Columns = crate::Cons<Self, crate::Nil>;
888}
889
890#[cfg(feature = "cidr")]
891impl<Row: ?Sized> RowColumnList<Row> for cidr::IpInet {
892 type Columns = crate::Cons<Self, crate::Nil>;
893}
894
895#[cfg(feature = "cidr")]
896impl<Row: ?Sized> RowColumnList<Row> for cidr::IpCidr {
897 type Columns = crate::Cons<Self, crate::Nil>;
898}
899
900#[cfg(feature = "geo-types")]
901impl<Row: ?Sized> RowColumnList<Row> for geo_types::Point<f64> {
902 type Columns = crate::Cons<Self, crate::Nil>;
903}
904
905#[cfg(feature = "geo-types")]
906impl<Row: ?Sized> RowColumnList<Row> for geo_types::LineString<f64> {
907 type Columns = crate::Cons<Self, crate::Nil>;
908}
909
910#[cfg(feature = "geo-types")]
911impl<Row: ?Sized> RowColumnList<Row> for geo_types::Rect<f64> {
912 type Columns = crate::Cons<Self, crate::Nil>;
913}
914
915#[cfg(feature = "bit-vec")]
916impl<Row: ?Sized> RowColumnList<Row> for bit_vec::BitVec {
917 type Columns = crate::Cons<Self, crate::Nil>;
918}
919
920#[cfg(feature = "arrayvec")]
921impl<Row: ?Sized, const N: usize> RowColumnList<Row> for arrayvec::ArrayString<N> {
922 type Columns = crate::Cons<Self, crate::Nil>;
923}
924
925#[cfg(feature = "arrayvec")]
926impl<Row: ?Sized, T, const N: usize> RowColumnList<Row> for arrayvec::ArrayVec<T, N> {
927 type Columns = crate::Cons<Self, crate::Nil>;
928}
929
930impl<Row: ?Sized> RowColumnList<Row> for compact_str::CompactString {
931 type Columns = crate::Cons<Self, crate::Nil>;
932}
933
934#[cfg(feature = "bytes")]
935impl<Row: ?Sized> RowColumnList<Row> for bytes::Bytes {
936 type Columns = crate::Cons<Self, crate::Nil>;
937}
938
939#[cfg(feature = "bytes")]
940impl<Row: ?Sized> RowColumnList<Row> for bytes::BytesMut {
941 type Columns = crate::Cons<Self, crate::Nil>;
942}
943
944impl<Row: ?Sized, A: smallvec::Array> RowColumnList<Row> for smallvec::SmallVec<A> {
945 type Columns = crate::Cons<Self, crate::Nil>;
946}
947
948impl<Row: ?Sized, T> RowColumnList<Row> for Option<T> {
949 type Columns = crate::Cons<Self, crate::Nil>;
950}
951
952macro_rules! impl_rcl_body {
955 ([$A:ident] []) => {
957 impl<Row: ?Sized, $A: RowColumnList<Row>> RowColumnList<Row> for ($A,) {
958 type Columns = <$A as RowColumnList<Row>>::Columns;
959 }
960 };
961 ([$($all:ident),+] [$($prev:ident),+; $last:ident]) => {
963 impl<Row: ?Sized, $($all),+> RowColumnList<Row> for ($($all,)+)
964 where
965 $last: RowColumnList<Row>,
966 ($($prev,)+): RowColumnList<Row>,
967 <($($prev,)+) as RowColumnList<Row>>::Columns:
968 crate::Concat<<$last as RowColumnList<Row>>::Columns>,
969 {
970 type Columns = <<($($prev,)+) as RowColumnList<Row>>::Columns as crate::Concat<
971 <$last as RowColumnList<Row>>::Columns,
972 >>::Output;
973 }
974 };
975}
976
977macro_rules! impl_rcl_tuple {
980 ($($T:ident),+) => {
981 impl_rcl_split!([$($T),+] [] $($T),+);
982 };
983}
984
985macro_rules! impl_rcl_split {
987 ([$A:ident] [] $only:ident) => {
989 impl_rcl_body!([$A] []);
990 };
991 ([$($all:ident),+] [$($prev:ident),+] $last:ident) => {
993 impl_rcl_body!([$($all),+] [$($prev),+; $last]);
994 };
995 ([$($all:ident),+] [] $head:ident, $($rest:ident),+) => {
997 impl_rcl_split!([$($all),+] [$head] $($rest),+);
998 };
999 ([$($all:ident),+] [$($prev:ident),+] $head:ident, $($rest:ident),+) => {
1001 impl_rcl_split!([$($all),+] [$($prev),+, $head] $($rest),+);
1002 };
1003}
1004
1005with_type_sizes_8!(impl_rcl_tuple);
1006
1007#[cfg(any(
1008 feature = "col16",
1009 feature = "col32",
1010 feature = "col64",
1011 feature = "col128",
1012 feature = "col200"
1013))]
1014with_type_sizes_16!(impl_rcl_tuple);
1015
1016#[cfg(any(
1017 feature = "col32",
1018 feature = "col64",
1019 feature = "col128",
1020 feature = "col200"
1021))]
1022with_type_sizes_32!(impl_rcl_tuple);
1023
1024#[diagnostic::on_unimplemented(
1041 message = "selected shape does not match decode target `{Actual}`",
1042 label = "this decode target is not type-compatible with .select(...) output",
1043 note = "use typed expressions or derive FromRow for explicit remapping when selecting custom expressions"
1044)]
1045pub trait MarkerColumnCountValid<Row: ?Sized, Inferred, Actual, Proof = ()> {}
1046
1047#[diagnostic::on_unimplemented(
1054 message = "raw select expressions require explicit typing in strict decode",
1055 label = "`select(sql!(...)).all()/get()` is not allowed in strict mode",
1056 note = "use typed wrappers like `raw_non_null`/`raw_nullable` or derive FromRow"
1057)]
1058pub trait StrictDecodeMarker {}
1059
1060impl StrictDecodeMarker for SelectStar {}
1061impl<Cols> StrictDecodeMarker for SelectCols<Cols> {}
1062impl<R> StrictDecodeMarker for SelectAs<R> {}
1063impl<M, Scope, Used> StrictDecodeMarker for Scoped<M, Scope, Used> where M: StrictDecodeMarker {}
1064
1065impl<Row: ?Sized, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1066 for SelectStar
1067{
1068}
1069
1070impl<Row: ?Sized, Cols, Inferred, Actual, Proof>
1071 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for SelectCols<Cols>
1072where
1073 Cols: SelectedColumnList,
1074 Actual: RowColumnList<Row>,
1075 <Cols as SelectedColumnList>::Columns:
1076 TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
1077{
1078}
1079
1080impl<Row: ?Sized, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1081 for SelectExpr
1082where
1083 Inferred: SameType<Actual>,
1084{
1085}
1086
1087impl<Row: ?Sized, R, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1088 for SelectAs<R>
1089{
1090}
1091
1092impl<Row: ?Sized, Table, Used, Inferred, Actual, Proof>
1094 MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1095 for Scoped<SelectStar, Cons<Table, Nil>, Used>
1096{
1097}
1098
1099impl<Row: ?Sized, First, Second, Rest, Used, Inferred, Actual, Proof>
1102 MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1103 for Scoped<SelectStar, Cons<First, Cons<Second, Rest>>, Used>
1104where
1105 Inferred: JoinedStarRow<Actual>,
1106{
1107}
1108
1109impl<Row: ?Sized, Cols, Scope, Used, Inferred, Actual, UsedProof, ColsProof>
1110 MarkerColumnCountValid<Row, Inferred, Actual, (UsedProof, ColsProof)>
1111 for Scoped<SelectCols<Cols>, Scope, Used>
1112where
1113 Cols: SelectedExpressionList,
1114 Cols::Expressions: ProjectionIn<Scope, ColsProof>,
1115 Actual: RowColumnList<Row>,
1116 <Cols::Expressions as ProjectionIn<Scope, ColsProof>>::Columns:
1117 TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
1118{
1119}
1120
1121impl<Row: ?Sized, Scope, Used, Inferred, Actual, Proof>
1122 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for Scoped<SelectExpr, Scope, Used>
1123where
1124 Inferred: SameType<Actual>,
1125{
1126}
1127
1128impl<Row: ?Sized, R, Scope, Used, Inferred, Actual, Proof>
1130 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for Scoped<SelectAs<R>, Scope, Used>
1131{
1132}
1133
1134#[diagnostic::on_unimplemented(
1140 message = "joined `SELECT *` rows decode as `{Self}`, not `{Actual}`",
1141 label = "the decode target does not match the joined row type",
1142 note = "LEFT/RIGHT/FULL JOIN sources can be NULL: decode them as `Option<_>`, \
1143 e.g. `(SelectUsers, Option<SelectPosts>)` after `.left_join(posts)`"
1144)]
1145pub trait JoinedStarRow<Actual> {}
1146
1147impl<A, B, ActualA, ActualB> JoinedStarRow<(ActualA, ActualB)> for (A, B)
1148where
1149 A: JoinedStarPart<ActualA>,
1150 B: JoinedStarPart<ActualB>,
1151{
1152}
1153
1154#[doc(hidden)]
1156#[diagnostic::on_unimplemented(
1157 message = "this half of the joined `SELECT *` row decodes as `{Self}`, not `{Actual}`",
1158 label = "the decode target does not match the joined row type",
1159 note = "LEFT/RIGHT/FULL JOIN sources can be NULL: decode them as `Option<_>`"
1160)]
1161pub trait JoinedStarPart<Actual> {}
1162
1163impl<T> JoinedStarPart<T> for T {}
1164
1165impl<T> JoinedStarPart<Option<T>> for T {}
1166
1167pub trait DecodeSelectedRef<RowRef, R> {
1172 fn decode(row: RowRef) -> Result<R, DrizzleError>;
1179}
1180
1181impl<RowRef, R> DecodeSelectedRef<RowRef, R> for SelectAs<R>
1182where
1183 R: TryFrom<RowRef>,
1184 <R as TryFrom<RowRef>>::Error: Into<DrizzleError>,
1185{
1186 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1187 R::try_from(row).map_err(Into::into)
1188 }
1189}
1190
1191impl<RowRef, R, M, Scope, Used> DecodeSelectedRef<RowRef, R> for Scoped<M, Scope, Used>
1192where
1193 M: DecodeSelectedRef<RowRef, R>,
1194{
1195 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1196 M::decode(row)
1197 }
1198}
1199
1200impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectStar
1201where
1202 RowRef: core::ops::Deref<Target = Row>,
1203 R: FromDrizzleRow<Row>,
1204{
1205 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1206 R::from_row(&*row)
1207 }
1208}
1209
1210impl<RowRef, Row: ?Sized, Cols, R> DecodeSelectedRef<RowRef, R> for SelectCols<Cols>
1211where
1212 RowRef: core::ops::Deref<Target = Row>,
1213 R: FromDrizzleRow<Row>,
1214{
1215 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1216 R::from_row(&*row)
1217 }
1218}
1219
1220impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectExpr
1221where
1222 RowRef: core::ops::Deref<Target = Row>,
1223 R: FromDrizzleRow<Row>,
1224{
1225 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1226 R::from_row(&*row)
1227 }
1228}
1229
1230#[diagnostic::on_unimplemented(
1243 message = "cannot deserialize `{Self}` from a database row",
1244 label = "this type does not implement FromDrizzleRow",
1245 note = "derive #[SQLiteFromRow], #[PostgresFromRow], or #[MySQLFromRow]"
1246)]
1247pub trait FromDrizzleRow<Row: ?Sized>: Sized {
1248 const COLUMN_COUNT: usize;
1250
1251 fn from_row_at(row: &Row, offset: usize) -> Result<Self, DrizzleError>;
1258
1259 fn from_row(row: &Row) -> Result<Self, DrizzleError> {
1265 Self::from_row_at(row, 0)
1266 }
1267}
1268
1269pub trait NullProbeRow<Row: ?Sized>: FromDrizzleRow<Row> {
1277 fn is_null_at(row: &Row, offset: usize) -> Result<bool, DrizzleError>;
1284}
1285
1286macro_rules! impl_from_drizzle_row_tuple {
1289 ($($T:ident),+; $($idx:tt),+) => {
1290 impl<__Row: ?Sized, $($T: FromDrizzleRow<__Row>),+> FromDrizzleRow<__Row> for ($($T,)+) {
1291 const COLUMN_COUNT: usize = 0 $(+ <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT)+;
1292
1293 #[allow(non_snake_case)]
1294 fn from_row_at(
1295 row: &__Row,
1296 offset: usize,
1297 ) -> Result<Self, DrizzleError> {
1298 let mut __off = offset;
1299 $(
1300 let $T = <$T as FromDrizzleRow<__Row>>::from_row_at(row, __off)?;
1301 __off += <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT;
1302 )+
1303 Ok(($($T,)+))
1304 }
1305 }
1306 };
1307}
1308
1309with_col_sizes_8!(impl_from_drizzle_row_tuple);
1310
1311#[cfg(any(
1312 feature = "col16",
1313 feature = "col32",
1314 feature = "col64",
1315 feature = "col128",
1316 feature = "col200"
1317))]
1318with_col_sizes_16!(impl_from_drizzle_row_tuple);
1319
1320#[cfg(any(
1321 feature = "col32",
1322 feature = "col64",
1323 feature = "col128",
1324 feature = "col200"
1325))]
1326with_col_sizes_32!(impl_from_drizzle_row_tuple);
1327
1328#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1329with_col_sizes_64!(impl_from_drizzle_row_tuple);
1330
1331#[cfg(any(feature = "col128", feature = "col200"))]
1332with_col_sizes_128!(impl_from_drizzle_row_tuple);
1333
1334#[cfg(feature = "col200")]
1335with_col_sizes_200!(impl_from_drizzle_row_tuple);
1336
1337#[diagnostic::on_unimplemented(
1354 message = "SQL type `{Self}` has no default Rust mapping for dialect `{D}`",
1355 label = "this SQL type has no default Rust mapping for this dialect",
1356 note = "enable `chrono` for Date/Time/Timestamp/TimestampTz, `uuid` for Uuid, or `serde` for Json/Jsonb"
1357)]
1358pub trait SQLTypeToRust<D> {
1359 type RustType;
1360}
1361
1362use crate::dialect::{MySQLDialect, PostgresDialect, SQLiteDialect};
1365
1366impl<D, T> SQLTypeToRust<D> for crate::types::Array<T>
1367where
1368 T: crate::types::DataType + SQLTypeToRust<D>,
1369{
1370 type RustType = crate::prelude::Vec<<T as SQLTypeToRust<D>>::RustType>;
1371}
1372
1373impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Integer {
1374 type RustType = i64;
1375}
1376
1377impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Text {
1378 type RustType = crate::prelude::String;
1379}
1380
1381impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Real {
1382 type RustType = f64;
1383}
1384
1385impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Blob {
1386 type RustType = crate::prelude::Vec<u8>;
1387}
1388
1389impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Numeric {
1390 type RustType = f64;
1391}
1392
1393impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Any {
1394 type RustType = crate::prelude::String;
1395}
1396
1397macro_rules! impl_mysql_sql_type_to_rust {
1398 ($rust:ty => $($sql:ty),+ $(,)?) => {
1399 $(
1400 impl SQLTypeToRust<MySQLDialect> for $sql {
1401 type RustType = $rust;
1402 }
1403 )+
1404 };
1405}
1406
1407impl_mysql_sql_type_to_rust!(i8 => drizzle_types::mysql::types::TinyInt);
1408impl_mysql_sql_type_to_rust!(u8 => drizzle_types::mysql::types::TinyIntUnsigned);
1409impl_mysql_sql_type_to_rust!(i16 => drizzle_types::mysql::types::SmallInt);
1410impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::SmallIntUnsigned);
1411impl_mysql_sql_type_to_rust!(i32 =>
1412 drizzle_types::mysql::types::MediumInt,
1413 drizzle_types::mysql::types::Int,
1414);
1415impl_mysql_sql_type_to_rust!(u32 =>
1416 drizzle_types::mysql::types::MediumIntUnsigned,
1417 drizzle_types::mysql::types::IntUnsigned,
1418);
1419impl_mysql_sql_type_to_rust!(i64 => drizzle_types::mysql::types::BigInt);
1420impl_mysql_sql_type_to_rust!(u64 => drizzle_types::mysql::types::BigIntUnsigned);
1421impl_mysql_sql_type_to_rust!(f32 => drizzle_types::mysql::types::Float);
1422impl_mysql_sql_type_to_rust!(f64 => drizzle_types::mysql::types::Double);
1423impl_mysql_sql_type_to_rust!(bool => drizzle_types::mysql::types::Boolean);
1424impl_mysql_sql_type_to_rust!(crate::prelude::String =>
1425 drizzle_types::mysql::types::Char,
1426 drizzle_types::mysql::types::Varchar,
1427 drizzle_types::mysql::types::TinyText,
1428 drizzle_types::mysql::types::Text,
1429 drizzle_types::mysql::types::MediumText,
1430 drizzle_types::mysql::types::LongText,
1431 drizzle_types::mysql::types::Enum,
1432 drizzle_types::mysql::types::Set,
1433 drizzle_types::mysql::types::Any,
1434);
1435impl_mysql_sql_type_to_rust!(crate::prelude::Vec<u8> =>
1436 drizzle_types::mysql::types::Binary,
1437 drizzle_types::mysql::types::Varbinary,
1438 drizzle_types::mysql::types::TinyBlob,
1439 drizzle_types::mysql::types::Blob,
1440 drizzle_types::mysql::types::MediumBlob,
1441 drizzle_types::mysql::types::LongBlob,
1442 drizzle_types::mysql::types::Bit,
1443);
1444impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::Year);
1445
1446#[cfg(feature = "rust-decimal")]
1447impl_mysql_sql_type_to_rust!(rust_decimal::Decimal => drizzle_types::mysql::types::Decimal);
1448#[cfg(not(feature = "rust-decimal"))]
1449impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Decimal);
1450
1451#[cfg(feature = "serde")]
1452impl_mysql_sql_type_to_rust!(serde_json::Value => drizzle_types::mysql::types::Json);
1453#[cfg(not(feature = "serde"))]
1454impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Json);
1455
1456#[cfg(feature = "chrono")]
1457impl_mysql_sql_type_to_rust!(chrono::NaiveDate => drizzle_types::mysql::types::Date);
1458#[cfg(all(not(feature = "chrono"), feature = "time"))]
1459impl_mysql_sql_type_to_rust!(time::Date => drizzle_types::mysql::types::Date);
1460#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1461impl_mysql_sql_type_to_rust!(jiff::civil::Date => drizzle_types::mysql::types::Date);
1462#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
1463impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Date);
1464
1465impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Time);
1470
1471#[cfg(feature = "chrono")]
1472impl_mysql_sql_type_to_rust!(chrono::NaiveDateTime => drizzle_types::mysql::types::DateTime);
1473#[cfg(feature = "chrono")]
1477impl_mysql_sql_type_to_rust!(chrono::DateTime<chrono::Utc> => drizzle_types::mysql::types::Timestamp);
1478#[cfg(all(not(feature = "chrono"), feature = "time"))]
1479impl_mysql_sql_type_to_rust!(time::PrimitiveDateTime => drizzle_types::mysql::types::DateTime);
1480#[cfg(all(not(feature = "chrono"), feature = "time"))]
1481impl_mysql_sql_type_to_rust!(time::OffsetDateTime => drizzle_types::mysql::types::Timestamp);
1482#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1483impl_mysql_sql_type_to_rust!(jiff::civil::DateTime => drizzle_types::mysql::types::DateTime);
1484#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1485impl_mysql_sql_type_to_rust!(jiff::Timestamp => drizzle_types::mysql::types::Timestamp);
1486#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
1487impl_mysql_sql_type_to_rust!(crate::prelude::String =>
1488 drizzle_types::mysql::types::DateTime,
1489 drizzle_types::mysql::types::Timestamp,
1490);
1491
1492impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int2 {
1493 type RustType = i16;
1494}
1495
1496impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int4 {
1497 type RustType = i32;
1498}
1499
1500impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int8 {
1501 type RustType = i64;
1502}
1503
1504impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float4 {
1505 type RustType = f32;
1506}
1507
1508impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float8 {
1509 type RustType = f64;
1510}
1511
1512impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Varchar {
1513 type RustType = crate::prelude::String;
1514}
1515
1516impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Text {
1517 type RustType = crate::prelude::String;
1518}
1519
1520impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Char {
1521 type RustType = crate::prelude::String;
1522}
1523
1524impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Bytea {
1525 type RustType = crate::prelude::Vec<u8>;
1526}
1527
1528impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Boolean {
1529 type RustType = bool;
1530}
1531
1532#[cfg(feature = "rust-decimal")]
1533impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
1534 type RustType = rust_decimal::Decimal;
1535}
1536
1537#[cfg(not(feature = "rust-decimal"))]
1538impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
1539 type RustType = crate::prelude::String;
1540}
1541
1542impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Any {
1543 type RustType = crate::prelude::String;
1544}
1545
1546#[cfg(feature = "chrono")]
1547impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1548 type RustType = chrono::DateTime<chrono::Utc>;
1549}
1550
1551#[cfg(feature = "chrono")]
1552impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1553 type RustType = chrono::NaiveDateTime;
1554}
1555
1556#[cfg(feature = "chrono")]
1557impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1558 type RustType = chrono::NaiveDate;
1559}
1560
1561#[cfg(feature = "chrono")]
1562impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1563 type RustType = chrono::NaiveTime;
1564}
1565
1566#[cfg(feature = "chrono")]
1567impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timetz {
1568 type RustType = chrono::NaiveTime;
1569}
1570
1571#[cfg(all(not(feature = "chrono"), feature = "time"))]
1572impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1573 type RustType = time::OffsetDateTime;
1574}
1575
1576#[cfg(all(not(feature = "chrono"), feature = "time"))]
1577impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1578 type RustType = time::PrimitiveDateTime;
1579}
1580
1581#[cfg(all(not(feature = "chrono"), feature = "time"))]
1582impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1583 type RustType = time::Date;
1584}
1585
1586#[cfg(all(not(feature = "chrono"), feature = "time"))]
1587impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1588 type RustType = time::Time;
1589}
1590
1591#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1592impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1593 type RustType = jiff::Timestamp;
1594}
1595
1596#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1597impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1598 type RustType = jiff::civil::DateTime;
1599}
1600
1601#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1602impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1603 type RustType = jiff::civil::Date;
1604}
1605
1606#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1607impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1608 type RustType = jiff::civil::Time;
1609}
1610
1611#[cfg(feature = "uuid")]
1612impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Uuid {
1613 type RustType = uuid::Uuid;
1614}
1615
1616#[cfg(feature = "serde")]
1617impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Json {
1618 type RustType = serde_json::Value;
1619}
1620
1621#[cfg(feature = "serde")]
1622impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Jsonb {
1623 type RustType = serde_json::Value;
1624}
1625
1626#[cfg(feature = "chrono")]
1629impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
1630 type RustType = chrono::Duration;
1631}
1632
1633#[cfg(not(feature = "chrono"))]
1634impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
1635 type RustType = crate::prelude::String;
1636}
1637
1638#[cfg(feature = "cidr")]
1639impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
1640 type RustType = cidr::IpInet;
1641}
1642
1643#[cfg(not(feature = "cidr"))]
1644impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
1645 type RustType = crate::prelude::String;
1646}
1647
1648#[cfg(feature = "cidr")]
1649impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
1650 type RustType = cidr::IpCidr;
1651}
1652
1653#[cfg(not(feature = "cidr"))]
1654impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
1655 type RustType = crate::prelude::String;
1656}
1657
1658impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr {
1659 type RustType = crate::prelude::String;
1660}
1661
1662impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr8 {
1663 type RustType = crate::prelude::String;
1664}
1665
1666#[cfg(feature = "geo-types")]
1667impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
1668 type RustType = geo_types::Point<f64>;
1669}
1670
1671#[cfg(not(feature = "geo-types"))]
1672impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
1673 type RustType = crate::prelude::String;
1674}
1675
1676#[cfg(feature = "geo-types")]
1677impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
1678 type RustType = geo_types::LineString<f64>;
1679}
1680
1681#[cfg(not(feature = "geo-types"))]
1682impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
1683 type RustType = crate::prelude::String;
1684}
1685
1686#[cfg(feature = "geo-types")]
1687impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
1688 type RustType = geo_types::Rect<f64>;
1689}
1690
1691#[cfg(not(feature = "geo-types"))]
1692impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
1693 type RustType = crate::prelude::String;
1694}
1695
1696#[cfg(feature = "bit-vec")]
1697impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
1698 type RustType = bit_vec::BitVec;
1699}
1700
1701#[cfg(not(feature = "bit-vec"))]
1702impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
1703 type RustType = crate::prelude::String;
1704}
1705
1706impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Line {
1707 type RustType = crate::prelude::String;
1708}
1709
1710impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineSegment {
1711 type RustType = crate::prelude::String;
1712}
1713
1714impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Polygon {
1715 type RustType = crate::prelude::String;
1716}
1717
1718impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Circle {
1719 type RustType = crate::prelude::String;
1720}
1721
1722impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Enum {
1723 type RustType = crate::prelude::String;
1724}
1725
1726pub trait WrapNullable<T> {
1733 type Output;
1735}
1736
1737impl<T> WrapNullable<T> for crate::expr::NonNull {
1738 type Output = T;
1739}
1740
1741impl<T> WrapNullable<T> for crate::expr::Null {
1742 type Output = Option<T>;
1743}
1744
1745#[diagnostic::on_unimplemented(
1758 message = "cannot infer Rust type for expression `{Self}`",
1759 label = "use typed expressions or derive FromRow to specify the Rust type",
1760 note = "raw SQL and JSON expressions require explicit type annotation"
1761)]
1762pub trait ExprValueType {
1763 type ValueType;
1765}
1766
1767impl<T: ExprValueType + ?Sized> ExprValueType for &T {
1768 type ValueType = T::ValueType;
1769}
1770
1771impl<V: crate::SQLParam, T, N, A, S> ExprValueType for crate::expr::SQLExpr<'_, V, T, N, A, S>
1772where
1773 T: crate::types::DataType + SQLTypeToRust<V::DialectMarker>,
1774 N: crate::expr::Nullability + WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>,
1775 A: crate::expr::AggregateKind,
1776{
1777 type ValueType = <N as WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>>::Output;
1778}
1779
1780impl<V: crate::SQLParam> ExprValueType for crate::sql::SQL<'_, V> {
1782 type ValueType = ();
1783}
1784
1785#[diagnostic::on_unimplemented(
1794 message = "`{Self}` is not a drizzle table",
1795 label = "ensure this type was derived with #[SQLiteTable], #[PostgresTable], or #[MySQLTable]"
1796)]
1797pub trait HasSelectModel {
1798 type SelectModel;
1800 const COLUMN_COUNT: usize;
1802}
1803
1804impl<T: HasSelectModel + ?Sized> HasSelectModel for &T {
1805 type SelectModel = T::SelectModel;
1806
1807 const COLUMN_COUNT: usize = T::COLUMN_COUNT;
1808}
1809
1810#[diagnostic::on_unimplemented(
1820 message = "cannot resolve return type for this query",
1821 label = "the selected columns and table do not produce a known row type"
1822)]
1823pub trait ResolveRow<Table> {
1824 type Row;
1826}
1827
1828impl<T: HasSelectModel> ResolveRow<T> for SelectStar {
1829 type Row = T::SelectModel;
1830}
1831
1832impl<T> ResolveRow<T> for SelectExpr {
1833 type Row = ();
1834}
1835
1836impl<R, T> ResolveRow<T> for SelectAs<R>
1837where
1838 R: SelectAsFrom<T>,
1839{
1840 type Row = R;
1841}
1842
1843impl<M, Scope, Used, T> ResolveRow<T> for Scoped<M, Scope, Used>
1844where
1845 M: ResolveRow<T>,
1846{
1847 type Row = M::Row;
1848}
1849
1850#[diagnostic::on_unimplemented(
1856 message = "row selector `{Self}` cannot be used with table `{Table}`",
1857 label = "the #[from(...)] table does not match .from(...)",
1858 note = "set #[from(TheTable)] to the same table passed to .from(...)"
1859)]
1860pub trait SelectAsFrom<Table> {}
1861
1862macro_rules! impl_resolve_row_cols {
1865 ($($T:ident),+; $($idx:tt),+) => {
1866 impl<__Table, $($T: ExprValueType),+> ResolveRow<__Table> for SelectCols<($($T,)+)> {
1867 type Row = ($(<$T as ExprValueType>::ValueType,)+);
1868 }
1869 };
1870}
1871
1872with_col_sizes_8!(impl_resolve_row_cols);
1873
1874#[cfg(any(
1875 feature = "col16",
1876 feature = "col32",
1877 feature = "col64",
1878 feature = "col128",
1879 feature = "col200"
1880))]
1881with_col_sizes_16!(impl_resolve_row_cols);
1882
1883#[cfg(any(
1884 feature = "col32",
1885 feature = "col64",
1886 feature = "col128",
1887 feature = "col200"
1888))]
1889with_col_sizes_32!(impl_resolve_row_cols);
1890
1891#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1892with_col_sizes_64!(impl_resolve_row_cols);
1893
1894#[cfg(any(feature = "col128", feature = "col200"))]
1895with_col_sizes_128!(impl_resolve_row_cols);
1896
1897#[cfg(feature = "col200")]
1898with_col_sizes_200!(impl_resolve_row_cols);
1899
1900macro_rules! selected_columns_cons {
1901 () => {
1902 crate::Nil
1903 };
1904 ($head:ident $(, $tail:ident)*) => {
1905 crate::Cons<<$head as ExprValueType>::ValueType, selected_columns_cons!($($tail),*)>
1906 };
1907}
1908
1909macro_rules! selected_expressions_cons {
1910 () => {
1911 crate::Nil
1912 };
1913 ($head:ident $(, $tail:ident)*) => {
1914 crate::Cons<$head, selected_expressions_cons!($($tail),*)>
1915 };
1916}
1917
1918macro_rules! impl_selected_column_list_tuple {
1919 ($($T:ident),+; $($idx:tt),+) => {
1920 impl<$($T: ExprValueType),+> SelectedColumnList for ($($T,)+) {
1921 type Columns = selected_columns_cons!($($T),+);
1922 }
1923 };
1924}
1925
1926macro_rules! impl_selected_expression_list_tuple {
1927 ($($T:ident),+; $($idx:tt),+) => {
1928 impl<$($T),+> SelectedExpressionList for ($($T,)+) {
1929 type Expressions = selected_expressions_cons!($($T),+);
1930 }
1931 };
1932}
1933
1934with_col_sizes_8!(impl_selected_column_list_tuple);
1935with_col_sizes_8!(impl_selected_expression_list_tuple);
1936
1937#[cfg(any(
1938 feature = "col16",
1939 feature = "col32",
1940 feature = "col64",
1941 feature = "col128",
1942 feature = "col200"
1943))]
1944with_col_sizes_16!(impl_selected_column_list_tuple);
1945#[cfg(any(
1946 feature = "col16",
1947 feature = "col32",
1948 feature = "col64",
1949 feature = "col128",
1950 feature = "col200"
1951))]
1952with_col_sizes_16!(impl_selected_expression_list_tuple);
1953
1954#[cfg(any(
1955 feature = "col32",
1956 feature = "col64",
1957 feature = "col128",
1958 feature = "col200"
1959))]
1960with_col_sizes_32!(impl_selected_column_list_tuple);
1961#[cfg(any(
1962 feature = "col32",
1963 feature = "col64",
1964 feature = "col128",
1965 feature = "col200"
1966))]
1967with_col_sizes_32!(impl_selected_expression_list_tuple);
1968
1969#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1970with_col_sizes_64!(impl_selected_column_list_tuple);
1971#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1972with_col_sizes_64!(impl_selected_expression_list_tuple);
1973
1974#[cfg(any(feature = "col128", feature = "col200"))]
1975with_col_sizes_128!(impl_selected_column_list_tuple);
1976#[cfg(any(feature = "col128", feature = "col200"))]
1977with_col_sizes_128!(impl_selected_expression_list_tuple);
1978
1979#[cfg(feature = "col200")]
1980with_col_sizes_200!(impl_selected_column_list_tuple);
1981#[cfg(feature = "col200")]
1982with_col_sizes_200!(impl_selected_expression_list_tuple);
1983
1984use crate::scope::{FullJoin, InnerJoin, JoinRow, LeftJoin, RightJoin};
1989
1990impl<R, T, Kind> JoinRow<R, T, crate::scope::Lateral<Kind>> for SelectStar
1992where
1993 SelectStar: JoinRow<R, T, Kind>,
1994{
1995 type Row = <SelectStar as JoinRow<R, T, Kind>>::Row;
1996}
1997
1998#[doc(hidden)]
2005pub trait LeftLateralSelection<Proof = ()>: left_lateral_private::Sealed {}
2006
2007mod left_lateral_private {
2008 pub trait Sealed {}
2009
2010 impl Sealed for super::SelectStar {}
2011 impl<Scope, Used> Sealed for super::Scoped<super::SelectStar, Scope, Used> {}
2012 impl<Columns, Scope, Used> Sealed for super::Scoped<super::SelectCols<Columns>, Scope, Used> {}
2013 impl<Row, Scope, Used> Sealed for super::Scoped<super::SelectAs<Row>, Scope, Used> {}
2014}
2015
2016impl LeftLateralSelection for SelectStar {}
2017impl<Scope, Used> LeftLateralSelection for Scoped<SelectStar, Scope, Used> {}
2018
2019impl<Columns, Scope, Used, Proof> LeftLateralSelection<Proof>
2020 for Scoped<SelectCols<Columns>, Scope, Used>
2021where
2022 Columns: SelectedExpressionList,
2023 Columns::Expressions: ProjectionIn<Scope, Proof>,
2024{
2025}
2026
2027impl<Row, Scope, Used, Proof> LeftLateralSelection<Proof> for Scoped<SelectAs<Row>, Scope, Used>
2028where
2029 Row: SelectTableFields,
2030 Row::TableFields: TableFieldsIn<Scope, Proof>,
2031{
2032}
2033
2034impl<R, T: HasSelectModel> JoinRow<R, T, InnerJoin> for SelectStar {
2036 type Row = (R, T::SelectModel);
2037}
2038
2039impl<R, T: HasSelectModel> JoinRow<R, T, LeftJoin> for SelectStar {
2041 type Row = (R, Option<T::SelectModel>);
2042}
2043
2044impl<R, T: HasSelectModel> JoinRow<R, T, RightJoin> for SelectStar {
2046 type Row = (Option<R>, T::SelectModel);
2047}
2048
2049impl<R, T: HasSelectModel> JoinRow<R, T, FullJoin> for SelectStar {
2051 type Row = (Option<R>, Option<T::SelectModel>);
2052}
2053
2054impl<Cols, R, T, Kind> JoinRow<R, T, Kind> for SelectCols<Cols> {
2056 type Row = R;
2057}
2058
2059impl<R, T, Kind> JoinRow<R, T, Kind> for SelectExpr {
2061 type Row = R;
2062}
2063
2064impl<Row, R, T, Kind> JoinRow<R, T, Kind> for SelectAs<Row> {
2066 type Row = R;
2067}
2068
2069#[diagnostic::on_unimplemented(
2089 message = "`{Self}` cannot be used as a select target",
2090 label = "this type does not implement IntoSelectTarget",
2091 note = "implement IntoSelectTarget or use a column, table, or typed expression"
2092)]
2093pub trait IntoSelectTarget {
2094 type Marker;
2096}
2097
2098impl<T: IntoSelectTarget + ?Sized> IntoSelectTarget for &T {
2099 type Marker = T::Marker;
2100}
2101
2102impl IntoSelectTarget for () {
2104 type Marker = SelectStar;
2105}
2106
2107impl<V: crate::SQLParam> IntoSelectTarget for crate::sql::SQL<'_, V> {
2109 type Marker = SelectExpr;
2110}
2111
2112impl<V: crate::SQLParam, T, N, A, S> IntoSelectTarget for crate::expr::SQLExpr<'_, V, T, N, A, S>
2114where
2115 T: crate::types::DataType,
2116 N: crate::expr::Nullability,
2117 A: crate::expr::AggregateKind,
2118{
2119 type Marker = SelectCols<(Self,)>;
2120}
2121
2122macro_rules! impl_into_select_target_tuple {
2124 ($($T:ident),+; $($idx:tt),+) => {
2125 impl<$($T),+> IntoSelectTarget for ($($T,)+) {
2126 type Marker = SelectCols<($($T,)+)>;
2127 }
2128 };
2129}
2130
2131with_col_sizes_8!(impl_into_select_target_tuple);
2132
2133#[cfg(any(
2134 feature = "col16",
2135 feature = "col32",
2136 feature = "col64",
2137 feature = "col128",
2138 feature = "col200"
2139))]
2140with_col_sizes_16!(impl_into_select_target_tuple);
2141
2142#[cfg(any(
2143 feature = "col32",
2144 feature = "col64",
2145 feature = "col128",
2146 feature = "col200"
2147))]
2148with_col_sizes_32!(impl_into_select_target_tuple);
2149
2150#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
2151with_col_sizes_64!(impl_into_select_target_tuple);
2152
2153#[cfg(any(feature = "col128", feature = "col200"))]
2154with_col_sizes_128!(impl_into_select_target_tuple);
2155
2156#[cfg(feature = "col200")]
2157with_col_sizes_200!(impl_into_select_target_tuple);