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 from<D, S: JoinSource<D>>(
438 self,
439 source: S,
440 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Nil>, Sel> {
441 let mut body = SelectBody::new(<S::Table as Table>::NAME);
442 body.bind(source);
443 Select {
444 body,
445 selection: self.selection,
446 _marker: PhantomData,
447 }
448 }
449}
450
451#[derive(Debug, Clone)]
456pub(crate) struct SelectBody {
457 ctes: Vec<CteDef>,
458 distinct: bool,
459 from_table: &'static str,
460 joins: Vec<JoinClause>,
461 wheres: Vec<ExprKind>,
462 order_by: Vec<(ExprKind, SortDir)>,
463 group_by: Vec<ExprKind>,
464 having: Vec<ExprKind>,
465 limit: Option<RowCount>,
466 offset: Option<RowCount>,
467}
468
469impl SelectBody {
470 fn new(from_table: &'static str) -> Self {
471 SelectBody {
472 ctes: Vec::new(),
473 distinct: false,
474 from_table,
475 joins: Vec::new(),
476 wheres: Vec::new(),
477 order_by: Vec::new(),
478 group_by: Vec::new(),
479 having: Vec::new(),
480 limit: None,
481 offset: None,
482 }
483 }
484
485 fn count_sql<D: Dialect>(&self, selection: &[SelectItem]) -> (String, Vec<Value>) {
495 let mut body = self.clone();
496 body.order_by.clear();
497 body.limit = None;
498 body.offset = None;
499 let one_row_each = body.group_by.is_empty()
500 && body.having.is_empty()
501 && !body.distinct
502 && selection
503 .iter()
504 .all(|item| matches!(item.kind, ExprKind::Column { .. }));
505
506 let mut sink = QuerySink::<D>::new();
507 if one_row_each {
508 body.render_into::<D>(&[crate::expr::count_item()], &mut sink);
509 return sink.finish();
510 }
511 crate::render::render_count_wrapped::<D>(&mut sink, |sink| {
512 body.render_into::<D>(selection, sink)
513 });
514 sink.finish()
515 }
516
517 fn bind<D, S: JoinSource<D>>(&mut self, source: S) {
520 self.ctes.extend(source.binding());
521 }
522}
523
524pub struct Select<D, Scope, Sel, Outer = Nil> {
529 body: SelectBody,
530 selection: Sel,
531 _marker: PhantomData<fn() -> (D, Scope, Outer)>,
532}
533
534impl<D, Scope, Sel: Clone, Outer> Clone for Select<D, Scope, Sel, Outer> {
536 fn clone(&self) -> Self {
537 Select {
538 body: self.body.clone(),
539 selection: self.selection.clone(),
540 _marker: PhantomData,
541 }
542 }
543}
544
545impl<D, Scope, Sel, Outer> Select<D, Scope, Sel, Outer> {
546 fn retype<NewScope>(self) -> Select<D, NewScope, Sel, Outer> {
547 Select {
548 body: self.body,
549 selection: self.selection,
550 _marker: PhantomData,
551 }
552 }
553
554 pub fn reselect<NewSel>(self, selection: NewSel) -> Select<D, Scope, NewSel, Outer> {
557 Select {
558 body: self.body,
559 selection,
560 _marker: PhantomData,
561 }
562 }
563
564 pub fn filter<C: Condition<D, Scope, Idxs>, Idxs>(mut self, cond: C) -> Self {
568 self.body.wheres.push(cond.into_predicate().into_kind());
569 self
570 }
571
572 pub fn filter_all(mut self, conds: impl IntoIterator<Item = Predicate<D, Scope>>) -> Self {
576 self.body
577 .wheres
578 .extend(conds.into_iter().map(Predicate::into_kind));
579 self
580 }
581
582 pub fn order_by<K: SortBy<Scope, Idxs>, Idxs>(mut self, key: K) -> Self {
583 let key = key.into_sort_key();
584 self.body.order_by.push((key.kind, key.dir));
585 self
586 }
587
588 pub fn order_by_all(mut self, keys: impl IntoIterator<Item = SortKey<Scope>>) -> Self {
592 self.body
593 .order_by
594 .extend(keys.into_iter().map(|k| (k.kind, k.dir)));
595 self
596 }
597
598 pub fn order_by_selected<K, SelIdx, Idx, L>(mut self, _key: K, dir: SortDir) -> Self
615 where
616 K: LookupKey,
617 Sel: Selection<Scope, SelIdx, Output = Row<L>>,
618 L: RowFieldLookup<K::Key, Idx>,
619 Idx: Position,
620 {
621 let mut items = self.selection.items();
622 let item = items.remove(<Idx as Position>::POSITION as usize - 1);
623 self.body.order_by.push((item.kind, dir));
624 self
625 }
626
627 pub fn order_by_selection<SelIdx>(mut self, dir: SortDir) -> Self
633 where
634 Sel: Selection<Scope, SelIdx>,
635 Sel::Output: SingleColumn,
636 {
637 let item = self.selection.items().remove(0);
638 self.body.order_by.push((item.kind, dir));
639 self
640 }
641
642 pub fn distinct(mut self) -> Self {
657 self.body.distinct = true;
658 self
659 }
660
661 pub fn group_by<K: GroupBy<Scope, Idxs>, Idxs>(mut self, key: K) -> Self {
665 self.body.group_by.push(key.into_grouping().kind);
666 self
667 }
668
669 pub fn group_by_all(mut self, keys: impl IntoIterator<Item = Grouping<Scope>>) -> Self {
672 self.body.group_by.extend(keys.into_iter().map(|g| g.kind));
673 self
674 }
675
676 pub fn having<C: Condition<D, Scope, Idxs>, Idxs>(mut self, cond: C) -> Self {
679 self.body.having.push(cond.into_predicate().into_kind());
680 self
681 }
682
683 pub fn having_all(mut self, conds: impl IntoIterator<Item = Predicate<D, Scope>>) -> Self {
686 self.body
687 .having
688 .extend(conds.into_iter().map(Predicate::into_kind));
689 self
690 }
691
692 pub fn limit(mut self, n: impl IntoRowCount) -> Self {
693 self.body.limit = Some(n.into_row_count());
694 self
695 }
696
697 pub fn offset(mut self, n: impl IntoRowCount) -> Self {
698 self.body.offset = Some(n.into_row_count());
699 self
700 }
701
702 pub fn inner_join<S: JoinSource<D>, C, Idxs>(
706 mut self,
707 source: S,
708 on: C,
709 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, Sel, Outer>
710 where
711 C: Condition<D, Cons<TableSlot<S::Table, NotNull>, Scope>, Idxs>,
712 {
713 self.body.bind(source);
714 self.body.joins.push(JoinClause {
715 kind: JoinKind::Inner,
716 table: <S::Table as Table>::NAME,
717 on: on.into_predicate().into_kind(),
718 });
719 self.retype()
720 }
721
722 pub fn left_join<S: JoinSource<D>, C, Idxs>(
723 mut self,
724 source: S,
725 on: C,
726 ) -> Select<D, Cons<TableSlot<S::Table, MaybeNull>, Scope>, Sel, Outer>
727 where
728 C: Condition<D, Cons<TableSlot<S::Table, MaybeNull>, Scope>, Idxs>,
729 {
730 self.body.bind(source);
731 self.body.joins.push(JoinClause {
732 kind: JoinKind::Left,
733 table: <S::Table as Table>::NAME,
734 on: on.into_predicate().into_kind(),
735 });
736 self.retype()
737 }
738
739 pub fn right_join<S: JoinSource<D>, C, Idxs>(
743 mut self,
744 source: S,
745 on: C,
746 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope::Output>, Sel, Outer>
747 where
748 D: SupportsRightJoin,
749 Scope: MapNullable,
750 C: Condition<D, Cons<TableSlot<S::Table, NotNull>, Scope::Output>, Idxs>,
751 {
752 self.body.bind(source);
753 self.body.joins.push(JoinClause {
754 kind: JoinKind::Right,
755 table: <S::Table as Table>::NAME,
756 on: on.into_predicate().into_kind(),
757 });
758 self.retype()
759 }
760
761 pub fn full_join<S: JoinSource<D>, C, Idxs>(
762 mut self,
763 source: S,
764 on: C,
765 ) -> Select<D, Cons<TableSlot<S::Table, MaybeNull>, Scope::Output>, Sel, Outer>
766 where
767 D: SupportsFullOuterJoin,
768 Scope: MapNullable,
769 C: Condition<D, Cons<TableSlot<S::Table, MaybeNull>, Scope::Output>, Idxs>,
770 {
771 self.body.bind(source);
772 self.body.joins.push(JoinClause {
773 kind: JoinKind::Full,
774 table: <S::Table as Table>::NAME,
775 on: on.into_predicate().into_kind(),
776 });
777 self.retype()
778 }
779}
780
781impl<D: Dialect, Scope, Sel> Select<D, Scope, Sel> {
786 pub fn to_sql<Idx>(&self, _dialect: D) -> (String, Vec<Value>)
795 where
796 Sel: Selection<Scope, Idx>,
797 {
798 self.render_as::<Idx>()
799 }
800
801 pub fn count_sql<Idx>(&self, _dialect: D) -> (String, Vec<Value>)
810 where
811 Sel: Selection<Scope, Idx>,
812 {
813 self.body.count_sql::<D>(&self.selection.items())
814 }
815}
816
817impl<D: Dialect, Scope, Sel> Select<D, Scope, Sel> {
818 pub(crate) fn fragment<Idx>(&self) -> Fragment
825 where
826 Sel: Selection<Scope, Idx>,
827 {
828 let mut sink = FragmentSink::new();
829 self.body
830 .render_into::<D>(&self.selection.items(), &mut sink);
831 sink.finish()
832 }
833
834 fn render_as<Idx>(&self) -> (String, Vec<Value>)
835 where
836 Sel: Selection<Scope, Idx>,
837 {
838 let mut sink = QuerySink::<D>::new();
839 self.body
840 .render_into::<D>(&self.selection.items(), &mut sink);
841 sink.finish()
842 }
843}
844
845impl SelectBody {
846 pub(crate) fn render_into<D: Dialect>(&self, selection: &[SelectItem], sink: &mut dyn Sink) {
847 let SelectBody {
848 ctes,
849 distinct,
850 from_table,
851 joins,
852 wheres,
853 order_by,
854 group_by,
855 having,
856 limit,
857 offset,
858 } = self;
859
860 if !ctes.is_empty() {
861 sink.text("WITH ");
862 for (i, cte) in ctes.iter().enumerate() {
863 if i > 0 {
864 sink.text(", ");
865 }
866 crate::render::render_ident::<D>(sink, cte.name);
867 sink.text(" (");
868 for (i, col) in cte.column_names.iter().enumerate() {
869 if i > 0 {
870 sink.text(", ");
871 }
872 crate::render::render_ident::<D>(sink, col);
873 }
874 sink.text(") AS (");
875 cte.body.splice_into(sink);
876 sink.ch(')');
877 }
878 sink.ch(' ');
879 }
880 sink.text("SELECT ");
881 if *distinct {
882 sink.text("DISTINCT ");
883 }
884
885 render_select_list::<D>(selection, sink);
886
887 sink.text(" FROM ");
888 crate::render::render_ident::<D>(sink, from_table);
889
890 for j in joins {
891 sink.ch(' ');
892 sink.text(match j.kind {
893 JoinKind::Inner => "INNER JOIN",
894 JoinKind::Left => "LEFT JOIN",
895 JoinKind::Right => "RIGHT JOIN",
896 JoinKind::Full => "FULL JOIN",
897 });
898 sink.ch(' ');
899 crate::render::render_ident::<D>(sink, j.table);
900 sink.text(" ON ");
901 render_expr::<D>(&j.on, sink);
902 }
903
904 render_and_list::<D>(sink, " WHERE ", wheres);
905
906 render_expr_list::<D>(sink, " GROUP BY ", group_by);
907 render_and_list::<D>(sink, " HAVING ", having);
908 render_order_by::<D>(sink, " ORDER BY ", order_by);
909 render_limit_offset::<D>(sink, limit.as_ref(), offset.as_ref());
910 }
911}
912
913pub(crate) fn correlated_with<D, Scope, S: JoinSource<D>, InnerSel>(
918 source: S,
919 selection: InnerSel,
920) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, InnerSel, Scope> {
921 let mut body = SelectBody::new(<S::Table as Table>::NAME);
922 body.bind(source);
923 Select {
924 body,
925 selection,
926 _marker: PhantomData,
927 }
928}
929
930impl<D, Scope, Sel, Outer> Select<D, Scope, Sel, Outer> {
931 pub fn correlated<S: JoinSource<D>, InnerSel>(
944 &self,
945 source: S,
946 selection: InnerSel,
947 ) -> Select<D, Cons<TableSlot<S::Table, NotNull>, Scope>, InnerSel, Scope> {
948 correlated_with(source, selection)
949 }
950}
951
952impl<D: Dialect, Scope, Sel, Outer: ScopeTables> Select<D, Scope, Sel, Outer> {
953 pub fn exists<Idx>(&self) -> Exists<D, Outer::Tables>
959 where
960 Sel: Selection<Scope, Idx>,
961 {
962 self.exists_kind::<Idx>(false)
963 }
964
965 pub fn not_exists<Idx>(&self) -> Exists<D, Outer::Tables>
966 where
967 Sel: Selection<Scope, Idx>,
968 {
969 self.exists_kind::<Idx>(true)
970 }
971
972 fn exists_kind<Idx>(&self, negated: bool) -> Exists<D, Outer::Tables>
973 where
974 Sel: Selection<Scope, Idx>,
975 {
976 Exists {
977 kind: ExprKind::Exists {
978 body: Box::new(self.body.clone()),
979 selection: self.selection.items(),
980 negated,
981 },
982 _marker: PhantomData,
983 }
984 }
985
986 pub fn contains<Lhs, Idx>(
1000 &self,
1001 lhs: Lhs,
1002 ) -> InSubquery<D, <Outer::Tables as Concat<Lhs::Req>>::Output>
1003 where
1004 Lhs: IntoExpr,
1005 Lhs::Sql: Comparable<Sel::Sql>,
1006 Sel: RowField<Scope, Idx> + Selection<Scope, Idx>,
1007 Outer::Tables: Concat<Lhs::Req>,
1008 {
1009 self.in_subquery_kind::<Lhs, Idx>(lhs, false)
1010 }
1011
1012 pub fn not_contains<Lhs, Idx>(
1013 &self,
1014 lhs: Lhs,
1015 ) -> InSubquery<D, <Outer::Tables as Concat<Lhs::Req>>::Output>
1016 where
1017 Lhs: IntoExpr,
1018 Lhs::Sql: Comparable<Sel::Sql>,
1019 Sel: RowField<Scope, Idx> + Selection<Scope, Idx>,
1020 Outer::Tables: Concat<Lhs::Req>,
1021 {
1022 self.in_subquery_kind::<Lhs, Idx>(lhs, true)
1023 }
1024
1025 fn in_subquery_kind<Lhs, Idx>(
1026 &self,
1027 lhs: Lhs,
1028 negated: bool,
1029 ) -> InSubquery<D, <Outer::Tables as Concat<Lhs::Req>>::Output>
1030 where
1031 Lhs: IntoExpr,
1032 Lhs::Sql: Comparable<Sel::Sql>,
1033 Sel: RowField<Scope, Idx> + Selection<Scope, Idx>,
1034 Outer::Tables: Concat<Lhs::Req>,
1035 {
1036 InSubquery {
1037 kind: ExprKind::InSubquery {
1038 lhs: Box::new(lhs.into_expr().kind),
1039 body: Box::new(self.body.clone()),
1040 selection: self.selection.items(),
1041 negated,
1042 },
1043 _marker: PhantomData,
1044 }
1045 }
1046}
1047
1048#[diagnostic::on_unimplemented(
1056 message = "`{Self}` isn't a number of rows",
1057 label = "an integer, or a `prepare!{{}}` placeholder of type `Integer`/`BigInt`"
1058)]
1059pub trait IntoRowCount {
1060 fn into_row_count(self) -> RowCount;
1061}
1062
1063#[derive(Debug, Clone)]
1066pub struct RowCount(RowCountKind);
1067
1068#[derive(Debug, Clone)]
1069enum RowCountKind {
1070 Literal(i64),
1073 Bound(ExprKind),
1075}
1076
1077macro_rules! into_row_count {
1078 ($($signed:ty),+ ; $($unsigned:ty),+) => {
1079 $(impl IntoRowCount for $signed {
1080 fn into_row_count(self) -> RowCount {
1081 RowCount(RowCountKind::Literal((self as i64).max(0)))
1082 }
1083 })+
1084 $(impl IntoRowCount for $unsigned {
1085 fn into_row_count(self) -> RowCount {
1086 RowCount(RowCountKind::Literal(i64::try_from(self).unwrap_or(i64::MAX)))
1087 }
1088 })+
1089 };
1090}
1091into_row_count!(i8, i16, i32, i64, isize ; u8, u16, u32, u64, usize);
1092
1093impl IntoRowCount for Expr<Nil, crate::expr::Integer> {
1097 fn into_row_count(self) -> RowCount {
1098 RowCount(RowCountKind::Bound(self.kind))
1099 }
1100}
1101
1102impl IntoRowCount for Expr<Nil, crate::expr::BigInt> {
1103 fn into_row_count(self) -> RowCount {
1104 RowCount(RowCountKind::Bound(self.kind))
1105 }
1106}
1107
1108pub(crate) fn render_limit_offset<D: Dialect>(
1111 sink: &mut dyn Sink,
1112 limit: Option<&RowCount>,
1113 offset: Option<&RowCount>,
1114) {
1115 match (limit, offset, D::OFFSET_WITHOUT_LIMIT) {
1116 (Some(l), _, _) => {
1117 sink.text(" LIMIT ");
1118 render_row_count::<D>(sink, l);
1119 }
1120 (None, Some(_), Some(filler)) => {
1121 sink.text(" LIMIT ");
1122 sink.text(filler);
1123 }
1124 _ => {}
1125 }
1126 if let Some(o) = offset {
1127 sink.text(" OFFSET ");
1128 render_row_count::<D>(sink, o);
1129 }
1130}
1131
1132fn render_row_count<D: Dialect>(sink: &mut dyn Sink, count: &RowCount) {
1133 match &count.0 {
1134 RowCountKind::Literal(n) => sink.text(&n.to_string()),
1135 RowCountKind::Bound(kind) => render_expr::<D>(kind, sink),
1136 }
1137}