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
465#[diagnostic::on_unimplemented(
468 message = "`{Self}` is selected next to an aggregate but is not grouped",
469 label = "this query mixes aggregated and ungrouped columns",
470 note = "add the column to `.group_by(...)`, or wrap it in an aggregate such as `max(...)`"
471)]
472pub trait SingleColGroupCheck<Grouped, Proof> {}
473
474pub trait GroupByIdentity {
479 type Identity;
481}
482
483impl<E: GroupByIdentity> GroupByIdentity for crate::expr::AliasedExpr<E> {
488 type Identity = E::Identity;
489}
490
491impl<V: crate::SQLParam, T, N, A, S> GroupByIdentity for crate::expr::SQLExpr<'_, V, T, N, A, S>
493where
494 T: crate::types::DataType,
495 N: crate::expr::Nullability,
496 A: crate::expr::AggregateKind,
497{
498 type Identity = Self;
499}
500
501impl<Lhs, Rhs, Op, D, SQLType, Nullable> GroupByIdentity
503 for crate::expr::ColumnBinOp<Lhs, Rhs, Op, D, SQLType, Nullable>
504{
505 type Identity = Self;
506}
507
508impl<T, D, SQLType, Nullable> GroupByIdentity for crate::expr::ColumnNeg<T, D, SQLType, Nullable> {
510 type Identity = Self;
511}
512
513impl<E, Grouped> SingleColGroupCheck<Grouped, AggSkip> for E where
515 E: crate::expr::HasAggStatus<Status = crate::expr::AllAgg>
516{
517}
518
519impl<E, Grouped, W> SingleColGroupCheck<Grouped, ScalarCheck<W>> for E
521where
522 E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
523 Grouped: crate::scope::ListContains<E::Identity, W>,
524{
525}
526
527impl<E, T> SingleColGroupCheck<PkGroup<T>, PkDependent> for E
532where
533 E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
534 E::Identity: crate::traits::ColumnOf<T>,
535{
536}
537
538impl<T0, T1, Grouped, P0, P1> ScalarColumnsIn<Grouped, (P0, P1)> for (T0, T1)
543where
544 T0: SingleColGroupCheck<Grouped, P0>,
545 T1: SingleColGroupCheck<Grouped, P1>,
546{
547}
548
549macro_rules! impl_scalar_columns_in {
551 ($T0:ident; $i0:tt) => {};
553 ($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {};
555 ($T0:ident, $($rest:ident),+; $i0:tt, $($ri:tt),+) => {
557 impl<$T0, $($rest),+, Grouped, HeadProof, TailProof>
558 ScalarColumnsIn<Grouped, (HeadProof, TailProof)>
559 for ($T0, $($rest),+)
560 where
561 $T0: SingleColGroupCheck<Grouped, HeadProof>,
562 ($($rest,)+): ScalarColumnsIn<Grouped, TailProof>,
563 {}
564 };
565}
566
567with_col_sizes_8!(impl_scalar_columns_in);
568
569#[cfg(any(
570 feature = "col16",
571 feature = "col32",
572 feature = "col64",
573 feature = "col128",
574 feature = "col200"
575))]
576with_col_sizes_16!(impl_scalar_columns_in);
577
578#[diagnostic::on_unimplemented(
593 message = "non-aggregate column in SELECT is not in GROUP BY",
594 label = "add this column to .group_by(...) or wrap it in an aggregate function"
595)]
596pub trait MarkerAggValidFor<Grouped, Proof = ()> {}
597
598impl<Mk> MarkerAggValidFor<()> for Mk {}
600
601impl<Scope, Used, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
603 for Scoped<SelectStar, Scope, Used>
604{
605}
606
607impl<Scope, Used, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
609 for Scoped<SelectExpr, Scope, Used>
610{
611}
612
613impl<Scope, Used, R, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
615 for Scoped<SelectAs<R>, Scope, Used>
616{
617}
618
619impl<Scope, Used, Cols, Head, Tail, Proof> MarkerAggValidFor<Cons<Head, Tail>, Proof>
621 for Scoped<SelectCols<Cols>, Scope, Used>
622where
623 Cols: ScalarColumnsIn<Cons<Head, Tail>, Proof>,
624{
625}
626
627impl<Scope, Used, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectStar, Scope, Used> {}
631
632impl<Scope, Used, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectExpr, Scope, Used> {}
633
634impl<Scope, Used, R, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectAs<R>, Scope, Used> {}
635
636impl<Scope, Used, Cols, T, Proof> MarkerAggValidFor<PkGroup<T>, Proof>
637 for Scoped<SelectCols<Cols>, Scope, Used>
638where
639 Cols: ScalarColumnsIn<PkGroup<T>, Proof>,
640{
641}
642
643pub trait RowColumnList<Row: ?Sized> {
652 type Columns: crate::TypeSet;
654}
655
656pub trait SelectedColumnList {
658 type Columns: crate::TypeSet;
660}
661
662#[doc(hidden)]
668pub trait SelectedExpressionList {
669 type Expressions: crate::TypeSet;
670}
671
672trait SameType<T> {}
673impl<T> SameType<T> for T {}
674
675#[diagnostic::on_unimplemented(
676 message = "selected column decodes as `{Expected}`, but the decode target uses `{Actual}`",
677 label = "the decode target does not match the selected columns",
678 note = "a selected `MaybeNull<T>` can be NULL (an outer join or a nullable operand) \
679 and must be decoded as `Option<T>`"
680)]
681trait ColumnTypeCompatible<Row: ?Sized, Expected, Actual> {}
682
683impl<Row: ?Sized, T> ColumnTypeCompatible<Row, T, T> for () {}
684
685impl<Row: ?Sized, Expected, Actual> ColumnTypeCompatible<Row, MaybeNull<Expected>, Option<Actual>>
689 for ()
690where
691 (): MaybeNullCompatible<Row, Expected, Actual>,
692{
693}
694
695trait MaybeNullCompatible<Row: ?Sized, Expected, Actual> {}
698
699impl<Row: ?Sized, T> MaybeNullCompatible<Row, T, T> for () {}
700
701impl<Row: ?Sized, T> MaybeNullCompatible<Row, Option<T>, T> for () {}
702
703trait TypeListCompatible<Row: ?Sized, ActualList> {}
704
705impl<Row: ?Sized> TypeListCompatible<Row, Self> for crate::Nil {}
706
707impl<Row: ?Sized, EH, ET, AH, AT> TypeListCompatible<Row, crate::Cons<AH, AT>>
708 for crate::Cons<EH, ET>
709where
710 (): ColumnTypeCompatible<Row, EH, AH>,
711 ET: TypeListCompatible<Row, AT>,
712{
713}
714
715trait SqliteDecodeRow {}
716
717#[cfg(feature = "rusqlite")]
718impl SqliteDecodeRow for ::rusqlite::Row<'_> {}
719
720#[cfg(feature = "libsql")]
721impl SqliteDecodeRow for ::libsql::Row {}
722
723#[cfg(feature = "turso")]
724impl SqliteDecodeRow for ::turso::Row {}
725
726macro_rules! impl_sqlite_integer_decode_compat {
727 ($expected:ty => $($actual:ty),+ $(,)?) => {
728 $(
729 impl<Row> ColumnTypeCompatible<Row, $expected, $actual> for ()
730 where
731 Row: SqliteDecodeRow,
732 {
733 }
734 )+
735 };
736}
737
738impl_sqlite_integer_decode_compat!(
739 i64 => i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
740);
741
742macro_rules! impl_sqlite_join_nullable_integer_decode_compat {
743 ($($actual:ty),+ $(,)?) => {
744 $(
745 impl<Row> MaybeNullCompatible<Row, i64, $actual> for ()
746 where
747 Row: SqliteDecodeRow,
748 {
749 }
750
751 impl<Row> MaybeNullCompatible<Row, Option<i64>, $actual> for ()
752 where
753 Row: SqliteDecodeRow,
754 {
755 }
756 )+
757 };
758}
759
760impl_sqlite_join_nullable_integer_decode_compat!(
761 i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
762);
763
764impl_sqlite_integer_decode_compat!(
765 Option<i64> =>
766 Option<i8>,
767 Option<i16>,
768 Option<i32>,
769 Option<isize>,
770 Option<u8>,
771 Option<u16>,
772 Option<u32>,
773 Option<u64>,
774 Option<usize>,
775 Option<bool>
776);
777
778macro_rules! impl_row_column_list_one {
779 ($($ty:ty),+ $(,)?) => {
780 $(
781 impl<Row: ?Sized> RowColumnList<Row> for $ty {
782 type Columns = crate::Cons<$ty, crate::Nil>;
783 }
784 )+
785 };
786}
787
788impl_row_column_list_one!(
789 i8,
790 i16,
791 i32,
792 i64,
793 isize,
794 u8,
795 u16,
796 u32,
797 u64,
798 usize,
799 f32,
800 f64,
801 bool,
802 crate::prelude::String,
803 crate::prelude::Vec<u8>
804);
805
806impl<Row: ?Sized> RowColumnList<Row> for () {
807 type Columns = crate::Cons<(), crate::Nil>;
808}
809
810#[cfg(feature = "uuid")]
811impl<Row: ?Sized> RowColumnList<Row> for uuid::Uuid {
812 type Columns = crate::Cons<Self, crate::Nil>;
813}
814
815#[cfg(feature = "chrono")]
816impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDate {
817 type Columns = crate::Cons<Self, crate::Nil>;
818}
819
820#[cfg(feature = "chrono")]
821impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveTime {
822 type Columns = crate::Cons<Self, crate::Nil>;
823}
824
825#[cfg(feature = "chrono")]
826impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDateTime {
827 type Columns = crate::Cons<Self, crate::Nil>;
828}
829
830#[cfg(feature = "chrono")]
831impl<Row: ?Sized> RowColumnList<Row> for chrono::DateTime<chrono::Utc> {
832 type Columns = crate::Cons<Self, crate::Nil>;
833}
834
835#[cfg(feature = "serde")]
836impl<Row: ?Sized> RowColumnList<Row> for serde_json::Value {
837 type Columns = crate::Cons<Self, crate::Nil>;
838}
839
840#[cfg(feature = "rust-decimal")]
841impl<Row: ?Sized> RowColumnList<Row> for rust_decimal::Decimal {
842 type Columns = crate::Cons<Self, crate::Nil>;
843}
844
845#[cfg(feature = "chrono")]
846impl<Row: ?Sized> RowColumnList<Row> for chrono::Duration {
847 type Columns = crate::Cons<Self, crate::Nil>;
848}
849
850#[cfg(feature = "time")]
851impl<Row: ?Sized> RowColumnList<Row> for time::Date {
852 type Columns = crate::Cons<Self, crate::Nil>;
853}
854
855#[cfg(feature = "time")]
856impl<Row: ?Sized> RowColumnList<Row> for time::Time {
857 type Columns = crate::Cons<Self, crate::Nil>;
858}
859
860#[cfg(feature = "time")]
861impl<Row: ?Sized> RowColumnList<Row> for time::PrimitiveDateTime {
862 type Columns = crate::Cons<Self, crate::Nil>;
863}
864
865#[cfg(feature = "time")]
866impl<Row: ?Sized> RowColumnList<Row> for time::OffsetDateTime {
867 type Columns = crate::Cons<Self, crate::Nil>;
868}
869
870#[cfg(feature = "time")]
871impl<Row: ?Sized> RowColumnList<Row> for time::Duration {
872 type Columns = crate::Cons<Self, crate::Nil>;
873}
874
875#[cfg(feature = "jiff")]
876impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Date {
877 type Columns = crate::Cons<Self, crate::Nil>;
878}
879
880#[cfg(feature = "jiff")]
881impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Time {
882 type Columns = crate::Cons<Self, crate::Nil>;
883}
884
885#[cfg(feature = "jiff")]
886impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::DateTime {
887 type Columns = crate::Cons<Self, crate::Nil>;
888}
889
890#[cfg(feature = "jiff")]
891impl<Row: ?Sized> RowColumnList<Row> for jiff::Timestamp {
892 type Columns = crate::Cons<Self, crate::Nil>;
893}
894
895#[cfg(feature = "cidr")]
896impl<Row: ?Sized> RowColumnList<Row> for cidr::IpInet {
897 type Columns = crate::Cons<Self, crate::Nil>;
898}
899
900#[cfg(feature = "cidr")]
901impl<Row: ?Sized> RowColumnList<Row> for cidr::IpCidr {
902 type Columns = crate::Cons<Self, crate::Nil>;
903}
904
905#[cfg(feature = "geo-types")]
906impl<Row: ?Sized> RowColumnList<Row> for geo_types::Point<f64> {
907 type Columns = crate::Cons<Self, crate::Nil>;
908}
909
910#[cfg(feature = "geo-types")]
911impl<Row: ?Sized> RowColumnList<Row> for geo_types::LineString<f64> {
912 type Columns = crate::Cons<Self, crate::Nil>;
913}
914
915#[cfg(feature = "geo-types")]
916impl<Row: ?Sized> RowColumnList<Row> for geo_types::Rect<f64> {
917 type Columns = crate::Cons<Self, crate::Nil>;
918}
919
920#[cfg(feature = "bit-vec")]
921impl<Row: ?Sized> RowColumnList<Row> for bit_vec::BitVec {
922 type Columns = crate::Cons<Self, crate::Nil>;
923}
924
925#[cfg(feature = "arrayvec")]
926impl<Row: ?Sized, const N: usize> RowColumnList<Row> for arrayvec::ArrayString<N> {
927 type Columns = crate::Cons<Self, crate::Nil>;
928}
929
930#[cfg(feature = "arrayvec")]
931impl<Row: ?Sized, T, const N: usize> RowColumnList<Row> for arrayvec::ArrayVec<T, N> {
932 type Columns = crate::Cons<Self, crate::Nil>;
933}
934
935impl<Row: ?Sized> RowColumnList<Row> for compact_str::CompactString {
936 type Columns = crate::Cons<Self, crate::Nil>;
937}
938
939#[cfg(feature = "bytes")]
940impl<Row: ?Sized> RowColumnList<Row> for bytes::Bytes {
941 type Columns = crate::Cons<Self, crate::Nil>;
942}
943
944#[cfg(feature = "bytes")]
945impl<Row: ?Sized> RowColumnList<Row> for bytes::BytesMut {
946 type Columns = crate::Cons<Self, crate::Nil>;
947}
948
949impl<Row: ?Sized, A: smallvec::Array> RowColumnList<Row> for smallvec::SmallVec<A> {
950 type Columns = crate::Cons<Self, crate::Nil>;
951}
952
953impl<Row: ?Sized, T> RowColumnList<Row> for Option<T> {
954 type Columns = crate::Cons<Self, crate::Nil>;
955}
956
957macro_rules! impl_rcl_body {
960 ([$A:ident] []) => {
962 impl<Row: ?Sized, $A: RowColumnList<Row>> RowColumnList<Row> for ($A,) {
963 type Columns = <$A as RowColumnList<Row>>::Columns;
964 }
965 };
966 ([$($all:ident),+] [$($prev:ident),+; $last:ident]) => {
968 impl<Row: ?Sized, $($all),+> RowColumnList<Row> for ($($all,)+)
969 where
970 $last: RowColumnList<Row>,
971 ($($prev,)+): RowColumnList<Row>,
972 <($($prev,)+) as RowColumnList<Row>>::Columns:
973 crate::Concat<<$last as RowColumnList<Row>>::Columns>,
974 {
975 type Columns = <<($($prev,)+) as RowColumnList<Row>>::Columns as crate::Concat<
976 <$last as RowColumnList<Row>>::Columns,
977 >>::Output;
978 }
979 };
980}
981
982macro_rules! impl_rcl_tuple {
985 ($($T:ident),+) => {
986 impl_rcl_split!([$($T),+] [] $($T),+);
987 };
988}
989
990macro_rules! impl_rcl_split {
992 ([$A:ident] [] $only:ident) => {
994 impl_rcl_body!([$A] []);
995 };
996 ([$($all:ident),+] [$($prev:ident),+] $last:ident) => {
998 impl_rcl_body!([$($all),+] [$($prev),+; $last]);
999 };
1000 ([$($all:ident),+] [] $head:ident, $($rest:ident),+) => {
1002 impl_rcl_split!([$($all),+] [$head] $($rest),+);
1003 };
1004 ([$($all:ident),+] [$($prev:ident),+] $head:ident, $($rest:ident),+) => {
1006 impl_rcl_split!([$($all),+] [$($prev),+, $head] $($rest),+);
1007 };
1008}
1009
1010with_type_sizes_8!(impl_rcl_tuple);
1011
1012#[cfg(any(
1013 feature = "col16",
1014 feature = "col32",
1015 feature = "col64",
1016 feature = "col128",
1017 feature = "col200"
1018))]
1019with_type_sizes_16!(impl_rcl_tuple);
1020
1021#[cfg(any(
1022 feature = "col32",
1023 feature = "col64",
1024 feature = "col128",
1025 feature = "col200"
1026))]
1027with_type_sizes_32!(impl_rcl_tuple);
1028
1029#[diagnostic::on_unimplemented(
1046 message = "selected shape does not match decode target `{Actual}`",
1047 label = "this decode target is not type-compatible with .select(...) output",
1048 note = "use typed expressions or derive FromRow for explicit remapping when selecting custom expressions"
1049)]
1050pub trait MarkerColumnCountValid<Row: ?Sized, Inferred, Actual, Proof = ()> {}
1051
1052#[diagnostic::on_unimplemented(
1059 message = "raw select expressions require explicit typing in strict decode",
1060 label = "`select(sql!(...)).all()/get()` is not allowed in strict mode",
1061 note = "use typed wrappers like `raw_non_null`/`raw_nullable` or derive FromRow"
1062)]
1063pub trait StrictDecodeMarker {}
1064
1065impl StrictDecodeMarker for SelectStar {}
1066impl<Cols> StrictDecodeMarker for SelectCols<Cols> {}
1067impl<R> StrictDecodeMarker for SelectAs<R> {}
1068impl<M, Scope, Used> StrictDecodeMarker for Scoped<M, Scope, Used> where M: StrictDecodeMarker {}
1069
1070impl<Row: ?Sized, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1071 for SelectStar
1072{
1073}
1074
1075impl<Row: ?Sized, Cols, Inferred, Actual, Proof>
1076 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for SelectCols<Cols>
1077where
1078 Cols: SelectedColumnList,
1079 Actual: RowColumnList<Row>,
1080 <Cols as SelectedColumnList>::Columns:
1081 TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
1082{
1083}
1084
1085impl<Row: ?Sized, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1086 for SelectExpr
1087where
1088 Inferred: SameType<Actual>,
1089{
1090}
1091
1092impl<Row: ?Sized, R, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1093 for SelectAs<R>
1094{
1095}
1096
1097impl<Row: ?Sized, Table, Used, Inferred, Actual, Proof>
1099 MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1100 for Scoped<SelectStar, Cons<Table, Nil>, Used>
1101{
1102}
1103
1104impl<Row: ?Sized, First, Second, Rest, Used, Inferred, Actual, Proof>
1107 MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1108 for Scoped<SelectStar, Cons<First, Cons<Second, Rest>>, Used>
1109where
1110 Inferred: JoinedStarRow<Actual>,
1111{
1112}
1113
1114impl<Row: ?Sized, Cols, Scope, Used, Inferred, Actual, UsedProof, ColsProof>
1115 MarkerColumnCountValid<Row, Inferred, Actual, (UsedProof, ColsProof)>
1116 for Scoped<SelectCols<Cols>, Scope, Used>
1117where
1118 Cols: SelectedExpressionList,
1119 Cols::Expressions: ProjectionIn<Scope, ColsProof>,
1120 Actual: RowColumnList<Row>,
1121 <Cols::Expressions as ProjectionIn<Scope, ColsProof>>::Columns:
1122 TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
1123{
1124}
1125
1126impl<Row: ?Sized, Scope, Used, Inferred, Actual, Proof>
1127 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for Scoped<SelectExpr, Scope, Used>
1128where
1129 Inferred: SameType<Actual>,
1130{
1131}
1132
1133impl<Row: ?Sized, R, Scope, Used, Inferred, Actual, Proof>
1135 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for Scoped<SelectAs<R>, Scope, Used>
1136{
1137}
1138
1139#[diagnostic::on_unimplemented(
1145 message = "joined `SELECT *` rows decode as `{Self}`, not `{Actual}`",
1146 label = "the decode target does not match the joined row type",
1147 note = "LEFT/RIGHT/FULL JOIN sources can be NULL: decode them as `Option<_>`, \
1148 e.g. `(SelectUsers, Option<SelectPosts>)` after `.left_join(posts)`"
1149)]
1150pub trait JoinedStarRow<Actual> {}
1151
1152impl<A, B, ActualA, ActualB> JoinedStarRow<(ActualA, ActualB)> for (A, B)
1153where
1154 A: JoinedStarPart<ActualA>,
1155 B: JoinedStarPart<ActualB>,
1156{
1157}
1158
1159#[doc(hidden)]
1161#[diagnostic::on_unimplemented(
1162 message = "this half of the joined `SELECT *` row decodes as `{Self}`, not `{Actual}`",
1163 label = "the decode target does not match the joined row type",
1164 note = "LEFT/RIGHT/FULL JOIN sources can be NULL: decode them as `Option<_>`"
1165)]
1166pub trait JoinedStarPart<Actual> {}
1167
1168impl<T> JoinedStarPart<T> for T {}
1169
1170impl<T> JoinedStarPart<Option<T>> for T {}
1171
1172pub trait DecodeSelectedRef<RowRef, R> {
1177 fn decode(row: RowRef) -> Result<R, DrizzleError>;
1184}
1185
1186impl<RowRef, R> DecodeSelectedRef<RowRef, R> for SelectAs<R>
1187where
1188 R: TryFrom<RowRef>,
1189 <R as TryFrom<RowRef>>::Error: Into<DrizzleError>,
1190{
1191 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1192 R::try_from(row).map_err(Into::into)
1193 }
1194}
1195
1196impl<RowRef, R, M, Scope, Used> DecodeSelectedRef<RowRef, R> for Scoped<M, Scope, Used>
1197where
1198 M: DecodeSelectedRef<RowRef, R>,
1199{
1200 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1201 M::decode(row)
1202 }
1203}
1204
1205impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectStar
1206where
1207 RowRef: core::ops::Deref<Target = Row>,
1208 R: FromDrizzleRow<Row>,
1209{
1210 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1211 R::from_row(&*row)
1212 }
1213}
1214
1215impl<RowRef, Row: ?Sized, Cols, R> DecodeSelectedRef<RowRef, R> for SelectCols<Cols>
1216where
1217 RowRef: core::ops::Deref<Target = Row>,
1218 R: FromDrizzleRow<Row>,
1219{
1220 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1221 R::from_row(&*row)
1222 }
1223}
1224
1225impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectExpr
1226where
1227 RowRef: core::ops::Deref<Target = Row>,
1228 R: FromDrizzleRow<Row>,
1229{
1230 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1231 R::from_row(&*row)
1232 }
1233}
1234
1235#[diagnostic::on_unimplemented(
1248 message = "cannot deserialize `{Self}` from a database row",
1249 label = "this type does not implement FromDrizzleRow",
1250 note = "derive #[SQLiteFromRow], #[PostgresFromRow], or #[MySQLFromRow]"
1251)]
1252pub trait FromDrizzleRow<Row: ?Sized>: Sized {
1253 const COLUMN_COUNT: usize;
1255
1256 fn from_row_at(row: &Row, offset: usize) -> Result<Self, DrizzleError>;
1263
1264 fn from_row(row: &Row) -> Result<Self, DrizzleError> {
1270 Self::from_row_at(row, 0)
1271 }
1272}
1273
1274pub trait NullProbeRow<Row: ?Sized>: FromDrizzleRow<Row> {
1282 fn is_null_at(row: &Row, offset: usize) -> Result<bool, DrizzleError>;
1289}
1290
1291macro_rules! impl_from_drizzle_row_tuple {
1294 ($($T:ident),+; $($idx:tt),+) => {
1295 impl<__Row: ?Sized, $($T: FromDrizzleRow<__Row>),+> FromDrizzleRow<__Row> for ($($T,)+) {
1296 const COLUMN_COUNT: usize = 0 $(+ <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT)+;
1297
1298 #[allow(non_snake_case)]
1299 fn from_row_at(
1300 row: &__Row,
1301 offset: usize,
1302 ) -> Result<Self, DrizzleError> {
1303 let mut __off = offset;
1304 $(
1305 let $T = <$T as FromDrizzleRow<__Row>>::from_row_at(row, __off)?;
1306 __off += <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT;
1307 )+
1308 Ok(($($T,)+))
1309 }
1310 }
1311 };
1312}
1313
1314with_col_sizes_8!(impl_from_drizzle_row_tuple);
1315
1316#[cfg(any(
1317 feature = "col16",
1318 feature = "col32",
1319 feature = "col64",
1320 feature = "col128",
1321 feature = "col200"
1322))]
1323with_col_sizes_16!(impl_from_drizzle_row_tuple);
1324
1325#[cfg(any(
1326 feature = "col32",
1327 feature = "col64",
1328 feature = "col128",
1329 feature = "col200"
1330))]
1331with_col_sizes_32!(impl_from_drizzle_row_tuple);
1332
1333#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1334with_col_sizes_64!(impl_from_drizzle_row_tuple);
1335
1336#[cfg(any(feature = "col128", feature = "col200"))]
1337with_col_sizes_128!(impl_from_drizzle_row_tuple);
1338
1339#[cfg(feature = "col200")]
1340with_col_sizes_200!(impl_from_drizzle_row_tuple);
1341
1342#[diagnostic::on_unimplemented(
1359 message = "SQL type `{Self}` has no default Rust mapping for dialect `{D}`",
1360 label = "this SQL type has no default Rust mapping for this dialect",
1361 note = "enable `chrono` for Date/Time/Timestamp/TimestampTz, `uuid` for Uuid, or `serde` for Json/Jsonb"
1362)]
1363pub trait SQLTypeToRust<D> {
1364 type RustType;
1365}
1366
1367use crate::dialect::{MySQLDialect, PostgresDialect, SQLiteDialect};
1370
1371impl<D, T> SQLTypeToRust<D> for crate::types::Array<T>
1372where
1373 T: crate::types::DataType + SQLTypeToRust<D>,
1374{
1375 type RustType = crate::prelude::Vec<<T as SQLTypeToRust<D>>::RustType>;
1376}
1377
1378impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Integer {
1379 type RustType = i64;
1380}
1381
1382impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Text {
1383 type RustType = crate::prelude::String;
1384}
1385
1386impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Real {
1387 type RustType = f64;
1388}
1389
1390impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Blob {
1391 type RustType = crate::prelude::Vec<u8>;
1392}
1393
1394impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Numeric {
1395 type RustType = f64;
1396}
1397
1398impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Any {
1399 type RustType = crate::prelude::String;
1400}
1401
1402macro_rules! impl_mysql_sql_type_to_rust {
1403 ($rust:ty => $($sql:ty),+ $(,)?) => {
1404 $(
1405 impl SQLTypeToRust<MySQLDialect> for $sql {
1406 type RustType = $rust;
1407 }
1408 )+
1409 };
1410}
1411
1412impl_mysql_sql_type_to_rust!(i8 => drizzle_types::mysql::types::TinyInt);
1413impl_mysql_sql_type_to_rust!(u8 => drizzle_types::mysql::types::TinyIntUnsigned);
1414impl_mysql_sql_type_to_rust!(i16 => drizzle_types::mysql::types::SmallInt);
1415impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::SmallIntUnsigned);
1416impl_mysql_sql_type_to_rust!(i32 =>
1417 drizzle_types::mysql::types::MediumInt,
1418 drizzle_types::mysql::types::Int,
1419);
1420impl_mysql_sql_type_to_rust!(u32 =>
1421 drizzle_types::mysql::types::MediumIntUnsigned,
1422 drizzle_types::mysql::types::IntUnsigned,
1423);
1424impl_mysql_sql_type_to_rust!(i64 => drizzle_types::mysql::types::BigInt);
1425impl_mysql_sql_type_to_rust!(u64 => drizzle_types::mysql::types::BigIntUnsigned);
1426impl_mysql_sql_type_to_rust!(f32 => drizzle_types::mysql::types::Float);
1427impl_mysql_sql_type_to_rust!(f64 => drizzle_types::mysql::types::Double);
1428impl_mysql_sql_type_to_rust!(bool => drizzle_types::mysql::types::Boolean);
1429impl_mysql_sql_type_to_rust!(crate::prelude::String =>
1430 drizzle_types::mysql::types::Char,
1431 drizzle_types::mysql::types::Varchar,
1432 drizzle_types::mysql::types::TinyText,
1433 drizzle_types::mysql::types::Text,
1434 drizzle_types::mysql::types::MediumText,
1435 drizzle_types::mysql::types::LongText,
1436 drizzle_types::mysql::types::Enum,
1437 drizzle_types::mysql::types::Set,
1438 drizzle_types::mysql::types::Any,
1439);
1440impl_mysql_sql_type_to_rust!(crate::prelude::Vec<u8> =>
1441 drizzle_types::mysql::types::Binary,
1442 drizzle_types::mysql::types::Varbinary,
1443 drizzle_types::mysql::types::TinyBlob,
1444 drizzle_types::mysql::types::Blob,
1445 drizzle_types::mysql::types::MediumBlob,
1446 drizzle_types::mysql::types::LongBlob,
1447 drizzle_types::mysql::types::Bit,
1448);
1449impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::Year);
1450
1451#[cfg(feature = "rust-decimal")]
1452impl_mysql_sql_type_to_rust!(rust_decimal::Decimal => drizzle_types::mysql::types::Decimal);
1453#[cfg(not(feature = "rust-decimal"))]
1454impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Decimal);
1455
1456#[cfg(feature = "serde")]
1457impl_mysql_sql_type_to_rust!(serde_json::Value => drizzle_types::mysql::types::Json);
1458#[cfg(not(feature = "serde"))]
1459impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Json);
1460
1461#[cfg(feature = "chrono")]
1462impl_mysql_sql_type_to_rust!(chrono::NaiveDate => drizzle_types::mysql::types::Date);
1463#[cfg(all(not(feature = "chrono"), feature = "time"))]
1464impl_mysql_sql_type_to_rust!(time::Date => drizzle_types::mysql::types::Date);
1465#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1466impl_mysql_sql_type_to_rust!(jiff::civil::Date => drizzle_types::mysql::types::Date);
1467#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
1468impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Date);
1469
1470impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Time);
1475
1476#[cfg(feature = "chrono")]
1477impl_mysql_sql_type_to_rust!(chrono::NaiveDateTime => drizzle_types::mysql::types::DateTime);
1478#[cfg(feature = "chrono")]
1482impl_mysql_sql_type_to_rust!(chrono::DateTime<chrono::Utc> => drizzle_types::mysql::types::Timestamp);
1483#[cfg(all(not(feature = "chrono"), feature = "time"))]
1484impl_mysql_sql_type_to_rust!(time::PrimitiveDateTime => drizzle_types::mysql::types::DateTime);
1485#[cfg(all(not(feature = "chrono"), feature = "time"))]
1486impl_mysql_sql_type_to_rust!(time::OffsetDateTime => drizzle_types::mysql::types::Timestamp);
1487#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1488impl_mysql_sql_type_to_rust!(jiff::civil::DateTime => drizzle_types::mysql::types::DateTime);
1489#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1490impl_mysql_sql_type_to_rust!(jiff::Timestamp => drizzle_types::mysql::types::Timestamp);
1491#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
1492impl_mysql_sql_type_to_rust!(crate::prelude::String =>
1493 drizzle_types::mysql::types::DateTime,
1494 drizzle_types::mysql::types::Timestamp,
1495);
1496
1497impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int2 {
1498 type RustType = i16;
1499}
1500
1501impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int4 {
1502 type RustType = i32;
1503}
1504
1505impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int8 {
1506 type RustType = i64;
1507}
1508
1509impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float4 {
1510 type RustType = f32;
1511}
1512
1513impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float8 {
1514 type RustType = f64;
1515}
1516
1517impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Varchar {
1518 type RustType = crate::prelude::String;
1519}
1520
1521impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Text {
1522 type RustType = crate::prelude::String;
1523}
1524
1525impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Char {
1526 type RustType = crate::prelude::String;
1527}
1528
1529impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Bytea {
1530 type RustType = crate::prelude::Vec<u8>;
1531}
1532
1533impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Boolean {
1534 type RustType = bool;
1535}
1536
1537#[cfg(feature = "rust-decimal")]
1538impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
1539 type RustType = rust_decimal::Decimal;
1540}
1541
1542#[cfg(not(feature = "rust-decimal"))]
1543impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
1544 type RustType = crate::prelude::String;
1545}
1546
1547impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Any {
1548 type RustType = crate::prelude::String;
1549}
1550
1551#[cfg(feature = "chrono")]
1552impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1553 type RustType = chrono::DateTime<chrono::Utc>;
1554}
1555
1556#[cfg(feature = "chrono")]
1557impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1558 type RustType = chrono::NaiveDateTime;
1559}
1560
1561#[cfg(feature = "chrono")]
1562impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1563 type RustType = chrono::NaiveDate;
1564}
1565
1566#[cfg(feature = "chrono")]
1567impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1568 type RustType = chrono::NaiveTime;
1569}
1570
1571#[cfg(feature = "chrono")]
1572impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timetz {
1573 type RustType = chrono::NaiveTime;
1574}
1575
1576#[cfg(all(not(feature = "chrono"), feature = "time"))]
1577impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1578 type RustType = time::OffsetDateTime;
1579}
1580
1581#[cfg(all(not(feature = "chrono"), feature = "time"))]
1582impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1583 type RustType = time::PrimitiveDateTime;
1584}
1585
1586#[cfg(all(not(feature = "chrono"), feature = "time"))]
1587impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1588 type RustType = time::Date;
1589}
1590
1591#[cfg(all(not(feature = "chrono"), feature = "time"))]
1592impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1593 type RustType = time::Time;
1594}
1595
1596#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1597impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1598 type RustType = jiff::Timestamp;
1599}
1600
1601#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1602impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1603 type RustType = jiff::civil::DateTime;
1604}
1605
1606#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1607impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1608 type RustType = jiff::civil::Date;
1609}
1610
1611#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1612impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1613 type RustType = jiff::civil::Time;
1614}
1615
1616#[cfg(feature = "uuid")]
1617impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Uuid {
1618 type RustType = uuid::Uuid;
1619}
1620
1621#[cfg(feature = "serde")]
1622impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Json {
1623 type RustType = serde_json::Value;
1624}
1625
1626#[cfg(feature = "serde")]
1627impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Jsonb {
1628 type RustType = serde_json::Value;
1629}
1630
1631#[cfg(feature = "chrono")]
1634impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
1635 type RustType = chrono::Duration;
1636}
1637
1638#[cfg(not(feature = "chrono"))]
1639impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
1640 type RustType = crate::prelude::String;
1641}
1642
1643#[cfg(feature = "cidr")]
1644impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
1645 type RustType = cidr::IpInet;
1646}
1647
1648#[cfg(not(feature = "cidr"))]
1649impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
1650 type RustType = crate::prelude::String;
1651}
1652
1653#[cfg(feature = "cidr")]
1654impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
1655 type RustType = cidr::IpCidr;
1656}
1657
1658#[cfg(not(feature = "cidr"))]
1659impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
1660 type RustType = crate::prelude::String;
1661}
1662
1663impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr {
1664 type RustType = crate::prelude::String;
1665}
1666
1667impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr8 {
1668 type RustType = crate::prelude::String;
1669}
1670
1671#[cfg(feature = "geo-types")]
1672impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
1673 type RustType = geo_types::Point<f64>;
1674}
1675
1676#[cfg(not(feature = "geo-types"))]
1677impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
1678 type RustType = crate::prelude::String;
1679}
1680
1681#[cfg(feature = "geo-types")]
1682impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
1683 type RustType = geo_types::LineString<f64>;
1684}
1685
1686#[cfg(not(feature = "geo-types"))]
1687impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
1688 type RustType = crate::prelude::String;
1689}
1690
1691#[cfg(feature = "geo-types")]
1692impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
1693 type RustType = geo_types::Rect<f64>;
1694}
1695
1696#[cfg(not(feature = "geo-types"))]
1697impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
1698 type RustType = crate::prelude::String;
1699}
1700
1701#[cfg(feature = "bit-vec")]
1702impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
1703 type RustType = bit_vec::BitVec;
1704}
1705
1706#[cfg(not(feature = "bit-vec"))]
1707impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
1708 type RustType = crate::prelude::String;
1709}
1710
1711impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Line {
1712 type RustType = crate::prelude::String;
1713}
1714
1715impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineSegment {
1716 type RustType = crate::prelude::String;
1717}
1718
1719impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Polygon {
1720 type RustType = crate::prelude::String;
1721}
1722
1723impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Circle {
1724 type RustType = crate::prelude::String;
1725}
1726
1727impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Enum {
1728 type RustType = crate::prelude::String;
1729}
1730
1731pub trait WrapNullable<T> {
1738 type Output;
1740}
1741
1742impl<T> WrapNullable<T> for crate::expr::NonNull {
1743 type Output = T;
1744}
1745
1746impl<T> WrapNullable<T> for crate::expr::Null {
1747 type Output = Option<T>;
1748}
1749
1750#[diagnostic::on_unimplemented(
1763 message = "cannot infer Rust type for expression `{Self}`",
1764 label = "use typed expressions or derive FromRow to specify the Rust type",
1765 note = "raw SQL and JSON expressions require explicit type annotation"
1766)]
1767pub trait ExprValueType {
1768 type ValueType;
1770}
1771
1772impl<T: ExprValueType + ?Sized> ExprValueType for &T {
1773 type ValueType = T::ValueType;
1774}
1775
1776impl<V: crate::SQLParam, T, N, A, S> ExprValueType for crate::expr::SQLExpr<'_, V, T, N, A, S>
1777where
1778 T: crate::types::DataType + SQLTypeToRust<V::DialectMarker>,
1779 N: crate::expr::Nullability + WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>,
1780 A: crate::expr::AggregateKind,
1781{
1782 type ValueType = <N as WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>>::Output;
1783}
1784
1785impl<V: crate::SQLParam> ExprValueType for crate::sql::SQL<'_, V> {
1787 type ValueType = ();
1788}
1789
1790#[diagnostic::on_unimplemented(
1799 message = "`{Self}` is not a drizzle table",
1800 label = "ensure this type was derived with #[SQLiteTable], #[PostgresTable], or #[MySQLTable]"
1801)]
1802pub trait HasSelectModel {
1803 type SelectModel;
1805 const COLUMN_COUNT: usize;
1807}
1808
1809impl<T: HasSelectModel + ?Sized> HasSelectModel for &T {
1810 type SelectModel = T::SelectModel;
1811
1812 const COLUMN_COUNT: usize = T::COLUMN_COUNT;
1813}
1814
1815#[diagnostic::on_unimplemented(
1825 message = "cannot resolve return type for this query",
1826 label = "the selected columns and table do not produce a known row type"
1827)]
1828pub trait ResolveRow<Table> {
1829 type Row;
1831}
1832
1833impl<T: HasSelectModel> ResolveRow<T> for SelectStar {
1834 type Row = T::SelectModel;
1835}
1836
1837impl<T> ResolveRow<T> for SelectExpr {
1838 type Row = ();
1839}
1840
1841impl<R, T> ResolveRow<T> for SelectAs<R>
1842where
1843 R: SelectAsFrom<T>,
1844{
1845 type Row = R;
1846}
1847
1848impl<M, Scope, Used, T> ResolveRow<T> for Scoped<M, Scope, Used>
1849where
1850 M: ResolveRow<T>,
1851{
1852 type Row = M::Row;
1853}
1854
1855#[diagnostic::on_unimplemented(
1861 message = "row selector `{Self}` cannot be used with table `{Table}`",
1862 label = "the #[from(...)] table does not match .from(...)",
1863 note = "set #[from(TheTable)] to the same table passed to .from(...)"
1864)]
1865pub trait SelectAsFrom<Table> {}
1866
1867macro_rules! impl_resolve_row_cols {
1870 ($($T:ident),+; $($idx:tt),+) => {
1871 impl<__Table, $($T: ExprValueType),+> ResolveRow<__Table> for SelectCols<($($T,)+)> {
1872 type Row = ($(<$T as ExprValueType>::ValueType,)+);
1873 }
1874 };
1875}
1876
1877with_col_sizes_8!(impl_resolve_row_cols);
1878
1879#[cfg(any(
1880 feature = "col16",
1881 feature = "col32",
1882 feature = "col64",
1883 feature = "col128",
1884 feature = "col200"
1885))]
1886with_col_sizes_16!(impl_resolve_row_cols);
1887
1888#[cfg(any(
1889 feature = "col32",
1890 feature = "col64",
1891 feature = "col128",
1892 feature = "col200"
1893))]
1894with_col_sizes_32!(impl_resolve_row_cols);
1895
1896#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1897with_col_sizes_64!(impl_resolve_row_cols);
1898
1899#[cfg(any(feature = "col128", feature = "col200"))]
1900with_col_sizes_128!(impl_resolve_row_cols);
1901
1902#[cfg(feature = "col200")]
1903with_col_sizes_200!(impl_resolve_row_cols);
1904
1905macro_rules! selected_columns_cons {
1906 () => {
1907 crate::Nil
1908 };
1909 ($head:ident $(, $tail:ident)*) => {
1910 crate::Cons<<$head as ExprValueType>::ValueType, selected_columns_cons!($($tail),*)>
1911 };
1912}
1913
1914macro_rules! selected_expressions_cons {
1915 () => {
1916 crate::Nil
1917 };
1918 ($head:ident $(, $tail:ident)*) => {
1919 crate::Cons<$head, selected_expressions_cons!($($tail),*)>
1920 };
1921}
1922
1923macro_rules! impl_selected_column_list_tuple {
1924 ($($T:ident),+; $($idx:tt),+) => {
1925 impl<$($T: ExprValueType),+> SelectedColumnList for ($($T,)+) {
1926 type Columns = selected_columns_cons!($($T),+);
1927 }
1928 };
1929}
1930
1931macro_rules! impl_selected_expression_list_tuple {
1932 ($($T:ident),+; $($idx:tt),+) => {
1933 impl<$($T),+> SelectedExpressionList for ($($T,)+) {
1934 type Expressions = selected_expressions_cons!($($T),+);
1935 }
1936 };
1937}
1938
1939with_col_sizes_8!(impl_selected_column_list_tuple);
1940with_col_sizes_8!(impl_selected_expression_list_tuple);
1941
1942#[cfg(any(
1943 feature = "col16",
1944 feature = "col32",
1945 feature = "col64",
1946 feature = "col128",
1947 feature = "col200"
1948))]
1949with_col_sizes_16!(impl_selected_column_list_tuple);
1950#[cfg(any(
1951 feature = "col16",
1952 feature = "col32",
1953 feature = "col64",
1954 feature = "col128",
1955 feature = "col200"
1956))]
1957with_col_sizes_16!(impl_selected_expression_list_tuple);
1958
1959#[cfg(any(
1960 feature = "col32",
1961 feature = "col64",
1962 feature = "col128",
1963 feature = "col200"
1964))]
1965with_col_sizes_32!(impl_selected_column_list_tuple);
1966#[cfg(any(
1967 feature = "col32",
1968 feature = "col64",
1969 feature = "col128",
1970 feature = "col200"
1971))]
1972with_col_sizes_32!(impl_selected_expression_list_tuple);
1973
1974#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1975with_col_sizes_64!(impl_selected_column_list_tuple);
1976#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1977with_col_sizes_64!(impl_selected_expression_list_tuple);
1978
1979#[cfg(any(feature = "col128", feature = "col200"))]
1980with_col_sizes_128!(impl_selected_column_list_tuple);
1981#[cfg(any(feature = "col128", feature = "col200"))]
1982with_col_sizes_128!(impl_selected_expression_list_tuple);
1983
1984#[cfg(feature = "col200")]
1985with_col_sizes_200!(impl_selected_column_list_tuple);
1986#[cfg(feature = "col200")]
1987with_col_sizes_200!(impl_selected_expression_list_tuple);
1988
1989use crate::scope::{FullJoin, InnerJoin, JoinRow, LeftJoin, RightJoin};
1994
1995impl<R, T, Kind> JoinRow<R, T, crate::scope::Lateral<Kind>> for SelectStar
1997where
1998 SelectStar: JoinRow<R, T, Kind>,
1999{
2000 type Row = <SelectStar as JoinRow<R, T, Kind>>::Row;
2001}
2002
2003#[doc(hidden)]
2010pub trait LeftLateralSelection<Proof = ()>: left_lateral_private::Sealed {}
2011
2012mod left_lateral_private {
2013 pub trait Sealed {}
2014
2015 impl Sealed for super::SelectStar {}
2016 impl<Scope, Used> Sealed for super::Scoped<super::SelectStar, Scope, Used> {}
2017 impl<Columns, Scope, Used> Sealed for super::Scoped<super::SelectCols<Columns>, Scope, Used> {}
2018 impl<Row, Scope, Used> Sealed for super::Scoped<super::SelectAs<Row>, Scope, Used> {}
2019}
2020
2021impl LeftLateralSelection for SelectStar {}
2022impl<Scope, Used> LeftLateralSelection for Scoped<SelectStar, Scope, Used> {}
2023
2024impl<Columns, Scope, Used, Proof> LeftLateralSelection<Proof>
2025 for Scoped<SelectCols<Columns>, Scope, Used>
2026where
2027 Columns: SelectedExpressionList,
2028 Columns::Expressions: ProjectionIn<Scope, Proof>,
2029{
2030}
2031
2032impl<Row, Scope, Used, Proof> LeftLateralSelection<Proof> for Scoped<SelectAs<Row>, Scope, Used>
2033where
2034 Row: SelectTableFields,
2035 Row::TableFields: TableFieldsIn<Scope, Proof>,
2036{
2037}
2038
2039impl<R, T: HasSelectModel> JoinRow<R, T, InnerJoin> for SelectStar {
2041 type Row = (R, T::SelectModel);
2042}
2043
2044impl<R, T: HasSelectModel> JoinRow<R, T, LeftJoin> for SelectStar {
2046 type Row = (R, Option<T::SelectModel>);
2047}
2048
2049impl<R, T: HasSelectModel> JoinRow<R, T, RightJoin> for SelectStar {
2051 type Row = (Option<R>, T::SelectModel);
2052}
2053
2054impl<R, T: HasSelectModel> JoinRow<R, T, FullJoin> for SelectStar {
2056 type Row = (Option<R>, Option<T::SelectModel>);
2057}
2058
2059impl<Cols, R, T, Kind> JoinRow<R, T, Kind> for SelectCols<Cols> {
2061 type Row = R;
2062}
2063
2064impl<R, T, Kind> JoinRow<R, T, Kind> for SelectExpr {
2066 type Row = R;
2067}
2068
2069impl<Row, R, T, Kind> JoinRow<R, T, Kind> for SelectAs<Row> {
2071 type Row = R;
2072}
2073
2074#[diagnostic::on_unimplemented(
2094 message = "`{Self}` cannot be used as a select target",
2095 label = "this type does not implement IntoSelectTarget",
2096 note = "implement IntoSelectTarget or use a column, table, or typed expression"
2097)]
2098pub trait IntoSelectTarget {
2099 type Marker;
2101}
2102
2103impl<T: IntoSelectTarget + ?Sized> IntoSelectTarget for &T {
2104 type Marker = T::Marker;
2105}
2106
2107impl IntoSelectTarget for () {
2109 type Marker = SelectStar;
2110}
2111
2112impl<V: crate::SQLParam> IntoSelectTarget for crate::sql::SQL<'_, V> {
2114 type Marker = SelectExpr;
2115}
2116
2117impl<V: crate::SQLParam, T, N, A, S> IntoSelectTarget for crate::expr::SQLExpr<'_, V, T, N, A, S>
2119where
2120 T: crate::types::DataType,
2121 N: crate::expr::Nullability,
2122 A: crate::expr::AggregateKind,
2123{
2124 type Marker = SelectCols<(Self,)>;
2125}
2126
2127macro_rules! impl_into_select_target_tuple {
2129 ($($T:ident),+; $($idx:tt),+) => {
2130 impl<$($T),+> IntoSelectTarget for ($($T,)+) {
2131 type Marker = SelectCols<($($T,)+)>;
2132 }
2133 };
2134}
2135
2136with_col_sizes_8!(impl_into_select_target_tuple);
2137
2138#[cfg(any(
2139 feature = "col16",
2140 feature = "col32",
2141 feature = "col64",
2142 feature = "col128",
2143 feature = "col200"
2144))]
2145with_col_sizes_16!(impl_into_select_target_tuple);
2146
2147#[cfg(any(
2148 feature = "col32",
2149 feature = "col64",
2150 feature = "col128",
2151 feature = "col200"
2152))]
2153with_col_sizes_32!(impl_into_select_target_tuple);
2154
2155#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
2156with_col_sizes_64!(impl_into_select_target_tuple);
2157
2158#[cfg(any(feature = "col128", feature = "col200"))]
2159with_col_sizes_128!(impl_into_select_target_tuple);
2160
2161#[cfg(feature = "col200")]
2162with_col_sizes_200!(impl_into_select_target_tuple);