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 type Sql: SqlType;
82 fn item(&self) -> SelectItem;
83}
84
85impl<C: ColumnKey, Scope, Idx> RowField<Scope, Idx> for Column<C>
86where
87 Scope: Find<C::Table, Idx>,
88 C::Sql: WrapNullable<<Scope as Find<C::Table, Idx>>::Nullability>,
89 <C::Sql as WrapNullable<<Scope as Find<C::Table, Idx>>::Nullability>>::Output: SqlType,
90{
91 type Value = <<C::Sql as WrapNullable<
92 <Scope as Find<C::Table, Idx>>::Nullability,
93 >>::Output as SqlType>::Native;
94 type Sql = <C::Sql as WrapNullable<<Scope as Find<C::Table, Idx>>::Nullability>>::Output;
95 fn item(&self) -> SelectItem {
96 SelectItem::bare(ExprKind::Column {
97 table: <C::Table as Table>::NAME,
98 name: C::NAME,
99 })
100 }
101}
102
103impl<K, Req, S: SqlType, Scope, Idx> RowField<Scope, Idx> for Keyed<K, Req, S>
104where
105 Scope: Superset<Req, Idx>,
106{
107 type Value = S::Native;
108 type Sql = S;
109 fn item(&self) -> SelectItem {
110 SelectItem::bare(self.kind.clone())
111 }
112}
113
114impl<K: LabelKey, Inner: RowField<Scope, Idx>, Scope, Idx> RowField<Scope, Idx>
119 for Labeled<K, Inner>
120{
121 type Value = Inner::Value;
122 type Sql = Inner::Sql;
123 fn item(&self) -> SelectItem {
124 SelectItem::labeled(self.inner.item().kind, <K as Named>::NAME)
125 }
126}
127
128#[diagnostic::on_unimplemented(
132 message = "`{Self}` isn't a valid selection list here",
133 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 32 of them",
134 note = "every element has to be in scope, so `.from(..)`/`.join(..)` the tables it names; an expression the builder inferred a type for also has to state its decoded type with `.decodes_as::<..>()`"
135)]
136pub trait Selection<Scope, Idx>: private::Sealed<Scope, Idx> {
137 type Output;
138 fn items(&self) -> Vec<SelectItem>;
139}
140
141macro_rules! scalar_selection {
142 (impl[$($generics:tt)*] $ty:ty) => {
143 impl<$($generics)*, Scope, Idx> Selection<Scope, Idx> for $ty
144 where
145 $ty: RowField<Scope, Idx>,
146 {
147 type Output = <$ty as RowField<Scope, Idx>>::Value;
148 fn items(&self) -> Vec<SelectItem> {
149 vec![RowField::item(self)]
150 }
151 }
152 };
153}
154
155#[diagnostic::on_unimplemented(
166 message = "`{Self}` can't be part of a selection list",
167 label = "a column, an aggregate, a window function, a `sql!` fragment, a labelled one of those, `<table>::All`, or a tuple of those can be",
168 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"
169)]
170pub trait SelectionPart<Scope, Idx>: private::Sealed<Scope, Idx> {
171 type Fields<Tail>;
172 fn push_items(&self, out: &mut Vec<SelectItem>);
173}
174
175macro_rules! field_part {
176 (impl[$($generics:tt)*] $ty:ty) => {
177 impl<$($generics)*, Scope, Idx> SelectionPart<Scope, Idx> for $ty
178 where
179 $ty: RowField<Scope, Idx>,
180 {
181 type Fields<Tail> = RowCons<
182 <$ty as RowKey>::Key,
183 <$ty as RowField<Scope, Idx>>::Value,
184 Tail,
185 >;
186 fn push_items(&self, out: &mut Vec<SelectItem>) {
187 out.push(RowField::item(self));
188 }
189 }
190 };
191}
192macro_rules! selectable {
196 (impl[$($generics:tt)*] $ty:ty) => {
197 scalar_selection!(impl[$($generics)*] $ty);
198 field_part!(impl[$($generics)*] $ty);
199 };
200}
201selectable!(impl[C: ColumnKey] Column<C>);
202selectable!(impl[K, Req, S: SqlType] Keyed<K, Req, S>);
203selectable!(impl[K, Inner] Labeled<K, Inner>);
204
205pub struct All<T>(PhantomData<fn() -> T>);
211
212impl<T> All<T> {
213 pub const fn new() -> Self {
214 All(PhantomData)
215 }
216}
217
218impl<T> Clone for All<T> {
219 fn clone(&self) -> Self {
220 *self
221 }
222}
223impl<T> Copy for All<T> {}
224
225impl<T> Default for All<T> {
226 fn default() -> Self {
227 All::new()
228 }
229}
230
231pub trait AllColumns: SelectableSealed {
234 type Columns;
240}
241
242mod column_list {
250 pub trait Sealed {}
251 impl Sealed for crate::scope::Nil {}
252 impl<C: crate::expr::ColumnKey, Tail> Sealed for crate::scope::Cons<crate::expr::Column<C>, Tail> {}
253}
254
255pub trait ColumnList<Scope, Idx>: column_list::Sealed {
256 type Fields<Tail>;
257 fn push_items(out: &mut Vec<SelectItem>);
258}
259
260impl<Scope, Idx> ColumnList<Scope, Idx> for crate::scope::Nil {
261 type Fields<Tail> = Tail;
262 fn push_items(_out: &mut Vec<SelectItem>) {}
263}
264
265impl<C: ColumnKey, Tail, Scope, Idx> ColumnList<Scope, Idx> for crate::scope::Cons<Column<C>, Tail>
266where
267 Column<C>: RowField<Scope, Idx>,
268 Tail: ColumnList<Scope, Idx>,
269{
270 type Fields<T> = RowCons<C, <Column<C> as RowField<Scope, Idx>>::Value, Tail::Fields<T>>;
271 fn push_items(out: &mut Vec<SelectItem>) {
272 out.push(RowField::item(&Column::<C>::new()));
273 Tail::push_items(out);
274 }
275}
276
277impl<T: AllColumns, Scope, Idx> SelectionPart<Scope, Idx> for All<T>
278where
279 T::Columns: ColumnList<Scope, Idx>,
280{
281 type Fields<Tail> = <T::Columns as ColumnList<Scope, Idx>>::Fields<Tail>;
282 fn push_items(&self, out: &mut Vec<SelectItem>) {
283 <T::Columns as ColumnList<Scope, Idx>>::push_items(out);
284 }
285}
286
287impl<T: AllColumns, Scope, Idx> Selection<Scope, Idx> for All<T>
288where
289 T::Columns: ColumnList<Scope, Idx>,
290{
291 type Output = Row<<T::Columns as ColumnList<Scope, Idx>>::Fields<RowNil>>;
292 fn items(&self) -> Vec<SelectItem> {
293 let mut out = Vec::new();
294 <T::Columns as ColumnList<Scope, Idx>>::push_items(&mut out);
295 out
296 }
297}
298
299macro_rules! row_chain {
303 ($tail:ty; $n:ident $i:ident) => {
304 <$n as SelectionPart<Scope, $i>>::Fields<$tail>
305 };
306 ($tail:ty; $n:ident $i:ident, $($rest:tt)*) => {
307 <$n as SelectionPart<Scope, $i>>::Fields<row_chain!($tail; $($rest)*)>
308 };
309}
310
311macro_rules! tuple_selection {
312 ($($n:ident $i:ident),+) => {
313 impl<Scope, $($n,)+ $($i,)+> private::Sealed<Scope, ($($i,)+)> for ($($n,)+)
314 where
315 $($n: SelectionPart<Scope, $i>,)+
316 {
317 }
318
319 #[allow(non_snake_case)]
320 impl<Scope, $($n,)+ $($i,)+> Selection<Scope, ($($i,)+)> for ($($n,)+)
321 where
322 $($n: SelectionPart<Scope, $i>,)+
323 {
324 type Output = Row<row_chain!(RowNil; $($n $i),+)>;
325 fn items(&self) -> Vec<SelectItem> {
326 let ($($n,)+) = self;
327 let mut out = Vec::new();
328 $(SelectionPart::push_items($n, &mut out);)+
329 out
330 }
331 }
332
333 #[allow(non_snake_case)]
334 impl<Scope, $($n,)+ $($i,)+> SelectionPart<Scope, ($($i,)+)> for ($($n,)+)
335 where
336 $($n: SelectionPart<Scope, $i>,)+
337 {
338 type Fields<Tail> = row_chain!(Tail; $($n $i),+);
339 fn push_items(&self, out: &mut Vec<SelectItem>) {
340 let ($($n,)+) = self;
341 $(SelectionPart::push_items($n, out);)+
342 }
343 }
344 };
345}
346tuple_selection!(A IA);
347tuple_selection!(A IA, B IB);
348tuple_selection!(A IA, B IB, C IC);
349tuple_selection!(A IA, B IB, C IC, D ID);
350tuple_selection!(A IA, B IB, C IC, D ID, E IE);
351tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF);
352tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG);
353tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH);
354tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II);
355tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ);
356tuple_selection!(A IA, B IB, C IC, D ID, E IE, F IF, G IG, H IH, I II, J IJ, K IK);
357tuple_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);
358tuple_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);
359tuple_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);
360tuple_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);
361tuple_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);
362tuple_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, Q IQ);
363tuple_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, Q IQ, R IR);
364tuple_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, Q IQ, R IR, S IS);
365tuple_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, Q IQ, R IR, S IS, T IT);
366tuple_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, Q IQ, R IR, S IS, T IT, U IU);
367tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV);
368tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW);
369tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX);
370tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY);
371tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ);
372tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ, AA IAA);
373tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ, AA IAA, BB IBB);
374tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ, AA IAA, BB IBB, CC ICC);
375tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ, AA IAA, BB IBB, CC ICC, DD IDD);
376tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ, AA IAA, BB IBB, CC ICC, DD IDD, EE IEE);
377tuple_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, Q IQ, R IR, S IS, T IT, U IU, V IV, W IW, X IX, Y IY, Z IZ, AA IAA, BB IBB, CC ICC, DD IDD, EE IEE, FF IFF);