1use crate::expr::{Column, ColumnKey, ExprKind, Keyed, LabelKey, Labeled, SqlType};
4use crate::render::SelectItem;
5use std::marker::PhantomData;
6
7use crate::row::{Named, Row, RowCons, RowKey, RowNil};
8use crate::scope::{Find, Superset, Table, WrapNullable};
9
10mod private {
16 pub trait Sealed<Scope, Idx> {}
21}
22
23#[doc(hidden)]
28pub trait SelectableSealed {}
29
30impl<C, Scope, Idx> private::Sealed<Scope, Idx> for Column<C>
31where
32 C: crate::expr::ColumnKey,
33 Scope: Find<C::Table, Idx>,
34{
35}
36
37impl<K, Req, S: SqlType, Scope, Idx> private::Sealed<Scope, Idx> for Keyed<K, Req, S> where
38 Scope: Superset<Req, Idx>
39{
40}
41
42impl<K, Inner, Scope, Idx> private::Sealed<Scope, Idx> for Labeled<K, Inner> where
43 Inner: RowField<Scope, Idx>
44{
45}
46
47impl<T: AllColumns, Scope, Idx> private::Sealed<Scope, Idx> for All<T> where
48 T::Columns: ColumnList<Scope, Idx>
49{
50}
51
52pub trait SingleColumn {}
57
58#[diagnostic::on_unimplemented(
71 message = "`{Self}` can't be a field of this query's rows",
72 label = "a column, an aggregate, a window function, a `sql!` fragment, or a labelled one of those can be",
73 note = "an expression the builder inferred a type for — a comparison, an `is_null`, a `LIKE` — has to state what it decodes to with `.decodes_as::<..>()`, since that inference can contradict the join; a `sql!` fragment already states it"
74)]
75pub trait RowField<Scope, Idx>: RowKey + private::Sealed<Scope, Idx> {
76 type Value;
77 fn item(&self) -> SelectItem;
78}
79
80impl<C: ColumnKey, Scope, Idx> RowField<Scope, Idx> for Column<C>
81where
82 Scope: Find<C::Table, Idx>,
83 C::Sql: WrapNullable<<Scope as Find<C::Table, Idx>>::Nullability>,
84 <C::Sql as WrapNullable<<Scope as Find<C::Table, Idx>>::Nullability>>::Output: SqlType,
85{
86 type Value = <<C::Sql as WrapNullable<
87 <Scope as Find<C::Table, Idx>>::Nullability,
88 >>::Output as SqlType>::Native;
89 fn item(&self) -> SelectItem {
90 SelectItem::bare(ExprKind::Column {
91 table: <C::Table as Table>::NAME,
92 name: C::NAME,
93 })
94 }
95}
96
97impl<K, Req, S: SqlType, Scope, Idx> RowField<Scope, Idx> for Keyed<K, Req, S>
98where
99 Scope: Superset<Req, Idx>,
100{
101 type Value = S::Native;
102 fn item(&self) -> SelectItem {
103 SelectItem::bare(self.kind.clone())
104 }
105}
106
107impl<K: LabelKey, Inner: RowField<Scope, Idx>, Scope, Idx> RowField<Scope, Idx>
112 for Labeled<K, Inner>
113{
114 type Value = Inner::Value;
115 fn item(&self) -> SelectItem {
116 SelectItem::labeled(self.inner.item().kind, <K as Named>::NAME)
117 }
118}
119
120#[diagnostic::on_unimplemented(
124 message = "`{Self}` isn't a valid selection list here",
125 label = "a selection is a column, an aggregate, a window function, a `sql!` fragment, a labelled one of those, `<table>::All`, or a tuple of up to 16 of them",
126 note = "every element has to be in scope — `.from(..)`/`.join(..)` the tables it names — and an expression the builder inferred a type for has to state its decoded type with `.decodes_as::<..>()`"
127)]
128pub trait Selection<Scope, Idx>: private::Sealed<Scope, Idx> {
129 type Output;
130 fn items(&self) -> Vec<SelectItem>;
131}
132
133macro_rules! scalar_selection {
134 (impl[$($generics:tt)*] $ty:ty) => {
135 impl<$($generics)*, Scope, Idx> Selection<Scope, Idx> for $ty
136 where
137 $ty: RowField<Scope, Idx>,
138 {
139 type Output = <$ty as RowField<Scope, Idx>>::Value;
140 fn items(&self) -> Vec<SelectItem> {
141 vec![RowField::item(self)]
142 }
143 }
144 };
145}
146
147#[diagnostic::on_unimplemented(
152 message = "`{Self}` can't be part of a selection list",
153 label = "a column, an aggregate, a window function, a `sql!` fragment, a labelled one of those, or `<table>::All` can be",
154 note = "an expression the builder inferred a type for — a comparison, an `is_null`, a `LIKE` — has to state what it decodes to with `.decodes_as::<..>()`, since that inference can contradict the join"
155)]
156pub trait SelectionPart<Scope, Idx>: private::Sealed<Scope, Idx> {
157 type Fields<Tail>;
158 fn push_items(&self, out: &mut Vec<SelectItem>);
159}
160
161macro_rules! field_part {
162 (impl[$($generics:tt)*] $ty:ty) => {
163 impl<$($generics)*, Scope, Idx> SelectionPart<Scope, Idx> for $ty
164 where
165 $ty: RowField<Scope, Idx>,
166 {
167 type Fields<Tail> = RowCons<
168 <$ty as RowKey>::Key,
169 <$ty as RowField<Scope, Idx>>::Value,
170 Tail,
171 >;
172 fn push_items(&self, out: &mut Vec<SelectItem>) {
173 out.push(RowField::item(self));
174 }
175 }
176 };
177}
178macro_rules! selectable {
182 (impl[$($generics:tt)*] $ty:ty) => {
183 scalar_selection!(impl[$($generics)*] $ty);
184 field_part!(impl[$($generics)*] $ty);
185 };
186}
187selectable!(impl[C: ColumnKey] Column<C>);
188selectable!(impl[K, Req, S: SqlType] Keyed<K, Req, S>);
189selectable!(impl[K, Inner] Labeled<K, Inner>);
190
191pub struct All<T>(PhantomData<fn() -> T>);
197
198impl<T> All<T> {
199 pub const fn new() -> Self {
200 All(PhantomData)
201 }
202}
203
204impl<T> Clone for All<T> {
205 fn clone(&self) -> Self {
206 *self
207 }
208}
209impl<T> Copy for All<T> {}
210
211impl<T> Default for All<T> {
212 fn default() -> Self {
213 All::new()
214 }
215}
216
217pub trait AllColumns: SelectableSealed {
220 type Columns;
226}
227
228mod column_list {
236 pub trait Sealed {}
237 impl Sealed for crate::scope::Nil {}
238 impl<C: crate::expr::ColumnKey, Tail> Sealed for crate::scope::Cons<crate::expr::Column<C>, Tail> {}
239}
240
241pub trait ColumnList<Scope, Idx>: column_list::Sealed {
242 type Fields<Tail>;
243 fn push_items(out: &mut Vec<SelectItem>);
244}
245
246impl<Scope, Idx> ColumnList<Scope, Idx> for crate::scope::Nil {
247 type Fields<Tail> = Tail;
248 fn push_items(_out: &mut Vec<SelectItem>) {}
249}
250
251impl<C: ColumnKey, Tail, Scope, Idx> ColumnList<Scope, Idx> for crate::scope::Cons<Column<C>, Tail>
252where
253 Column<C>: RowField<Scope, Idx>,
254 Tail: ColumnList<Scope, Idx>,
255{
256 type Fields<T> = RowCons<C, <Column<C> as RowField<Scope, Idx>>::Value, Tail::Fields<T>>;
257 fn push_items(out: &mut Vec<SelectItem>) {
258 out.push(RowField::item(&Column::<C>::new()));
259 Tail::push_items(out);
260 }
261}
262
263impl<T: AllColumns, Scope, Idx> SelectionPart<Scope, Idx> for All<T>
264where
265 T::Columns: ColumnList<Scope, Idx>,
266{
267 type Fields<Tail> = <T::Columns as ColumnList<Scope, Idx>>::Fields<Tail>;
268 fn push_items(&self, out: &mut Vec<SelectItem>) {
269 <T::Columns as ColumnList<Scope, Idx>>::push_items(out);
270 }
271}
272
273impl<T: AllColumns, Scope, Idx> Selection<Scope, Idx> for All<T>
274where
275 T::Columns: ColumnList<Scope, Idx>,
276{
277 type Output = Row<<T::Columns as ColumnList<Scope, Idx>>::Fields<RowNil>>;
278 fn items(&self) -> Vec<SelectItem> {
279 let mut out = Vec::new();
280 <T::Columns as ColumnList<Scope, Idx>>::push_items(&mut out);
281 out
282 }
283}
284
285macro_rules! row_chain {
286 ($n:ident $i:ident) => {
287 <$n as SelectionPart<Scope, $i>>::Fields<RowNil>
288 };
289 ($n:ident $i:ident, $($rest:tt)*) => {
290 <$n as SelectionPart<Scope, $i>>::Fields<row_chain!($($rest)*)>
291 };
292}
293
294macro_rules! tuple_selection {
295 ($($n:ident $i:ident),+) => {
296 impl<Scope, $($n,)+ $($i,)+> private::Sealed<Scope, ($($i,)+)> for ($($n,)+)
297 where
298 $($n: SelectionPart<Scope, $i>,)+
299 {
300 }
301
302 #[allow(non_snake_case)]
303 impl<Scope, $($n,)+ $($i,)+> Selection<Scope, ($($i,)+)> for ($($n,)+)
304 where
305 $($n: SelectionPart<Scope, $i>,)+
306 {
307 type Output = Row<row_chain!($($n $i),+)>;
308 fn items(&self) -> Vec<SelectItem> {
309 let ($($n,)+) = self;
310 let mut out = Vec::new();
311 $(SelectionPart::push_items($n, &mut out);)+
312 out
313 }
314 }
315 };
316}
317tuple_selection!(A IA);
318tuple_selection!(A IA, B IB);
319tuple_selection!(A IA, B IB, C IC);
320tuple_selection!(A IA, B IB, C IC, D ID);
321tuple_selection!(A IA, B IB, C IC, D ID, E IE);
322tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF);
323tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG);
324tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH);
325tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II);
326tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ);
327tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK);
328tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK, L IL);
329tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK, L IL, M IM);
330tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK, L IL, M IM, N IN);
331tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK, L IL, M IM, N IN, O IO);
332tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK, L IL, M IM, N IN, O IO, P IP);