1mod count;
32pub use count::{
33 ExactlyOne, GetRow, GroupingRows, QueryRows, RowCount, SelectionRows, StatusRows, ZeroOrMore,
34 first_row,
35};
36
37#[cfg(feature = "libsql")]
39mod libsql;
40#[cfg(any(feature = "tokio-postgres", feature = "postgres-sync"))]
41mod postgres;
42#[cfg(any(feature = "tokio-postgres", feature = "postgres-sync"))]
43#[doc(hidden)]
44pub use postgres::AnyNullProbe;
45#[cfg(feature = "rusqlite")]
46mod rusqlite;
47#[cfg(any(feature = "rusqlite", feature = "libsql", feature = "turso"))]
51pub(crate) mod sqlite_value;
52#[cfg(feature = "turso")]
53mod turso;
54
55use core::marker::PhantomData;
56
57use crate::error::DrizzleError;
58use crate::{Cons, Nil};
59
60#[derive(Debug, Clone, Copy, Default)]
67pub struct SelectStar;
68
69#[derive(Debug, Clone, Copy, Default)]
72pub struct SelectCols<Cols>(PhantomData<Cols>);
73
74#[derive(Debug, Clone, Copy, Default)]
77pub struct SelectExpr;
78
79#[derive(Debug, Clone, Copy, Default)]
82pub struct SelectAs<R>(PhantomData<R>);
83
84pub use crate::scope::{
85 HasScope, OuterJoined, ScopeContains, ScopeEntry, ScopeHere, ScopeThere, Scoped,
86};
87
88pub trait MarkerScopeValidFor<Proof> {}
162
163impl<Scope, Used, Proof> MarkerScopeValidFor<Proof> for Scoped<SelectStar, Scope, Used> where
164 Used: SourcesIn<Nil, Proof>
165{
166}
167
168impl<Scope, Used, Proof> MarkerScopeValidFor<Proof> for Scoped<SelectExpr, Scope, Used> where
169 Used: SourcesIn<Nil, Proof>
170{
171}
172
173impl<R, Scope, Used, UsedProof, FieldsProof> MarkerScopeValidFor<(UsedProof, FieldsProof)>
174 for Scoped<SelectAs<R>, Scope, Used>
175where
176 Used: SourcesIn<Nil, UsedProof>,
177 R: SelectTableFields,
178 R::TableFields: TableFieldsIn<Scope, FieldsProof>,
179{
180}
181
182impl<Cols, Scope, Used, UsedProof, ColsProof> MarkerScopeValidFor<(UsedProof, ColsProof)>
183 for Scoped<SelectCols<Cols>, Scope, Used>
184where
185 Used: SourcesIn<Nil, UsedProof>,
186 Cols: SelectedExpressionList,
187 Cols::Expressions: ProjectionIn<Scope, ColsProof>,
188{
189}
190
191use crate::scope::SourcesIn;
192
193#[doc(hidden)]
200#[derive(Debug, Clone, Copy, Default)]
201pub struct MaybeNull<T>(PhantomData<T>);
202
203#[doc(hidden)]
208pub trait ProjectionIn<Scope, Proof> {
209 type Columns: crate::TypeSet;
211}
212
213impl<Scope> ProjectionIn<Scope, ()> for Nil {
214 type Columns = Self;
215}
216
217impl<Head, Tail, Scope, HeadProof, TailProof> ProjectionIn<Scope, (HeadProof, TailProof)>
218 for Cons<Head, Tail>
219where
220 Head: crate::expr::ExprSources + ExprValueType,
221 Head::Sources: SourcesIn<Scope, HeadProof>,
222 Tail: ProjectionIn<Scope, TailProof>,
223{
224 type Columns = Cons<
225 <<Head::Sources as SourcesIn<Scope, HeadProof>>::Nullable as crate::expr::Nullability>::Decoded<
226 Head::ValueType,
227 >,
228 Tail::Columns,
229 >;
230}
231
232pub trait SelectTableFields {
239 type TableFields;
241}
242
243#[derive(Debug, Clone, Copy, Default)]
245pub struct TableFields<Source, Fields>(PhantomData<(Source, Fields)>);
246
247#[doc(hidden)]
251#[diagnostic::on_unimplemented(
252 message = "a field read from the nullable side of an outer join must be an `Option`",
253 label = "LEFT/RIGHT/FULL JOIN can return NULL for every column of this table",
254 note = "change the field type to `Option<_>`, or use an inner join"
255)]
256pub trait FieldsAcceptNullability<Nullable> {}
257
258impl<Fields> FieldsAcceptNullability<crate::expr::NonNull> for Fields {}
259
260impl FieldsAcceptNullability<crate::expr::Null> for Nil {}
261
262impl<T, Tail> FieldsAcceptNullability<crate::expr::Null> for Cons<Option<T>, Tail> where
263 Tail: FieldsAcceptNullability<crate::expr::Null>
264{
265}
266
267#[doc(hidden)]
269pub trait TableFieldsIn<Scope, Proof> {}
270
271impl<Scope> TableFieldsIn<Scope, ()> for Nil {}
272
273impl<Source, Fields, Tail, Scope, Witness, TailProof> TableFieldsIn<Scope, (Witness, TailProof)>
274 for Cons<TableFields<Source, Fields>, Tail>
275where
276 Source: ScopeEntry,
277 Scope: ScopeContains<Source::Key, Witness>,
278 Fields: FieldsAcceptNullability<<Scope as ScopeContains<Source::Key, Witness>>::Nullable>,
279 Tail: TableFieldsIn<Scope, TailProof>,
280{
281}
282
283pub trait AggStatus {
292 type Status;
294}
295
296impl<E: crate::expr::HasAggStatus> AggStatus for (E,) {
298 type Status = E::Status;
299}
300
301macro_rules! impl_tuple_agg_status {
306 ($E0:ident; $i0:tt) => {};
308 ($E0:ident, $E1:ident; $i0:tt, $i1:tt) => {
310 impl<$E0, $E1> AggStatus for ($E0, $E1)
311 where
312 $E0: crate::expr::HasAggStatus,
313 $E1: crate::expr::HasAggStatus,
314 <$E0 as crate::expr::HasAggStatus>::Status:
315 crate::expr::CombineAggStatus<<$E1 as crate::expr::HasAggStatus>::Status>,
316 {
317 type Status = <<$E0 as crate::expr::HasAggStatus>::Status as
318 crate::expr::CombineAggStatus<<$E1 as crate::expr::HasAggStatus>::Status>>::Output;
319 }
320 };
321 ($E0:ident, $E1:ident, $($rest:ident),+; $i0:tt, $i1:tt, $($ri:tt),+) => {
323 impl<$E0, $E1, $($rest),+> AggStatus for ($E0, $E1, $($rest),+)
324 where
325 $E0: crate::expr::HasAggStatus,
326 ($E1, $($rest),+): AggStatus,
327 <$E0 as crate::expr::HasAggStatus>::Status:
328 crate::expr::CombineAggStatus<<($E1, $($rest),+) as AggStatus>::Status>,
329 {
330 type Status = <<$E0 as crate::expr::HasAggStatus>::Status as
331 crate::expr::CombineAggStatus<<($E1, $($rest),+) as AggStatus>::Status>>::Output;
332 }
333 };
334}
335
336with_col_sizes_8!(impl_tuple_agg_status);
337
338#[cfg(any(
339 feature = "col16",
340 feature = "col32",
341 feature = "col64",
342 feature = "col128",
343 feature = "col200"
344))]
345with_col_sizes_16!(impl_tuple_agg_status);
346
347#[cfg(any(
348 feature = "col32",
349 feature = "col64",
350 feature = "col128",
351 feature = "col200"
352))]
353with_col_sizes_32!(impl_tuple_agg_status);
354
355#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
356with_col_sizes_64!(impl_tuple_agg_status);
357
358#[cfg(any(feature = "col128", feature = "col200"))]
359with_col_sizes_128!(impl_tuple_agg_status);
360
361#[cfg(feature = "col200")]
362with_col_sizes_200!(impl_tuple_agg_status);
363
364pub trait IntoGroupBy<'a, V: crate::SQLParam + 'a>:
375 crate::ToSQL<'a, V> + crate::expr::ExprSources
376{
377 type Columns;
380}
381
382#[derive(Debug, Clone, Copy, Default)]
397pub struct PkGroup<Table>(PhantomData<Table>);
398
399macro_rules! impl_into_group_by_tuple {
401 ($T0:ident; $i0:tt) => {};
403 ($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {
405 impl<'a, V: crate::SQLParam + 'a, $T0, $T1> IntoGroupBy<'a, V> for ($T0, $T1)
406 where
407 $T0: crate::ToSQL<'a, V> + crate::expr::ExprSources,
408 $T1: crate::ToSQL<'a, V> + crate::expr::ExprSources,
409 {
410 type Columns = Cons<$T0, Cons<$T1, Nil>>;
411 }
412 };
413 ($T0:ident, $T1:ident, $($rest:ident),+; $i0:tt, $i1:tt, $($ri:tt),+) => {
415 impl<'a, V: crate::SQLParam + 'a, $T0, $T1, $($rest),+> IntoGroupBy<'a, V> for ($T0, $T1, $($rest),+)
416 where
417 $T0: crate::ToSQL<'a, V> + crate::expr::ExprSources,
418 $T1: crate::ToSQL<'a, V> + crate::expr::ExprSources,
419 $($rest: crate::ToSQL<'a, V> + crate::expr::ExprSources,)+
420 {
421 type Columns = impl_into_group_by_tuple!(@cons $T0, $T1, $($rest),+);
422 }
423 };
424 (@cons $T:ident) => { Cons<$T, Nil> };
426 (@cons $T:ident, $($rest:ident),+) => { Cons<$T, impl_into_group_by_tuple!(@cons $($rest),+)> };
427}
428
429with_col_sizes_8!(impl_into_group_by_tuple);
430
431#[cfg(any(
432 feature = "col16",
433 feature = "col32",
434 feature = "col64",
435 feature = "col128",
436 feature = "col200"
437))]
438with_col_sizes_16!(impl_into_group_by_tuple);
439
440#[diagnostic::on_unimplemented(
450 message = "non-aggregate column in SELECT is not in GROUP BY",
451 label = "this column must appear in .group_by(...) or be wrapped in an aggregate function",
452 note = "when using GROUP BY, every non-aggregate column in SELECT must be listed in GROUP BY, \
453 unless the group key is the column's table primary key (`.group_by(table.pk)`)"
454)]
455pub trait ScalarColumnsIn<Grouped, Proof> {}
456
457pub struct AggSkip;
459
460pub struct ScalarCheck<W>(core::marker::PhantomData<W>);
463
464pub struct PkDependent;
467
468impl<E, Grouped, Proof> ScalarColumnsIn<Grouped, (Proof,)> for (E,) where
470 E: SingleColGroupCheck<Grouped, Proof>
471{
472}
473
474#[diagnostic::on_unimplemented(
477 message = "`{Self}` is selected next to an aggregate but is not grouped",
478 label = "this query mixes aggregated and ungrouped columns",
479 note = "add the column to `.group_by(...)`, or wrap it in an aggregate such as `max(...)`"
480)]
481pub trait SingleColGroupCheck<Grouped, Proof> {}
482
483pub trait GroupByIdentity {
488 type Identity;
490}
491
492impl<E: GroupByIdentity> GroupByIdentity for crate::expr::AliasedExpr<E> {
497 type Identity = E::Identity;
498}
499
500impl<V: crate::SQLParam, T, N, A, S> GroupByIdentity for crate::expr::SQLExpr<'_, V, T, N, A, S>
502where
503 T: crate::types::DataType,
504 N: crate::expr::Nullability,
505 A: crate::expr::AggregateKind,
506{
507 type Identity = Self;
508}
509
510impl<Lhs, Rhs, Op, D, SQLType, Nullable> GroupByIdentity
512 for crate::expr::ColumnBinOp<Lhs, Rhs, Op, D, SQLType, Nullable>
513{
514 type Identity = Self;
515}
516
517impl<T, D, SQLType, Nullable> GroupByIdentity for crate::expr::ColumnNeg<T, D, SQLType, Nullable> {
519 type Identity = Self;
520}
521
522impl<E, Grouped> SingleColGroupCheck<Grouped, AggSkip> for E where
524 E: crate::expr::HasAggStatus<Status = crate::expr::AllAgg>
525{
526}
527
528impl<E, Grouped, W> SingleColGroupCheck<Grouped, ScalarCheck<W>> for E
530where
531 E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
532 Grouped: crate::scope::ListContains<E::Identity, W>,
533{
534}
535
536impl<E, T> SingleColGroupCheck<PkGroup<T>, PkDependent> for E
541where
542 E: crate::expr::HasAggStatus<Status = crate::expr::AllScalar> + GroupByIdentity,
543 E::Identity: crate::traits::ColumnOf<T>,
544{
545}
546
547impl<T0, T1, Grouped, P0, P1> ScalarColumnsIn<Grouped, (P0, P1)> for (T0, T1)
552where
553 T0: SingleColGroupCheck<Grouped, P0>,
554 T1: SingleColGroupCheck<Grouped, P1>,
555{
556}
557
558macro_rules! impl_scalar_columns_in {
560 ($T0:ident; $i0:tt) => {};
562 ($T0:ident, $T1:ident; $i0:tt, $i1:tt) => {};
564 ($T0:ident, $($rest:ident),+; $i0:tt, $($ri:tt),+) => {
566 impl<$T0, $($rest),+, Grouped, HeadProof, TailProof>
567 ScalarColumnsIn<Grouped, (HeadProof, TailProof)>
568 for ($T0, $($rest),+)
569 where
570 $T0: SingleColGroupCheck<Grouped, HeadProof>,
571 ($($rest,)+): ScalarColumnsIn<Grouped, TailProof>,
572 {}
573 };
574}
575
576with_col_sizes_8!(impl_scalar_columns_in);
577
578#[cfg(any(
579 feature = "col16",
580 feature = "col32",
581 feature = "col64",
582 feature = "col128",
583 feature = "col200"
584))]
585with_col_sizes_16!(impl_scalar_columns_in);
586
587#[diagnostic::on_unimplemented(
602 message = "non-aggregate column in SELECT is not in GROUP BY",
603 label = "add this column to .group_by(...) or wrap it in an aggregate function"
604)]
605pub trait MarkerAggValidFor<Grouped, Proof = ()> {}
606
607impl<Mk> MarkerAggValidFor<()> for Mk {}
609
610impl<Scope, Used, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
612 for Scoped<SelectStar, Scope, Used>
613{
614}
615
616impl<Scope, Used, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
618 for Scoped<SelectExpr, Scope, Used>
619{
620}
621
622impl<Scope, Used, R, Head, Tail> MarkerAggValidFor<Cons<Head, Tail>>
624 for Scoped<SelectAs<R>, Scope, Used>
625{
626}
627
628impl<Scope, Used, Cols, Head, Tail, Proof> MarkerAggValidFor<Cons<Head, Tail>, Proof>
630 for Scoped<SelectCols<Cols>, Scope, Used>
631where
632 Cols: ScalarColumnsIn<Cons<Head, Tail>, Proof>,
633{
634}
635
636impl<Scope, Used, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectStar, Scope, Used> {}
640
641impl<Scope, Used, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectExpr, Scope, Used> {}
642
643impl<Scope, Used, R, T> MarkerAggValidFor<PkGroup<T>> for Scoped<SelectAs<R>, Scope, Used> {}
644
645impl<Scope, Used, Cols, T, Proof> MarkerAggValidFor<PkGroup<T>, Proof>
646 for Scoped<SelectCols<Cols>, Scope, Used>
647where
648 Cols: ScalarColumnsIn<PkGroup<T>, Proof>,
649{
650}
651
652pub trait RowColumnList<Row: ?Sized> {
661 type Columns: crate::TypeSet;
663}
664
665pub trait SelectedColumnList {
667 type Columns: crate::TypeSet;
669}
670
671#[doc(hidden)]
677pub trait SelectedExpressionList {
678 type Expressions: crate::TypeSet;
679}
680
681trait SameType<T> {}
682impl<T> SameType<T> for T {}
683
684#[diagnostic::on_unimplemented(
685 message = "selected column decodes as `{Expected}`, but the decode target uses `{Actual}`",
686 label = "the decode target does not match the selected columns",
687 note = "a selected `MaybeNull<T>` can be NULL (an outer join or a nullable operand) \
688 and must be decoded as `Option<T>`"
689)]
690trait ColumnTypeCompatible<Row: ?Sized, Expected, Actual> {}
691
692impl<Row: ?Sized, T> ColumnTypeCompatible<Row, T, T> for () {}
693
694impl<Row: ?Sized, Expected, Actual> ColumnTypeCompatible<Row, MaybeNull<Expected>, Option<Actual>>
698 for ()
699where
700 (): MaybeNullCompatible<Row, Expected, Actual>,
701{
702}
703
704trait MaybeNullCompatible<Row: ?Sized, Expected, Actual> {}
707
708impl<Row: ?Sized, T> MaybeNullCompatible<Row, T, T> for () {}
709
710impl<Row: ?Sized, T> MaybeNullCompatible<Row, Option<T>, T> for () {}
711
712trait TypeListCompatible<Row: ?Sized, ActualList> {}
713
714impl<Row: ?Sized> TypeListCompatible<Row, Self> for crate::Nil {}
715
716impl<Row: ?Sized, EH, ET, AH, AT> TypeListCompatible<Row, crate::Cons<AH, AT>>
717 for crate::Cons<EH, ET>
718where
719 (): ColumnTypeCompatible<Row, EH, AH>,
720 ET: TypeListCompatible<Row, AT>,
721{
722}
723
724trait SqliteDecodeRow {}
725
726#[cfg(feature = "rusqlite")]
727impl SqliteDecodeRow for ::rusqlite::Row<'_> {}
728
729#[cfg(feature = "libsql")]
730impl SqliteDecodeRow for ::libsql::Row {}
731
732#[cfg(feature = "turso")]
733impl SqliteDecodeRow for ::turso::Row {}
734
735macro_rules! impl_sqlite_integer_decode_compat {
736 ($expected:ty => $($actual:ty),+ $(,)?) => {
737 $(
738 impl<Row> ColumnTypeCompatible<Row, $expected, $actual> for ()
739 where
740 Row: SqliteDecodeRow,
741 {
742 }
743 )+
744 };
745}
746
747impl_sqlite_integer_decode_compat!(
748 i64 => i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
749);
750
751macro_rules! impl_sqlite_join_nullable_integer_decode_compat {
752 ($($actual:ty),+ $(,)?) => {
753 $(
754 impl<Row> MaybeNullCompatible<Row, i64, $actual> for ()
755 where
756 Row: SqliteDecodeRow,
757 {
758 }
759
760 impl<Row> MaybeNullCompatible<Row, Option<i64>, $actual> for ()
761 where
762 Row: SqliteDecodeRow,
763 {
764 }
765 )+
766 };
767}
768
769impl_sqlite_join_nullable_integer_decode_compat!(
770 i8, i16, i32, isize, u8, u16, u32, u64, usize, bool
771);
772
773impl_sqlite_integer_decode_compat!(
774 Option<i64> =>
775 Option<i8>,
776 Option<i16>,
777 Option<i32>,
778 Option<isize>,
779 Option<u8>,
780 Option<u16>,
781 Option<u32>,
782 Option<u64>,
783 Option<usize>,
784 Option<bool>
785);
786
787macro_rules! impl_row_column_list_one {
788 ($($ty:ty),+ $(,)?) => {
789 $(
790 impl<Row: ?Sized> RowColumnList<Row> for $ty {
791 type Columns = crate::Cons<$ty, crate::Nil>;
792 }
793 )+
794 };
795}
796
797impl_row_column_list_one!(
798 i8,
799 i16,
800 i32,
801 i64,
802 isize,
803 u8,
804 u16,
805 u32,
806 u64,
807 usize,
808 f32,
809 f64,
810 bool,
811 crate::prelude::String,
812 crate::prelude::Vec<u8>
813);
814
815impl<Row: ?Sized> RowColumnList<Row> for () {
816 type Columns = crate::Cons<(), crate::Nil>;
817}
818
819impl<Row: ?Sized, const N: usize> RowColumnList<Row> for [u8; N] {
820 type Columns = crate::Cons<Self, crate::Nil>;
821}
822
823#[cfg(feature = "uuid")]
824impl<Row: ?Sized> RowColumnList<Row> for uuid::Uuid {
825 type Columns = crate::Cons<Self, crate::Nil>;
826}
827
828#[cfg(feature = "chrono")]
829impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDate {
830 type Columns = crate::Cons<Self, crate::Nil>;
831}
832
833#[cfg(feature = "chrono")]
834impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveTime {
835 type Columns = crate::Cons<Self, crate::Nil>;
836}
837
838#[cfg(feature = "chrono")]
839impl<Row: ?Sized> RowColumnList<Row> for chrono::NaiveDateTime {
840 type Columns = crate::Cons<Self, crate::Nil>;
841}
842
843#[cfg(feature = "chrono")]
844impl<Row: ?Sized> RowColumnList<Row> for chrono::DateTime<chrono::Utc> {
845 type Columns = crate::Cons<Self, crate::Nil>;
846}
847
848#[cfg(feature = "serde")]
849impl<Row: ?Sized> RowColumnList<Row> for serde_json::Value {
850 type Columns = crate::Cons<Self, crate::Nil>;
851}
852
853#[cfg(feature = "rust-decimal")]
854impl<Row: ?Sized> RowColumnList<Row> for rust_decimal::Decimal {
855 type Columns = crate::Cons<Self, crate::Nil>;
856}
857
858#[cfg(feature = "chrono")]
859impl<Row: ?Sized> RowColumnList<Row> for chrono::Duration {
860 type Columns = crate::Cons<Self, crate::Nil>;
861}
862
863#[cfg(feature = "time")]
864impl<Row: ?Sized> RowColumnList<Row> for time::Date {
865 type Columns = crate::Cons<Self, crate::Nil>;
866}
867
868#[cfg(feature = "time")]
869impl<Row: ?Sized> RowColumnList<Row> for time::Time {
870 type Columns = crate::Cons<Self, crate::Nil>;
871}
872
873#[cfg(feature = "time")]
874impl<Row: ?Sized> RowColumnList<Row> for time::PrimitiveDateTime {
875 type Columns = crate::Cons<Self, crate::Nil>;
876}
877
878#[cfg(feature = "time")]
879impl<Row: ?Sized> RowColumnList<Row> for time::OffsetDateTime {
880 type Columns = crate::Cons<Self, crate::Nil>;
881}
882
883#[cfg(feature = "time")]
884impl<Row: ?Sized> RowColumnList<Row> for time::Duration {
885 type Columns = crate::Cons<Self, crate::Nil>;
886}
887
888#[cfg(feature = "jiff")]
889impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Date {
890 type Columns = crate::Cons<Self, crate::Nil>;
891}
892
893#[cfg(feature = "jiff")]
894impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::Time {
895 type Columns = crate::Cons<Self, crate::Nil>;
896}
897
898#[cfg(feature = "jiff")]
899impl<Row: ?Sized> RowColumnList<Row> for jiff::civil::DateTime {
900 type Columns = crate::Cons<Self, crate::Nil>;
901}
902
903#[cfg(feature = "jiff")]
904impl<Row: ?Sized> RowColumnList<Row> for jiff::Timestamp {
905 type Columns = crate::Cons<Self, crate::Nil>;
906}
907
908#[cfg(feature = "cidr")]
909impl<Row: ?Sized> RowColumnList<Row> for cidr::IpInet {
910 type Columns = crate::Cons<Self, crate::Nil>;
911}
912
913#[cfg(feature = "cidr")]
914impl<Row: ?Sized> RowColumnList<Row> for cidr::IpCidr {
915 type Columns = crate::Cons<Self, crate::Nil>;
916}
917
918#[cfg(feature = "geo-types")]
919impl<Row: ?Sized> RowColumnList<Row> for geo_types::Point<f64> {
920 type Columns = crate::Cons<Self, crate::Nil>;
921}
922
923#[cfg(feature = "geo-types")]
924impl<Row: ?Sized> RowColumnList<Row> for geo_types::LineString<f64> {
925 type Columns = crate::Cons<Self, crate::Nil>;
926}
927
928#[cfg(feature = "geo-types")]
929impl<Row: ?Sized> RowColumnList<Row> for geo_types::Rect<f64> {
930 type Columns = crate::Cons<Self, crate::Nil>;
931}
932
933#[cfg(feature = "bit-vec")]
934impl<Row: ?Sized> RowColumnList<Row> for bit_vec::BitVec {
935 type Columns = crate::Cons<Self, crate::Nil>;
936}
937
938#[cfg(feature = "arrayvec")]
939impl<Row: ?Sized, const N: usize> RowColumnList<Row> for arrayvec::ArrayString<N> {
940 type Columns = crate::Cons<Self, crate::Nil>;
941}
942
943#[cfg(feature = "arrayvec")]
944impl<Row: ?Sized, T, const N: usize> RowColumnList<Row> for arrayvec::ArrayVec<T, N> {
945 type Columns = crate::Cons<Self, crate::Nil>;
946}
947
948impl<Row: ?Sized> RowColumnList<Row> for compact_str::CompactString {
949 type Columns = crate::Cons<Self, crate::Nil>;
950}
951
952#[cfg(feature = "bytes")]
953impl<Row: ?Sized> RowColumnList<Row> for bytes::Bytes {
954 type Columns = crate::Cons<Self, crate::Nil>;
955}
956
957#[cfg(feature = "bytes")]
958impl<Row: ?Sized> RowColumnList<Row> for bytes::BytesMut {
959 type Columns = crate::Cons<Self, crate::Nil>;
960}
961
962impl<Row: ?Sized, A: smallvec::Array> RowColumnList<Row> for smallvec::SmallVec<A> {
963 type Columns = crate::Cons<Self, crate::Nil>;
964}
965
966impl<Row: ?Sized, T> RowColumnList<Row> for Option<T> {
967 type Columns = crate::Cons<Self, crate::Nil>;
968}
969
970macro_rules! impl_rcl_body {
973 ([$A:ident] []) => {
975 impl<Row: ?Sized, $A: RowColumnList<Row>> RowColumnList<Row> for ($A,) {
976 type Columns = <$A as RowColumnList<Row>>::Columns;
977 }
978 };
979 ([$($all:ident),+] [$($prev:ident),+; $last:ident]) => {
981 impl<Row: ?Sized, $($all),+> RowColumnList<Row> for ($($all,)+)
982 where
983 $last: RowColumnList<Row>,
984 ($($prev,)+): RowColumnList<Row>,
985 <($($prev,)+) as RowColumnList<Row>>::Columns:
986 crate::Concat<<$last as RowColumnList<Row>>::Columns>,
987 {
988 type Columns = <<($($prev,)+) as RowColumnList<Row>>::Columns as crate::Concat<
989 <$last as RowColumnList<Row>>::Columns,
990 >>::Output;
991 }
992 };
993}
994
995macro_rules! impl_rcl_tuple {
998 ($($T:ident),+) => {
999 impl_rcl_split!([$($T),+] [] $($T),+);
1000 };
1001}
1002
1003macro_rules! impl_rcl_split {
1005 ([$A:ident] [] $only:ident) => {
1007 impl_rcl_body!([$A] []);
1008 };
1009 ([$($all:ident),+] [$($prev:ident),+] $last:ident) => {
1011 impl_rcl_body!([$($all),+] [$($prev),+; $last]);
1012 };
1013 ([$($all:ident),+] [] $head:ident, $($rest:ident),+) => {
1015 impl_rcl_split!([$($all),+] [$head] $($rest),+);
1016 };
1017 ([$($all:ident),+] [$($prev:ident),+] $head:ident, $($rest:ident),+) => {
1019 impl_rcl_split!([$($all),+] [$($prev),+, $head] $($rest),+);
1020 };
1021}
1022
1023with_type_sizes_8!(impl_rcl_tuple);
1024
1025#[cfg(any(
1026 feature = "col16",
1027 feature = "col32",
1028 feature = "col64",
1029 feature = "col128",
1030 feature = "col200"
1031))]
1032with_type_sizes_16!(impl_rcl_tuple);
1033
1034#[cfg(any(
1035 feature = "col32",
1036 feature = "col64",
1037 feature = "col128",
1038 feature = "col200"
1039))]
1040with_type_sizes_32!(impl_rcl_tuple);
1041
1042#[diagnostic::on_unimplemented(
1059 message = "selected shape does not match decode target `{Actual}`",
1060 label = "this decode target is not type-compatible with .select(...) output",
1061 note = "use typed expressions or derive FromRow for explicit remapping when selecting custom expressions"
1062)]
1063pub trait MarkerColumnCountValid<Row: ?Sized, Inferred, Actual, Proof = ()> {}
1064
1065#[diagnostic::on_unimplemented(
1072 message = "raw select expressions require explicit typing in strict decode",
1073 label = "`select(sql!(...)).all()/get()` is not allowed in strict mode",
1074 note = "use typed wrappers like `raw_non_null`/`raw_nullable` or derive FromRow"
1075)]
1076pub trait StrictDecodeMarker {}
1077
1078impl StrictDecodeMarker for SelectStar {}
1079impl<Cols> StrictDecodeMarker for SelectCols<Cols> {}
1080impl<R> StrictDecodeMarker for SelectAs<R> {}
1081impl<M, Scope, Used> StrictDecodeMarker for Scoped<M, Scope, Used> where M: StrictDecodeMarker {}
1082
1083impl<Row: ?Sized, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1084 for SelectStar
1085{
1086}
1087
1088impl<Row: ?Sized, Cols, Inferred, Actual, Proof>
1089 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for SelectCols<Cols>
1090where
1091 Cols: SelectedColumnList,
1092 Actual: RowColumnList<Row>,
1093 <Cols as SelectedColumnList>::Columns:
1094 TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
1095{
1096}
1097
1098impl<Row: ?Sized, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1099 for SelectExpr
1100where
1101 Inferred: SameType<Actual>,
1102{
1103}
1104
1105impl<Row: ?Sized, R, Inferred, Actual, Proof> MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1106 for SelectAs<R>
1107{
1108}
1109
1110impl<Row: ?Sized, Table, Used, Inferred, Actual, Proof>
1112 MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1113 for Scoped<SelectStar, Cons<Table, Nil>, Used>
1114{
1115}
1116
1117impl<Row: ?Sized, First, Second, Rest, Used, Inferred, Actual, Proof>
1120 MarkerColumnCountValid<Row, Inferred, Actual, Proof>
1121 for Scoped<SelectStar, Cons<First, Cons<Second, Rest>>, Used>
1122where
1123 Inferred: JoinedStarRow<Actual>,
1124{
1125}
1126
1127impl<Row: ?Sized, Cols, Scope, Used, Inferred, Actual, UsedProof, ColsProof>
1128 MarkerColumnCountValid<Row, Inferred, Actual, (UsedProof, ColsProof)>
1129 for Scoped<SelectCols<Cols>, Scope, Used>
1130where
1131 Cols: SelectedExpressionList,
1132 Cols::Expressions: ProjectionIn<Scope, ColsProof>,
1133 Actual: RowColumnList<Row>,
1134 <Cols::Expressions as ProjectionIn<Scope, ColsProof>>::Columns:
1135 TypeListCompatible<Row, <Actual as RowColumnList<Row>>::Columns>,
1136{
1137}
1138
1139impl<Row: ?Sized, Scope, Used, Inferred, Actual, Proof>
1140 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for Scoped<SelectExpr, Scope, Used>
1141where
1142 Inferred: SameType<Actual>,
1143{
1144}
1145
1146impl<Row: ?Sized, R, Scope, Used, Inferred, Actual, Proof>
1148 MarkerColumnCountValid<Row, Inferred, Actual, Proof> for Scoped<SelectAs<R>, Scope, Used>
1149{
1150}
1151
1152#[diagnostic::on_unimplemented(
1158 message = "joined `SELECT *` rows decode as `{Self}`, not `{Actual}`",
1159 label = "the decode target does not match the joined row type",
1160 note = "LEFT/RIGHT/FULL JOIN sources can be NULL: decode them as `Option<_>`, \
1161 e.g. `(SelectUsers, Option<SelectPosts>)` after `.left_join(posts)`"
1162)]
1163pub trait JoinedStarRow<Actual> {}
1164
1165impl<A, B, ActualA, ActualB> JoinedStarRow<(ActualA, ActualB)> for (A, B)
1166where
1167 A: JoinedStarPart<ActualA>,
1168 B: JoinedStarPart<ActualB>,
1169{
1170}
1171
1172#[doc(hidden)]
1174#[diagnostic::on_unimplemented(
1175 message = "this half of the joined `SELECT *` row decodes as `{Self}`, not `{Actual}`",
1176 label = "the decode target does not match the joined row type",
1177 note = "LEFT/RIGHT/FULL JOIN sources can be NULL: decode them as `Option<_>`"
1178)]
1179pub trait JoinedStarPart<Actual> {}
1180
1181impl<T> JoinedStarPart<T> for T {}
1182
1183impl<T> JoinedStarPart<Option<T>> for T {}
1184
1185pub trait DecodeSelectedRef<RowRef, R> {
1190 fn decode(row: RowRef) -> Result<R, DrizzleError>;
1197}
1198
1199impl<RowRef, R> DecodeSelectedRef<RowRef, R> for SelectAs<R>
1200where
1201 R: TryFrom<RowRef>,
1202 <R as TryFrom<RowRef>>::Error: Into<DrizzleError>,
1203{
1204 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1205 R::try_from(row).map_err(Into::into)
1206 }
1207}
1208
1209impl<RowRef, R, M, Scope, Used> DecodeSelectedRef<RowRef, R> for Scoped<M, Scope, Used>
1210where
1211 M: DecodeSelectedRef<RowRef, R>,
1212{
1213 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1214 M::decode(row)
1215 }
1216}
1217
1218impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectStar
1219where
1220 RowRef: core::ops::Deref<Target = Row>,
1221 R: FromDrizzleRow<Row>,
1222{
1223 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1224 R::from_row(&*row)
1225 }
1226}
1227
1228impl<RowRef, Row: ?Sized, Cols, R> DecodeSelectedRef<RowRef, R> for SelectCols<Cols>
1229where
1230 RowRef: core::ops::Deref<Target = Row>,
1231 R: FromDrizzleRow<Row>,
1232{
1233 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1234 R::from_row(&*row)
1235 }
1236}
1237
1238impl<RowRef, Row: ?Sized, R> DecodeSelectedRef<RowRef, R> for SelectExpr
1239where
1240 RowRef: core::ops::Deref<Target = Row>,
1241 R: FromDrizzleRow<Row>,
1242{
1243 fn decode(row: RowRef) -> Result<R, DrizzleError> {
1244 R::from_row(&*row)
1245 }
1246}
1247
1248#[diagnostic::on_unimplemented(
1261 message = "cannot deserialize `{Self}` from a database row",
1262 label = "this type does not implement FromDrizzleRow",
1263 note = "derive #[SQLiteFromRow], #[PostgresFromRow], or #[MySQLFromRow]"
1264)]
1265pub trait FromDrizzleRow<Row: ?Sized>: Sized {
1266 const COLUMN_COUNT: usize;
1268
1269 fn from_row_at(row: &Row, offset: usize) -> Result<Self, DrizzleError>;
1276
1277 fn from_row(row: &Row) -> Result<Self, DrizzleError> {
1283 Self::from_row_at(row, 0)
1284 }
1285}
1286
1287pub trait NullProbeRow<Row: ?Sized>: FromDrizzleRow<Row> {
1295 fn is_null_at(row: &Row, offset: usize) -> Result<bool, DrizzleError>;
1306}
1307
1308macro_rules! impl_from_drizzle_row_tuple {
1311 ($($T:ident),+; $($idx:tt),+) => {
1312 impl<__Row: ?Sized, $($T: FromDrizzleRow<__Row>),+> FromDrizzleRow<__Row> for ($($T,)+) {
1313 const COLUMN_COUNT: usize = 0 $(+ <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT)+;
1314
1315 #[allow(non_snake_case)]
1316 fn from_row_at(
1317 row: &__Row,
1318 offset: usize,
1319 ) -> Result<Self, DrizzleError> {
1320 let mut __off = offset;
1321 $(
1322 let $T = <$T as FromDrizzleRow<__Row>>::from_row_at(row, __off)?;
1323 __off += <$T as FromDrizzleRow<__Row>>::COLUMN_COUNT;
1324 )+
1325 Ok(($($T,)+))
1326 }
1327 }
1328 };
1329}
1330
1331with_col_sizes_8!(impl_from_drizzle_row_tuple);
1332
1333#[cfg(any(
1334 feature = "col16",
1335 feature = "col32",
1336 feature = "col64",
1337 feature = "col128",
1338 feature = "col200"
1339))]
1340with_col_sizes_16!(impl_from_drizzle_row_tuple);
1341
1342#[cfg(any(
1343 feature = "col32",
1344 feature = "col64",
1345 feature = "col128",
1346 feature = "col200"
1347))]
1348with_col_sizes_32!(impl_from_drizzle_row_tuple);
1349
1350#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1351with_col_sizes_64!(impl_from_drizzle_row_tuple);
1352
1353#[cfg(any(feature = "col128", feature = "col200"))]
1354with_col_sizes_128!(impl_from_drizzle_row_tuple);
1355
1356#[cfg(feature = "col200")]
1357with_col_sizes_200!(impl_from_drizzle_row_tuple);
1358
1359#[diagnostic::on_unimplemented(
1376 message = "SQL type `{Self}` has no default Rust mapping for dialect `{D}`",
1377 label = "this SQL type has no default Rust mapping for this dialect",
1378 note = "enable `chrono` for Date/Time/Timestamp/TimestampTz, `uuid` for Uuid, or `serde` for Json/Jsonb"
1379)]
1380pub trait SQLTypeToRust<D> {
1381 type RustType;
1382}
1383
1384use crate::dialect::{MySQLDialect, PostgresDialect, SQLiteDialect};
1387
1388impl<D, T> SQLTypeToRust<D> for crate::types::Array<T>
1389where
1390 T: crate::types::DataType + SQLTypeToRust<D>,
1391{
1392 type RustType = crate::prelude::Vec<<T as SQLTypeToRust<D>>::RustType>;
1393}
1394
1395impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Integer {
1396 type RustType = i64;
1397}
1398
1399impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Text {
1400 type RustType = crate::prelude::String;
1401}
1402
1403impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Real {
1404 type RustType = f64;
1405}
1406
1407impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Blob {
1408 type RustType = crate::prelude::Vec<u8>;
1409}
1410
1411impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Numeric {
1412 type RustType = f64;
1413}
1414
1415impl SQLTypeToRust<SQLiteDialect> for drizzle_types::sqlite::types::Any {
1416 type RustType = crate::prelude::String;
1417}
1418
1419macro_rules! impl_mysql_sql_type_to_rust {
1420 ($rust:ty => $($sql:ty),+ $(,)?) => {
1421 $(
1422 impl SQLTypeToRust<MySQLDialect> for $sql {
1423 type RustType = $rust;
1424 }
1425 )+
1426 };
1427}
1428
1429impl_mysql_sql_type_to_rust!(i8 => drizzle_types::mysql::types::TinyInt);
1430impl_mysql_sql_type_to_rust!(u8 => drizzle_types::mysql::types::TinyIntUnsigned);
1431impl_mysql_sql_type_to_rust!(i16 => drizzle_types::mysql::types::SmallInt);
1432impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::SmallIntUnsigned);
1433impl_mysql_sql_type_to_rust!(i32 =>
1434 drizzle_types::mysql::types::MediumInt,
1435 drizzle_types::mysql::types::Int,
1436);
1437impl_mysql_sql_type_to_rust!(u32 =>
1438 drizzle_types::mysql::types::MediumIntUnsigned,
1439 drizzle_types::mysql::types::IntUnsigned,
1440);
1441impl_mysql_sql_type_to_rust!(i64 => drizzle_types::mysql::types::BigInt);
1442impl_mysql_sql_type_to_rust!(u64 => drizzle_types::mysql::types::BigIntUnsigned);
1443impl_mysql_sql_type_to_rust!(f32 => drizzle_types::mysql::types::Float);
1444impl_mysql_sql_type_to_rust!(f64 => drizzle_types::mysql::types::Double);
1445impl_mysql_sql_type_to_rust!(bool => drizzle_types::mysql::types::Boolean);
1446impl_mysql_sql_type_to_rust!(crate::prelude::String =>
1447 drizzle_types::mysql::types::Char,
1448 drizzle_types::mysql::types::Varchar,
1449 drizzle_types::mysql::types::TinyText,
1450 drizzle_types::mysql::types::Text,
1451 drizzle_types::mysql::types::MediumText,
1452 drizzle_types::mysql::types::LongText,
1453 drizzle_types::mysql::types::Enum,
1454 drizzle_types::mysql::types::Set,
1455 drizzle_types::mysql::types::Any,
1456);
1457impl_mysql_sql_type_to_rust!(crate::prelude::Vec<u8> =>
1458 drizzle_types::mysql::types::Binary,
1459 drizzle_types::mysql::types::Varbinary,
1460 drizzle_types::mysql::types::TinyBlob,
1461 drizzle_types::mysql::types::Blob,
1462 drizzle_types::mysql::types::MediumBlob,
1463 drizzle_types::mysql::types::LongBlob,
1464 drizzle_types::mysql::types::Bit,
1465);
1466impl_mysql_sql_type_to_rust!(u16 => drizzle_types::mysql::types::Year);
1467
1468#[cfg(feature = "rust-decimal")]
1469impl_mysql_sql_type_to_rust!(rust_decimal::Decimal => drizzle_types::mysql::types::Decimal);
1470#[cfg(not(feature = "rust-decimal"))]
1471impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Decimal);
1472
1473#[cfg(feature = "serde")]
1474impl_mysql_sql_type_to_rust!(serde_json::Value => drizzle_types::mysql::types::Json);
1475#[cfg(not(feature = "serde"))]
1476impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Json);
1477
1478#[cfg(feature = "chrono")]
1479impl_mysql_sql_type_to_rust!(chrono::NaiveDate => drizzle_types::mysql::types::Date);
1480#[cfg(all(not(feature = "chrono"), feature = "time"))]
1481impl_mysql_sql_type_to_rust!(time::Date => drizzle_types::mysql::types::Date);
1482#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1483impl_mysql_sql_type_to_rust!(jiff::civil::Date => drizzle_types::mysql::types::Date);
1484#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
1485impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Date);
1486
1487impl_mysql_sql_type_to_rust!(crate::prelude::String => drizzle_types::mysql::types::Time);
1492
1493#[cfg(feature = "chrono")]
1494impl_mysql_sql_type_to_rust!(chrono::NaiveDateTime => drizzle_types::mysql::types::DateTime);
1495#[cfg(feature = "chrono")]
1499impl_mysql_sql_type_to_rust!(chrono::DateTime<chrono::Utc> => drizzle_types::mysql::types::Timestamp);
1500#[cfg(all(not(feature = "chrono"), feature = "time"))]
1501impl_mysql_sql_type_to_rust!(time::PrimitiveDateTime => drizzle_types::mysql::types::DateTime);
1502#[cfg(all(not(feature = "chrono"), feature = "time"))]
1503impl_mysql_sql_type_to_rust!(time::OffsetDateTime => drizzle_types::mysql::types::Timestamp);
1504#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1505impl_mysql_sql_type_to_rust!(jiff::civil::DateTime => drizzle_types::mysql::types::DateTime);
1506#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1507impl_mysql_sql_type_to_rust!(jiff::Timestamp => drizzle_types::mysql::types::Timestamp);
1508#[cfg(not(any(feature = "chrono", feature = "time", feature = "jiff")))]
1509impl_mysql_sql_type_to_rust!(crate::prelude::String =>
1510 drizzle_types::mysql::types::DateTime,
1511 drizzle_types::mysql::types::Timestamp,
1512);
1513
1514impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int2 {
1515 type RustType = i16;
1516}
1517
1518impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int4 {
1519 type RustType = i32;
1520}
1521
1522impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Int8 {
1523 type RustType = i64;
1524}
1525
1526impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float4 {
1527 type RustType = f32;
1528}
1529
1530impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Float8 {
1531 type RustType = f64;
1532}
1533
1534impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Varchar {
1535 type RustType = crate::prelude::String;
1536}
1537
1538impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Text {
1539 type RustType = crate::prelude::String;
1540}
1541
1542impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Char {
1543 type RustType = crate::prelude::String;
1544}
1545
1546impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Bytea {
1547 type RustType = crate::prelude::Vec<u8>;
1548}
1549
1550impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Boolean {
1551 type RustType = bool;
1552}
1553
1554#[cfg(feature = "rust-decimal")]
1555impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
1556 type RustType = rust_decimal::Decimal;
1557}
1558
1559#[cfg(not(feature = "rust-decimal"))]
1560impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Numeric {
1561 type RustType = crate::prelude::String;
1562}
1563
1564impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Any {
1565 type RustType = crate::prelude::String;
1566}
1567
1568#[cfg(feature = "chrono")]
1569impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1570 type RustType = chrono::DateTime<chrono::Utc>;
1571}
1572
1573#[cfg(feature = "chrono")]
1574impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1575 type RustType = chrono::NaiveDateTime;
1576}
1577
1578#[cfg(feature = "chrono")]
1579impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1580 type RustType = chrono::NaiveDate;
1581}
1582
1583#[cfg(feature = "chrono")]
1584impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1585 type RustType = chrono::NaiveTime;
1586}
1587
1588#[cfg(feature = "chrono")]
1589impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timetz {
1590 type RustType = chrono::NaiveTime;
1591}
1592
1593#[cfg(all(not(feature = "chrono"), feature = "time"))]
1594impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1595 type RustType = time::OffsetDateTime;
1596}
1597
1598#[cfg(all(not(feature = "chrono"), feature = "time"))]
1599impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1600 type RustType = time::PrimitiveDateTime;
1601}
1602
1603#[cfg(all(not(feature = "chrono"), feature = "time"))]
1604impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1605 type RustType = time::Date;
1606}
1607
1608#[cfg(all(not(feature = "chrono"), feature = "time"))]
1609impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1610 type RustType = time::Time;
1611}
1612
1613#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1614impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamptz {
1615 type RustType = jiff::Timestamp;
1616}
1617
1618#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1619impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Timestamp {
1620 type RustType = jiff::civil::DateTime;
1621}
1622
1623#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1624impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Date {
1625 type RustType = jiff::civil::Date;
1626}
1627
1628#[cfg(all(not(any(feature = "chrono", feature = "time")), feature = "jiff"))]
1629impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Time {
1630 type RustType = jiff::civil::Time;
1631}
1632
1633#[cfg(feature = "uuid")]
1634impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Uuid {
1635 type RustType = uuid::Uuid;
1636}
1637
1638#[cfg(feature = "serde")]
1639impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Json {
1640 type RustType = serde_json::Value;
1641}
1642
1643#[cfg(feature = "serde")]
1644impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Jsonb {
1645 type RustType = serde_json::Value;
1646}
1647
1648#[cfg(feature = "chrono")]
1651impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
1652 type RustType = chrono::Duration;
1653}
1654
1655#[cfg(not(feature = "chrono"))]
1656impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Interval {
1657 type RustType = crate::prelude::String;
1658}
1659
1660#[cfg(feature = "cidr")]
1661impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
1662 type RustType = cidr::IpInet;
1663}
1664
1665#[cfg(not(feature = "cidr"))]
1666impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Inet {
1667 type RustType = crate::prelude::String;
1668}
1669
1670#[cfg(feature = "cidr")]
1671impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
1672 type RustType = cidr::IpCidr;
1673}
1674
1675#[cfg(not(feature = "cidr"))]
1676impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Cidr {
1677 type RustType = crate::prelude::String;
1678}
1679
1680impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr {
1681 type RustType = crate::prelude::String;
1682}
1683
1684impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::MacAddr8 {
1685 type RustType = crate::prelude::String;
1686}
1687
1688#[cfg(feature = "geo-types")]
1689impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
1690 type RustType = geo_types::Point<f64>;
1691}
1692
1693#[cfg(not(feature = "geo-types"))]
1694impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Point {
1695 type RustType = crate::prelude::String;
1696}
1697
1698#[cfg(feature = "geo-types")]
1699impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
1700 type RustType = geo_types::LineString<f64>;
1701}
1702
1703#[cfg(not(feature = "geo-types"))]
1704impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineString {
1705 type RustType = crate::prelude::String;
1706}
1707
1708#[cfg(feature = "geo-types")]
1709impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
1710 type RustType = geo_types::Rect<f64>;
1711}
1712
1713#[cfg(not(feature = "geo-types"))]
1714impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Rect {
1715 type RustType = crate::prelude::String;
1716}
1717
1718#[cfg(feature = "bit-vec")]
1719impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
1720 type RustType = bit_vec::BitVec;
1721}
1722
1723#[cfg(not(feature = "bit-vec"))]
1724impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::BitString {
1725 type RustType = crate::prelude::String;
1726}
1727
1728impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Line {
1729 type RustType = crate::prelude::String;
1730}
1731
1732impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::LineSegment {
1733 type RustType = crate::prelude::String;
1734}
1735
1736impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Polygon {
1737 type RustType = crate::prelude::String;
1738}
1739
1740impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Circle {
1741 type RustType = crate::prelude::String;
1742}
1743
1744impl SQLTypeToRust<PostgresDialect> for drizzle_types::postgres::types::Enum {
1745 type RustType = crate::prelude::String;
1746}
1747
1748pub trait WrapNullable<T> {
1755 type Output;
1757}
1758
1759impl<T> WrapNullable<T> for crate::expr::NonNull {
1760 type Output = T;
1761}
1762
1763impl<T> WrapNullable<T> for crate::expr::Null {
1764 type Output = Option<T>;
1765}
1766
1767#[diagnostic::on_unimplemented(
1780 message = "cannot infer Rust type for expression `{Self}`",
1781 label = "use typed expressions or derive FromRow to specify the Rust type",
1782 note = "raw SQL and JSON expressions require explicit type annotation"
1783)]
1784pub trait ExprValueType {
1785 type ValueType;
1787}
1788
1789impl<T: ExprValueType + ?Sized> ExprValueType for &T {
1790 type ValueType = T::ValueType;
1791}
1792
1793impl<V: crate::SQLParam, T, N, A, S> ExprValueType for crate::expr::SQLExpr<'_, V, T, N, A, S>
1794where
1795 T: crate::types::DataType + SQLTypeToRust<V::DialectMarker>,
1796 N: crate::expr::Nullability + WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>,
1797 A: crate::expr::AggregateKind,
1798{
1799 type ValueType = <N as WrapNullable<<T as SQLTypeToRust<V::DialectMarker>>::RustType>>::Output;
1800}
1801
1802impl<V: crate::SQLParam> ExprValueType for crate::sql::SQL<'_, V> {
1804 type ValueType = ();
1805}
1806
1807#[diagnostic::on_unimplemented(
1816 message = "`{Self}` is not a drizzle table",
1817 label = "ensure this type was derived with #[SQLiteTable], #[PostgresTable], or #[MySQLTable]"
1818)]
1819pub trait HasSelectModel {
1820 type SelectModel;
1822 const COLUMN_COUNT: usize;
1824}
1825
1826impl<T: HasSelectModel + ?Sized> HasSelectModel for &T {
1827 type SelectModel = T::SelectModel;
1828
1829 const COLUMN_COUNT: usize = T::COLUMN_COUNT;
1830}
1831
1832#[diagnostic::on_unimplemented(
1842 message = "cannot resolve return type for this query",
1843 label = "the selected columns and table do not produce a known row type"
1844)]
1845pub trait ResolveRow<Table> {
1846 type Row;
1848}
1849
1850impl<T: HasSelectModel> ResolveRow<T> for SelectStar {
1851 type Row = T::SelectModel;
1852}
1853
1854impl<T> ResolveRow<T> for SelectExpr {
1855 type Row = ();
1856}
1857
1858impl<R, T> ResolveRow<T> for SelectAs<R>
1859where
1860 R: SelectAsFrom<T>,
1861{
1862 type Row = R;
1863}
1864
1865impl<M, Scope, Used, T> ResolveRow<T> for Scoped<M, Scope, Used>
1866where
1867 M: ResolveRow<T>,
1868{
1869 type Row = M::Row;
1870}
1871
1872#[diagnostic::on_unimplemented(
1878 message = "row selector `{Self}` cannot be used with table `{Table}`",
1879 label = "the #[from(...)] table does not match .from(...)",
1880 note = "set #[from(TheTable)] to the same table passed to .from(...)"
1881)]
1882pub trait SelectAsFrom<Table> {}
1883
1884macro_rules! impl_resolve_row_cols {
1887 ($($T:ident),+; $($idx:tt),+) => {
1888 impl<__Table, $($T: ExprValueType),+> ResolveRow<__Table> for SelectCols<($($T,)+)> {
1889 type Row = ($(<$T as ExprValueType>::ValueType,)+);
1890 }
1891 };
1892}
1893
1894with_col_sizes_8!(impl_resolve_row_cols);
1895
1896#[cfg(any(
1897 feature = "col16",
1898 feature = "col32",
1899 feature = "col64",
1900 feature = "col128",
1901 feature = "col200"
1902))]
1903with_col_sizes_16!(impl_resolve_row_cols);
1904
1905#[cfg(any(
1906 feature = "col32",
1907 feature = "col64",
1908 feature = "col128",
1909 feature = "col200"
1910))]
1911with_col_sizes_32!(impl_resolve_row_cols);
1912
1913#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1914with_col_sizes_64!(impl_resolve_row_cols);
1915
1916#[cfg(any(feature = "col128", feature = "col200"))]
1917with_col_sizes_128!(impl_resolve_row_cols);
1918
1919#[cfg(feature = "col200")]
1920with_col_sizes_200!(impl_resolve_row_cols);
1921
1922macro_rules! selected_columns_cons {
1923 () => {
1924 crate::Nil
1925 };
1926 ($head:ident $(, $tail:ident)*) => {
1927 crate::Cons<<$head as ExprValueType>::ValueType, selected_columns_cons!($($tail),*)>
1928 };
1929}
1930
1931macro_rules! selected_expressions_cons {
1932 () => {
1933 crate::Nil
1934 };
1935 ($head:ident $(, $tail:ident)*) => {
1936 crate::Cons<$head, selected_expressions_cons!($($tail),*)>
1937 };
1938}
1939
1940macro_rules! impl_selected_column_list_tuple {
1941 ($($T:ident),+; $($idx:tt),+) => {
1942 impl<$($T: ExprValueType),+> SelectedColumnList for ($($T,)+) {
1943 type Columns = selected_columns_cons!($($T),+);
1944 }
1945 };
1946}
1947
1948macro_rules! impl_selected_expression_list_tuple {
1949 ($($T:ident),+; $($idx:tt),+) => {
1950 impl<$($T),+> SelectedExpressionList for ($($T,)+) {
1951 type Expressions = selected_expressions_cons!($($T),+);
1952 }
1953 };
1954}
1955
1956with_col_sizes_8!(impl_selected_column_list_tuple);
1957with_col_sizes_8!(impl_selected_expression_list_tuple);
1958
1959#[cfg(any(
1960 feature = "col16",
1961 feature = "col32",
1962 feature = "col64",
1963 feature = "col128",
1964 feature = "col200"
1965))]
1966with_col_sizes_16!(impl_selected_column_list_tuple);
1967#[cfg(any(
1968 feature = "col16",
1969 feature = "col32",
1970 feature = "col64",
1971 feature = "col128",
1972 feature = "col200"
1973))]
1974with_col_sizes_16!(impl_selected_expression_list_tuple);
1975
1976#[cfg(any(
1977 feature = "col32",
1978 feature = "col64",
1979 feature = "col128",
1980 feature = "col200"
1981))]
1982with_col_sizes_32!(impl_selected_column_list_tuple);
1983#[cfg(any(
1984 feature = "col32",
1985 feature = "col64",
1986 feature = "col128",
1987 feature = "col200"
1988))]
1989with_col_sizes_32!(impl_selected_expression_list_tuple);
1990
1991#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1992with_col_sizes_64!(impl_selected_column_list_tuple);
1993#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
1994with_col_sizes_64!(impl_selected_expression_list_tuple);
1995
1996#[cfg(any(feature = "col128", feature = "col200"))]
1997with_col_sizes_128!(impl_selected_column_list_tuple);
1998#[cfg(any(feature = "col128", feature = "col200"))]
1999with_col_sizes_128!(impl_selected_expression_list_tuple);
2000
2001#[cfg(feature = "col200")]
2002with_col_sizes_200!(impl_selected_column_list_tuple);
2003#[cfg(feature = "col200")]
2004with_col_sizes_200!(impl_selected_expression_list_tuple);
2005
2006use crate::scope::{FullJoin, InnerJoin, JoinRow, LeftJoin, RightJoin};
2011
2012impl<R, T, Kind> JoinRow<R, T, crate::scope::Lateral<Kind>> for SelectStar
2014where
2015 SelectStar: JoinRow<R, T, Kind>,
2016{
2017 type Row = <SelectStar as JoinRow<R, T, Kind>>::Row;
2018}
2019
2020#[doc(hidden)]
2027pub trait LeftLateralSelection<Proof = ()>: left_lateral_private::Sealed {}
2028
2029mod left_lateral_private {
2030 pub trait Sealed {}
2031
2032 impl Sealed for super::SelectStar {}
2033 impl<Scope, Used> Sealed for super::Scoped<super::SelectStar, Scope, Used> {}
2034 impl<Columns, Scope, Used> Sealed for super::Scoped<super::SelectCols<Columns>, Scope, Used> {}
2035 impl<Row, Scope, Used> Sealed for super::Scoped<super::SelectAs<Row>, Scope, Used> {}
2036}
2037
2038impl LeftLateralSelection for SelectStar {}
2039impl<Scope, Used> LeftLateralSelection for Scoped<SelectStar, Scope, Used> {}
2040
2041impl<Columns, Scope, Used, Proof> LeftLateralSelection<Proof>
2042 for Scoped<SelectCols<Columns>, Scope, Used>
2043where
2044 Columns: SelectedExpressionList,
2045 Columns::Expressions: ProjectionIn<Scope, Proof>,
2046{
2047}
2048
2049impl<Row, Scope, Used, Proof> LeftLateralSelection<Proof> for Scoped<SelectAs<Row>, Scope, Used>
2050where
2051 Row: SelectTableFields,
2052 Row::TableFields: TableFieldsIn<Scope, Proof>,
2053{
2054}
2055
2056impl<R, T: HasSelectModel> JoinRow<R, T, InnerJoin> for SelectStar {
2058 type Row = (R, T::SelectModel);
2059}
2060
2061impl<R, T: HasSelectModel> JoinRow<R, T, LeftJoin> for SelectStar {
2063 type Row = (R, Option<T::SelectModel>);
2064}
2065
2066impl<R, T: HasSelectModel> JoinRow<R, T, RightJoin> for SelectStar {
2068 type Row = (Option<R>, T::SelectModel);
2069}
2070
2071impl<R, T: HasSelectModel> JoinRow<R, T, FullJoin> for SelectStar {
2073 type Row = (Option<R>, Option<T::SelectModel>);
2074}
2075
2076impl<Cols, R, T, Kind> JoinRow<R, T, Kind> for SelectCols<Cols> {
2078 type Row = R;
2079}
2080
2081impl<R, T, Kind> JoinRow<R, T, Kind> for SelectExpr {
2083 type Row = R;
2084}
2085
2086impl<Row, R, T, Kind> JoinRow<R, T, Kind> for SelectAs<Row> {
2088 type Row = R;
2089}
2090
2091#[diagnostic::on_unimplemented(
2111 message = "`{Self}` cannot be used as a select target",
2112 label = "this type does not implement IntoSelectTarget",
2113 note = "implement IntoSelectTarget or use a column, table, or typed expression"
2114)]
2115pub trait IntoSelectTarget {
2116 type Marker;
2118}
2119
2120impl<T: IntoSelectTarget + ?Sized> IntoSelectTarget for &T {
2121 type Marker = T::Marker;
2122}
2123
2124impl IntoSelectTarget for () {
2126 type Marker = SelectStar;
2127}
2128
2129impl<V: crate::SQLParam> IntoSelectTarget for crate::sql::SQL<'_, V> {
2131 type Marker = SelectExpr;
2132}
2133
2134impl<V: crate::SQLParam, T, N, A, S> IntoSelectTarget for crate::expr::SQLExpr<'_, V, T, N, A, S>
2136where
2137 T: crate::types::DataType,
2138 N: crate::expr::Nullability,
2139 A: crate::expr::AggregateKind,
2140{
2141 type Marker = SelectCols<(Self,)>;
2142}
2143
2144macro_rules! impl_into_select_target_tuple {
2146 ($($T:ident),+; $($idx:tt),+) => {
2147 impl<$($T),+> IntoSelectTarget for ($($T,)+) {
2148 type Marker = SelectCols<($($T,)+)>;
2149 }
2150 };
2151}
2152
2153with_col_sizes_8!(impl_into_select_target_tuple);
2154
2155#[cfg(any(
2156 feature = "col16",
2157 feature = "col32",
2158 feature = "col64",
2159 feature = "col128",
2160 feature = "col200"
2161))]
2162with_col_sizes_16!(impl_into_select_target_tuple);
2163
2164#[cfg(any(
2165 feature = "col32",
2166 feature = "col64",
2167 feature = "col128",
2168 feature = "col200"
2169))]
2170with_col_sizes_32!(impl_into_select_target_tuple);
2171
2172#[cfg(any(feature = "col64", feature = "col128", feature = "col200"))]
2173with_col_sizes_64!(impl_into_select_target_tuple);
2174
2175#[cfg(any(feature = "col128", feature = "col200"))]
2176with_col_sizes_128!(impl_into_select_target_tuple);
2177
2178#[cfg(feature = "col200")]
2179with_col_sizes_200!(impl_into_select_target_tuple);