1use std::marker::PhantomData;
6
7use crate::cte::Cte;
8use crate::dialect::{Dialect, SupportsFullOuterJoin, SupportsRightJoin};
9use crate::expr::{BoolLike, Comparable, Expr, ExprKind, IntoExpr, Value};
10use crate::render::{
11 Fragment, FragmentSink, QuerySink, SelectItem, Sink, render_and_list, render_expr,
12 render_expr_list, render_order_by, render_select_list,
13};
14use crate::row::{Field as RowFieldLookup, LookupKey, Row};
15use crate::scope::{
16 BaseTable, Concat, Cons, MapNullable, MaybeNull, Nil, NotNull, Position, ScopeTables, Superset,
17 Table, TableSlot,
18};
19
20mod dyn_select;
21mod prepared;
22mod selection;
23mod set_op;
24
25pub use crate::expr::SortDir;
26pub use dyn_select::{CannotFilterAfterErase, DynSelect};
27pub use prepared::{Prepared, PreparedParams, Total, UnresolvedPlaceholder};
28pub use selection::{
29 All, AllColumns, ColumnList, RowField, SelectableSealed, Selection, SelectionPart, SingleColumn,
30};
31pub use set_op::SetOp;
32
33#[doc(hidden)]
38#[derive(Debug, Clone)]
39pub struct CteDef {
40 name: &'static str,
41 column_names: Vec<&'static str>,
42 body: Fragment,
43}
44
45impl CteDef {
46 pub(crate) fn new(name: &'static str, column_names: Vec<&'static str>, body: Fragment) -> Self {
47 CteDef {
48 name,
49 column_names,
50 body,
51 }
52 }
53}
54
55#[derive(Debug, Clone)]
56enum JoinKind {
57 Inner,
58 Left,
59 Right,
60 Full,
61}
62
63#[derive(Debug, Clone)]
64struct JoinClause {
65 kind: JoinKind,
66 table: &'static str,
67 on: ExprKind,
68}
69
70pub struct OrderKey<Req> {
74 kind: ExprKind,
75 dir: SortDir,
76 _marker: PhantomData<fn() -> Req>,
77}
78
79impl<Req> Clone for OrderKey<Req> {
82 fn clone(&self) -> Self {
83 OrderKey {
84 kind: self.kind.clone(),
85 dir: self.dir,
86 _marker: PhantomData,
87 }
88 }
89}
90
91impl<Req> OrderKey<Req> {
92 pub(crate) fn into_parts(self) -> (ExprKind, SortDir) {
93 (self.kind, self.dir)
94 }
95}
96
97pub trait OrderExt: IntoExpr + Sized {
98 fn asc(self) -> OrderKey<Self::Req> {
99 OrderKey {
100 kind: self.into_expr().kind,
101 dir: SortDir::Asc,
102 _marker: PhantomData,
103 }
104 }
105 fn sort(self, dir: SortDir) -> OrderKey<Self::Req> {
108 OrderKey {
109 kind: self.into_expr().kind,
110 dir,
111 _marker: PhantomData,
112 }
113 }
114 fn desc(self) -> OrderKey<Self::Req> {
115 OrderKey {
116 kind: self.into_expr().kind,
117 dir: SortDir::Desc,
118 _marker: PhantomData,
119 }
120 }
121}
122impl<T: IntoExpr> OrderExt for T {}
123
124pub trait JoinSource<D>: join_source::Sealed {
129 type Table: Table;
131 #[doc(hidden)]
134 fn binding(self) -> Option<CteDef>;
135}
136
137mod join_source {
138 pub trait Sealed {}
141 impl<T: super::BaseTable> Sealed for T {}
142 impl<D, Marker> Sealed for crate::cte::Cte<D, Marker> {}
143}
144
145impl<D, T: BaseTable> JoinSource<D> for T {
146 type Table = T;
147 fn binding(self) -> Option<CteDef> {
148 None
149 }
150}
151
152impl<D, Marker: crate::cte::CteShape> JoinSource<D> for Cte<D, Marker> {
153 type Table = Marker;
154 fn binding(self) -> Option<CteDef> {
155 Some(CteDef::new(
156 <Marker as Table>::NAME,
157 <Marker::Row as crate::row::ColumnNames>::names(),
158 self.into_body(),
159 ))
160 }
161}
162
163#[diagnostic::on_unimplemented(
167 message = "`{Self}` isn't a sort key",
168 label = "a column or expression with `.asc()`/`.desc()`/`.sort(dir)` on it, or a `sort_key(..)`",
169 note = "a `SortKey` also has to have been discharged against *this* scope: a scope lists its tables most-recently-joined first, so two that look alike can still differ in order"
170)]
171pub trait SortBy<Scope, Idxs> {
172 #[doc(hidden)]
173 fn into_sort_key(self) -> SortKey<Scope>;
174}
175
176impl<Scope: Superset<Req, Idxs>, Req, Idxs> SortBy<Scope, Idxs> for OrderKey<Req> {
177 fn into_sort_key(self) -> SortKey<Scope> {
178 SortKey {
179 kind: self.kind,
180 dir: self.dir,
181 _marker: PhantomData,
182 }
183 }
184}
185
186impl<Scope> SortBy<Scope, ()> for SortKey<Scope> {
187 fn into_sort_key(self) -> SortKey<Scope> {
188 self
189 }
190}
191
192#[diagnostic::on_unimplemented(
195 message = "`{Self}` isn't a grouping key",
196 label = "a column or expression, or a `grouping(..)`",
197 note = "a `Grouping` also has to have been discharged against *this* scope: a scope lists its tables most-recently-joined first, so two that look alike can still differ in order"
198)]
199pub trait GroupBy<Scope, Idxs> {
200 #[doc(hidden)]
201 fn into_grouping(self) -> Grouping<Scope>;
202}
203
204impl<Scope: Superset<Req, Idxs>, Req, Idxs, T: IntoExpr<Req = Req>> GroupBy<Scope, Idxs> for T {
205 fn into_grouping(self) -> Grouping<Scope> {
206 Grouping {
207 kind: self.into_expr().kind,
208 _marker: PhantomData,
209 }
210 }
211}
212
213impl<Scope> GroupBy<Scope, ()> for Grouping<Scope> {
214 fn into_grouping(self) -> Grouping<Scope> {
215 self
216 }
217}
218
219pub struct SortKey<Scope> {
224 kind: ExprKind,
225 dir: SortDir,
226 _marker: PhantomData<fn() -> Scope>,
227}
228
229impl<Scope> Clone for SortKey<Scope> {
230 fn clone(&self) -> Self {
231 SortKey {
232 kind: self.kind.clone(),
233 dir: self.dir,
234 _marker: PhantomData,
235 }
236 }
237}
238
239pub fn sort_key<Scope, Idxs, K: SortBy<Scope, Idxs>>(key: K) -> SortKey<Scope> {
244 key.into_sort_key()
245}
246
247pub struct Grouping<Scope> {
250 kind: ExprKind,
251 _marker: PhantomData<fn() -> Scope>,
252}
253
254impl<Scope> Clone for Grouping<Scope> {
255 fn clone(&self) -> Self {
256 Grouping {
257 kind: self.kind.clone(),
258 _marker: PhantomData,
259 }
260 }
261}
262
263pub fn grouping<Scope, Idxs, K: GroupBy<Scope, Idxs>>(key: K) -> Grouping<Scope> {
266 key.into_grouping()
267}
268
269#[diagnostic::on_unimplemented(
274 message = "`{Self}` isn't a condition",
275 label = "a comparison (`.eq(..)`, `.gt(..)`, `.is_null()`), an `any_of`/`all_of` of them, a `sql!` fragment of type `Bool`, a `predicate(..)`, or an `EXISTS`/`.contains(..)` of a subquery in *this* dialect",
276 note = "a `Predicate` also has to have been discharged against *this* scope: a scope lists its tables most-recently-joined first, so two that look alike can still differ in order"
277)]
278pub trait Condition<D, Scope, Idxs> {
279 #[doc(hidden)]
282 fn into_predicate(self) -> Predicate<D, Scope>;
283}
284
285impl<D, Scope: Superset<Req, Idxs>, Req, Idxs, T: IntoExpr<Req = Req>> Condition<D, Scope, Idxs>
286 for T
287where
288 T::Sql: BoolLike,
289{
290 fn into_predicate(self) -> Predicate<D, Scope> {
291 Predicate {
292 kind: self.into_expr().kind,
293 _marker: PhantomData,
294 }
295 }
296}
297
298impl<D, Scope> Condition<D, Scope, ()> for Predicate<D, Scope> {
299 fn into_predicate(self) -> Predicate<D, Scope> {
300 self
301 }
302}
303
304pub struct Exists<D, Req> {
313 kind: ExprKind,
314 _marker: PhantomData<fn() -> (D, Req)>,
315}
316
317impl<D, Req> Clone for Exists<D, Req> {
320 fn clone(&self) -> Self {
321 Exists {
322 kind: self.kind.clone(),
323 _marker: PhantomData,
324 }
325 }
326}
327
328impl<D, Scope: Superset<Req, Idxs>, Req, Idxs> Condition<D, Scope, Idxs> for Exists<D, Req> {
329 fn into_predicate(self) -> Predicate<D, Scope> {
330 Predicate {
331 kind: self.kind,
332 _marker: PhantomData,
333 }
334 }
335}
336
337pub struct InSubquery<D, Req> {
342 kind: ExprKind,
343 _marker: PhantomData<fn() -> (D, Req)>,
344}
345
346impl<D, Req> Clone for InSubquery<D, Req> {
347 fn clone(&self) -> Self {
348 InSubquery {
349 kind: self.kind.clone(),
350 _marker: PhantomData,
351 }
352 }
353}
354
355impl<D, Scope: Superset<Req, Idxs>, Req, Idxs> Condition<D, Scope, Idxs> for InSubquery<D, Req> {
356 fn into_predicate(self) -> Predicate<D, Scope> {
357 Predicate {
358 kind: self.kind,
359 _marker: PhantomData,
360 }
361 }
362}
363
364pub struct Predicate<D, Scope> {
370 kind: ExprKind,
371 _marker: PhantomData<fn() -> (D, Scope)>,
372}
373
374impl<D, Scope> Clone for Predicate<D, Scope> {
377 fn clone(&self) -> Self {
378 Predicate {
379 kind: self.kind.clone(),
380 _marker: PhantomData,
381 }
382 }
383}
384
385impl<D, Scope> Predicate<D, Scope> {
386 pub fn any_of(preds: impl IntoIterator<Item = Predicate<D, Scope>>) -> Self {
391 Predicate::combine(preds, false)
392 }
393
394 pub fn all_of(preds: impl IntoIterator<Item = Predicate<D, Scope>>) -> Self {
397 Predicate::combine(preds, true)
398 }
399
400 fn combine(preds: impl IntoIterator<Item = Predicate<D, Scope>>, all: bool) -> Self {
401 Predicate {
402 kind: crate::expr::fold_conditions(preds.into_iter().map(Predicate::into_kind), all),
403 _marker: PhantomData,
404 }
405 }
406
407 pub(crate) fn into_kind(self) -> ExprKind {
408 self.kind
409 }
410}
411
412pub fn predicate<D, Scope, Idxs, C: Condition<D, Scope, Idxs>>(cond: C) -> Predicate<D, Scope> {
416 cond.into_predicate()
417}
418
419pub struct SelectSeed<Sel> {
426 selection: Sel,
427}
428
429pub fn select<Sel>(selection: Sel) -> SelectSeed<Sel> {
430 SelectSeed { selection }
431}
432
433impl<Sel> SelectSeed<Sel> {
434 pub fn to_sql<D: Dialect, Idx>(&self, _dialect: D) -> (String, Vec<Value>)
452 where
453 Sel: Selection<Nil, Idx>,
454 {
455 let mut sink = QuerySink::<D>::new();
456 sink.text("SELECT ");
457 render_select_list::<D>(&self.selection.items(), &mut sink);
458 sink.finish()
459 }
460
461 pub fn from<D, S: JoinSource<D>>(
465 self,
466 source: S,
467 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Nil>, Sel> {
468 let mut body = SelectBody::new(<S::Table as Table>::NAME);
469 body.bind(source);
470 Select {
471 body,
472 selection: self.selection,
473 _marker: PhantomData,
474 }
475 }
476}
477
478#[derive(Debug, Clone)]
483pub(crate) struct SelectBody {
484 ctes: Vec<CteDef>,
485 distinct: bool,
486 from_table: &'static str,
487 joins: Vec<JoinClause>,
488 wheres: Vec<ExprKind>,
489 order_by: Vec<(ExprKind, SortDir)>,
490 group_by: Vec<ExprKind>,
491 having: Vec<ExprKind>,
492 limit: Option<RowCount>,
493 offset: Option<RowCount>,
494}
495
496impl SelectBody {
497 fn new(from_table: &'static str) -> Self {
498 SelectBody {
499 ctes: Vec::new(),
500 distinct: false,
501 from_table,
502 joins: Vec::new(),
503 wheres: Vec::new(),
504 order_by: Vec::new(),
505 group_by: Vec::new(),
506 having: Vec::new(),
507 limit: None,
508 offset: None,
509 }
510 }
511
512 fn count_sql<D: Dialect>(&self, selection: &[SelectItem]) -> (String, Vec<Value>) {
522 let mut body = self.clone();
523 body.order_by.clear();
524 body.limit = None;
525 body.offset = None;
526 let one_row_each = body.group_by.is_empty()
527 && body.having.is_empty()
528 && !body.distinct
529 && selection
530 .iter()
531 .all(|item| matches!(item.kind, ExprKind::Column { .. }));
532
533 let mut sink = QuerySink::<D>::new();
534 if one_row_each {
535 body.render_into::<D>(&[crate::expr::count_item()], &mut sink);
536 return sink.finish();
537 }
538 crate::render::render_count_wrapped::<D>(&mut sink, |sink| {
539 body.render_into::<D>(selection, sink)
540 });
541 sink.finish()
542 }
543
544 fn bind<D, S: JoinSource<D>>(&mut self, source: S) {
547 self.ctes.extend(source.binding());
548 }
549}
550
551pub struct Select<D, Scope, Sel, Outer = Nil> {
556 body: SelectBody,
557 selection: Sel,
558 _marker: PhantomData<fn() -> (D, Scope, Outer)>,
559}
560
561impl<D, Scope, Sel: Clone, Outer> Clone for Select<D, Scope, Sel, Outer> {
563 fn clone(&self) -> Self {
564 Select {
565 body: self.body.clone(),
566 selection: self.selection.clone(),
567 _marker: PhantomData,
568 }
569 }
570}
571
572impl<D, Scope, Sel, Outer> Select<D, Scope, Sel, Outer> {
573 fn retype<NewScope>(self) -> Select<D, NewScope, Sel, Outer> {
574 Select {
575 body: self.body,
576 selection: self.selection,
577 _marker: PhantomData,
578 }
579 }
580
581 pub fn reselect<NewSel>(self, selection: NewSel) -> Select<D, Scope, NewSel, Outer> {
584 Select {
585 body: self.body,
586 selection,
587 _marker: PhantomData,
588 }
589 }
590
591 pub fn filter<C: Condition<D, Scope, Idxs>, Idxs>(mut self, cond: C) -> Self {
595 self.body.wheres.push(cond.into_predicate().into_kind());
596 self
597 }
598
599 pub fn filter_all(mut self, conds: impl IntoIterator<Item = Predicate<D, Scope>>) -> Self {
603 self.body
604 .wheres
605 .extend(conds.into_iter().map(Predicate::into_kind));
606 self
607 }
608
609 pub fn order_by<K: SortBy<Scope, Idxs>, Idxs>(mut self, key: K) -> Self {
610 let key = key.into_sort_key();
611 self.body.order_by.push((key.kind, key.dir));
612 self
613 }
614
615 pub fn order_by_all(mut self, keys: impl IntoIterator<Item = SortKey<Scope>>) -> Self {
619 self.body
620 .order_by
621 .extend(keys.into_iter().map(|k| (k.kind, k.dir)));
622 self
623 }
624
625 pub fn order_by_selected<K, SelIdx, Idx, L>(mut self, _key: K, dir: SortDir) -> Self
642 where
643 K: LookupKey,
644 Sel: Selection<Scope, SelIdx, Output = Row<L>>,
645 L: RowFieldLookup<K::Key, Idx>,
646 Idx: Position,
647 {
648 let mut items = self.selection.items();
649 let item = items.remove(<Idx as Position>::POSITION as usize - 1);
650 self.body.order_by.push((item.kind, dir));
651 self
652 }
653
654 pub fn order_by_selection<SelIdx>(mut self, dir: SortDir) -> Self
660 where
661 Sel: Selection<Scope, SelIdx>,
662 Sel::Output: SingleColumn,
663 {
664 let item = self.selection.items().remove(0);
665 self.body.order_by.push((item.kind, dir));
666 self
667 }
668
669 pub fn distinct(mut self) -> Self {
684 self.body.distinct = true;
685 self
686 }
687
688 pub fn group_by<K: GroupBy<Scope, Idxs>, Idxs>(mut self, key: K) -> Self {
692 self.body.group_by.push(key.into_grouping().kind);
693 self
694 }
695
696 pub fn group_by_all(mut self, keys: impl IntoIterator<Item = Grouping<Scope>>) -> Self {
699 self.body.group_by.extend(keys.into_iter().map(|g| g.kind));
700 self
701 }
702
703 pub fn having<C: Condition<D, Scope, Idxs>, Idxs>(mut self, cond: C) -> Self {
706 self.body.having.push(cond.into_predicate().into_kind());
707 self
708 }
709
710 pub fn having_all(mut self, conds: impl IntoIterator<Item = Predicate<D, Scope>>) -> Self {
713 self.body
714 .having
715 .extend(conds.into_iter().map(Predicate::into_kind));
716 self
717 }
718
719 pub fn limit(mut self, n: impl IntoRowCount) -> Self {
720 self.body.limit = Some(n.into_row_count());
721 self
722 }
723
724 pub fn offset(mut self, n: impl IntoRowCount) -> Self {
725 self.body.offset = Some(n.into_row_count());
726 self
727 }
728
729 pub fn inner_join<S: JoinSource<D>, C, Idxs>(
733 mut self,
734 source: S,
735 on: C,
736 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, Sel, Outer>
737 where
738 C: Condition<D, Cons<TableSlot<S::Table, NotNull>, Scope>, Idxs>,
739 {
740 self.body.bind(source);
741 self.body.joins.push(JoinClause {
742 kind: JoinKind::Inner,
743 table: <S::Table as Table>::NAME,
744 on: on.into_predicate().into_kind(),
745 });
746 self.retype()
747 }
748
749 pub fn left_join<S: JoinSource<D>, C, Idxs>(
750 mut self,
751 source: S,
752 on: C,
753 ) -> Select<D, Cons<TableSlot<S::Table, MaybeNull>, Scope>, Sel, Outer>
754 where
755 C: Condition<D, Cons<TableSlot<S::Table, MaybeNull>, Scope>, Idxs>,
756 {
757 self.body.bind(source);
758 self.body.joins.push(JoinClause {
759 kind: JoinKind::Left,
760 table: <S::Table as Table>::NAME,
761 on: on.into_predicate().into_kind(),
762 });
763 self.retype()
764 }
765
766 pub fn right_join<S: JoinSource<D>, C, Idxs>(
770 mut self,
771 source: S,
772 on: C,
773 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope::Output>, Sel, Outer>
774 where
775 D: SupportsRightJoin,
776 Scope: MapNullable,
777 C: Condition<D, Cons<TableSlot<S::Table, NotNull>, Scope::Output>, Idxs>,
778 {
779 self.body.bind(source);
780 self.body.joins.push(JoinClause {
781 kind: JoinKind::Right,
782 table: <S::Table as Table>::NAME,
783 on: on.into_predicate().into_kind(),
784 });
785 self.retype()
786 }
787
788 pub fn full_join<S: JoinSource<D>, C, Idxs>(
789 mut self,
790 source: S,
791 on: C,
792 ) -> Select<D, Cons<TableSlot<S::Table, MaybeNull>, Scope::Output>, Sel, Outer>
793 where
794 D: SupportsFullOuterJoin,
795 Scope: MapNullable,
796 C: Condition<D, Cons<TableSlot<S::Table, MaybeNull>, Scope::Output>, Idxs>,
797 {
798 self.body.bind(source);
799 self.body.joins.push(JoinClause {
800 kind: JoinKind::Full,
801 table: <S::Table as Table>::NAME,
802 on: on.into_predicate().into_kind(),
803 });
804 self.retype()
805 }
806}
807
808impl<D: Dialect, Scope, Sel> Select<D, Scope, Sel> {
813 pub fn to_sql<Idx>(&self, _dialect: D) -> (String, Vec<Value>)
822 where
823 Sel: Selection<Scope, Idx>,
824 {
825 self.render_as::<Idx>()
826 }
827
828 pub fn count_sql<Idx>(&self, _dialect: D) -> (String, Vec<Value>)
837 where
838 Sel: Selection<Scope, Idx>,
839 {
840 self.body.count_sql::<D>(&self.selection.items())
841 }
842}
843
844impl<D: Dialect, Scope, Sel> Select<D, Scope, Sel> {
845 pub(crate) fn fragment<Idx>(&self) -> Fragment
852 where
853 Sel: Selection<Scope, Idx>,
854 {
855 let mut sink = FragmentSink::new();
856 self.render_body_into::<Idx>(&mut sink);
857 sink.finish()
858 }
859
860 pub(crate) fn render_body_into<Idx>(&self, sink: &mut dyn crate::render::Sink)
861 where
862 Sel: Selection<Scope, Idx>,
863 {
864 self.body.render_into::<D>(&self.selection.items(), sink);
865 }
866
867 fn render_as<Idx>(&self) -> (String, Vec<Value>)
868 where
869 Sel: Selection<Scope, Idx>,
870 {
871 let mut sink = QuerySink::<D>::new();
872 self.body
873 .render_into::<D>(&self.selection.items(), &mut sink);
874 sink.finish()
875 }
876}
877
878impl SelectBody {
879 pub(crate) fn render_into<D: Dialect>(&self, selection: &[SelectItem], sink: &mut dyn Sink) {
880 let SelectBody {
881 ctes,
882 distinct,
883 from_table,
884 joins,
885 wheres,
886 order_by,
887 group_by,
888 having,
889 limit,
890 offset,
891 } = self;
892
893 if !ctes.is_empty() {
894 sink.text("WITH ");
895 for (i, cte) in ctes.iter().enumerate() {
896 if i > 0 {
897 sink.text(", ");
898 }
899 crate::render::render_ident::<D>(sink, cte.name);
900 sink.text(" (");
901 for (i, col) in cte.column_names.iter().enumerate() {
902 if i > 0 {
903 sink.text(", ");
904 }
905 crate::render::render_ident::<D>(sink, col);
906 }
907 sink.text(") AS (");
908 cte.body.splice_into(sink);
909 sink.ch(')');
910 }
911 sink.ch(' ');
912 }
913 sink.text("SELECT ");
914 if *distinct {
915 sink.text("DISTINCT ");
916 }
917
918 render_select_list::<D>(selection, sink);
919
920 sink.text(" FROM ");
921 crate::render::render_ident::<D>(sink, from_table);
922
923 for j in joins {
924 sink.ch(' ');
925 sink.text(match j.kind {
926 JoinKind::Inner => "INNER JOIN",
927 JoinKind::Left => "LEFT JOIN",
928 JoinKind::Right => "RIGHT JOIN",
929 JoinKind::Full => "FULL JOIN",
930 });
931 sink.ch(' ');
932 crate::render::render_ident::<D>(sink, j.table);
933 sink.text(" ON ");
934 render_expr::<D>(&j.on, sink);
935 }
936
937 render_and_list::<D>(sink, " WHERE ", wheres);
938
939 render_expr_list::<D>(sink, " GROUP BY ", group_by);
940 render_and_list::<D>(sink, " HAVING ", having);
941 render_order_by::<D>(sink, " ORDER BY ", order_by);
942 render_limit_offset::<D>(sink, limit.as_ref(), offset.as_ref());
943 }
944}
945
946pub(crate) fn correlated_with<D, Scope, S: JoinSource<D>, InnerSel>(
951 source: S,
952 selection: InnerSel,
953) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, InnerSel, Scope> {
954 let mut body = SelectBody::new(<S::Table as Table>::NAME);
955 body.bind(source);
956 Select {
957 body,
958 selection,
959 _marker: PhantomData,
960 }
961}
962
963impl<D, Scope, Sel, Outer> Select<D, Scope, Sel, Outer> {
964 pub fn correlated<S: JoinSource<D>, InnerSel>(
977 &self,
978 source: S,
979 selection: InnerSel,
980 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, InnerSel, Scope> {
981 correlated_with(source, selection)
982 }
983}
984
985impl<D: Dialect, Scope, Sel, Outer: ScopeTables> Select<D, Scope, Sel, Outer> {
986 pub fn exists<Idx>(&self) -> Exists<D, Outer::Tables>
992 where
993 Sel: Selection<Scope, Idx>,
994 {
995 self.exists_kind::<Idx>(false)
996 }
997
998 pub fn not_exists<Idx>(&self) -> Exists<D, Outer::Tables>
999 where
1000 Sel: Selection<Scope, Idx>,
1001 {
1002 self.exists_kind::<Idx>(true)
1003 }
1004
1005 fn exists_kind<Idx>(&self, negated: bool) -> Exists<D, Outer::Tables>
1006 where
1007 Sel: Selection<Scope, Idx>,
1008 {
1009 Exists {
1010 kind: ExprKind::Exists {
1011 body: Box::new(self.body.clone()),
1012 selection: self.selection.items(),
1013 negated,
1014 },
1015 _marker: PhantomData,
1016 }
1017 }
1018
1019 pub fn contains<Lhs, Idx>(
1033 &self,
1034 lhs: Lhs,
1035 ) -> InSubquery<D, <Outer::Tables as Concat<Lhs::Req>>::Output>
1036 where
1037 Lhs: IntoExpr,
1038 Lhs::Sql: Comparable<Sel::Sql>,
1039 Sel: RowField<Scope, Idx> + Selection<Scope, Idx>,
1040 Outer::Tables: Concat<Lhs::Req>,
1041 {
1042 self.in_subquery_kind::<Lhs, Idx>(lhs, false)
1043 }
1044
1045 pub fn not_contains<Lhs, Idx>(
1046 &self,
1047 lhs: Lhs,
1048 ) -> InSubquery<D, <Outer::Tables as Concat<Lhs::Req>>::Output>
1049 where
1050 Lhs: IntoExpr,
1051 Lhs::Sql: Comparable<Sel::Sql>,
1052 Sel: RowField<Scope, Idx> + Selection<Scope, Idx>,
1053 Outer::Tables: Concat<Lhs::Req>,
1054 {
1055 self.in_subquery_kind::<Lhs, Idx>(lhs, true)
1056 }
1057
1058 fn in_subquery_kind<Lhs, Idx>(
1059 &self,
1060 lhs: Lhs,
1061 negated: bool,
1062 ) -> InSubquery<D, <Outer::Tables as Concat<Lhs::Req>>::Output>
1063 where
1064 Lhs: IntoExpr,
1065 Lhs::Sql: Comparable<Sel::Sql>,
1066 Sel: RowField<Scope, Idx> + Selection<Scope, Idx>,
1067 Outer::Tables: Concat<Lhs::Req>,
1068 {
1069 InSubquery {
1070 kind: ExprKind::InSubquery {
1071 lhs: Box::new(lhs.into_expr().kind),
1072 body: Box::new(self.body.clone()),
1073 selection: self.selection.items(),
1074 negated,
1075 },
1076 _marker: PhantomData,
1077 }
1078 }
1079}
1080
1081#[diagnostic::on_unimplemented(
1089 message = "`{Self}` isn't a number of rows",
1090 label = "an integer, or a `prepare!{{}}` placeholder of type `Integer`/`BigInt`"
1091)]
1092pub trait IntoRowCount {
1093 fn into_row_count(self) -> RowCount;
1094}
1095
1096#[derive(Debug, Clone)]
1099pub struct RowCount(RowCountKind);
1100
1101#[derive(Debug, Clone)]
1102enum RowCountKind {
1103 Literal(i64),
1106 Bound(ExprKind),
1108}
1109
1110macro_rules! into_row_count {
1111 ($($signed:ty),+ ; $($unsigned:ty),+) => {
1112 $(impl IntoRowCount for $signed {
1113 fn into_row_count(self) -> RowCount {
1114 RowCount(RowCountKind::Literal((self as i64).max(0)))
1115 }
1116 })+
1117 $(impl IntoRowCount for $unsigned {
1118 fn into_row_count(self) -> RowCount {
1119 RowCount(RowCountKind::Literal(i64::try_from(self).unwrap_or(i64::MAX)))
1120 }
1121 })+
1122 };
1123}
1124into_row_count!(i8, i16, i32, i64, isize ; u8, u16, u32, u64, usize);
1125
1126impl IntoRowCount for Expr<Nil, crate::expr::Integer> {
1130 fn into_row_count(self) -> RowCount {
1131 RowCount(RowCountKind::Bound(self.kind))
1132 }
1133}
1134
1135impl IntoRowCount for Expr<Nil, crate::expr::BigInt> {
1136 fn into_row_count(self) -> RowCount {
1137 RowCount(RowCountKind::Bound(self.kind))
1138 }
1139}
1140
1141pub(crate) fn render_limit_offset<D: Dialect>(
1144 sink: &mut dyn Sink,
1145 limit: Option<&RowCount>,
1146 offset: Option<&RowCount>,
1147) {
1148 match (limit, offset, D::OFFSET_WITHOUT_LIMIT) {
1149 (Some(l), _, _) => {
1150 sink.text(" LIMIT ");
1151 render_row_count::<D>(sink, l);
1152 }
1153 (None, Some(_), Some(filler)) => {
1154 sink.text(" LIMIT ");
1155 sink.text(filler);
1156 }
1157 _ => {}
1158 }
1159 if let Some(o) = offset {
1160 sink.text(" OFFSET ");
1161 render_row_count::<D>(sink, o);
1162 }
1163}
1164
1165fn render_row_count<D: Dialect>(sink: &mut dyn Sink, count: &RowCount) {
1166 match &count.0 {
1167 RowCountKind::Literal(n) => sink.text(&n.to_string()),
1168 RowCountKind::Bound(kind) => render_expr::<D>(kind, sink),
1169 }
1170}