1use crate::common::PostgresSchemaType;
2use crate::helpers;
3use crate::traits::PostgresTable;
4use crate::values::PostgresValue;
5use core::fmt::Debug;
6use core::marker::PhantomData;
7use drizzle_core::ToSQL;
8use drizzle_core::traits::SQLTable;
9use paste::paste;
10
11use super::ExecutableState;
13
14#[derive(Debug, Clone, Copy, Default)]
20pub struct SelectInitial;
21
22#[derive(Debug, Clone, Copy, Default)]
24pub struct SelectFromSet;
25
26#[derive(Debug, Clone, Copy, Default)]
28pub struct SelectJoinSet;
29
30#[derive(Debug, Clone, Copy, Default)]
32pub struct SelectWhereSet;
33
34#[derive(Debug, Clone, Copy, Default)]
36pub struct SelectGroupSet;
37
38#[derive(Debug, Clone, Copy, Default)]
40pub struct SelectOrderSet;
41
42#[derive(Debug, Clone, Copy, Default)]
44pub struct SelectLimitSet;
45
46#[derive(Debug, Clone, Copy, Default)]
48pub struct SelectOffsetSet;
49
50#[derive(Debug, Clone, Copy, Default)]
52pub struct SelectSetOpSet;
53
54#[derive(Debug, Clone, Copy, Default)]
56pub struct SelectForSet;
57
58#[doc(hidden)]
63macro_rules! join_impl {
64 () => {
65 join_impl!(natural, Join::new().natural(), drizzle_core::AfterJoin);
66 join_impl!(natural_left, Join::new().natural().left(), drizzle_core::AfterLeftJoin);
67 join_impl!(left, Join::new().left(), drizzle_core::AfterLeftJoin);
68 join_impl!(left_outer, Join::new().left().outer(), drizzle_core::AfterLeftJoin);
69 join_impl!(natural_left_outer, Join::new().natural().left().outer(), drizzle_core::AfterLeftJoin);
70 join_impl!(natural_right, Join::new().natural().right(), drizzle_core::AfterRightJoin);
71 join_impl!(right, Join::new().right(), drizzle_core::AfterRightJoin);
72 join_impl!(right_outer, Join::new().right().outer(), drizzle_core::AfterRightJoin);
73 join_impl!(natural_right_outer, Join::new().natural().right().outer(), drizzle_core::AfterRightJoin);
74 join_impl!(natural_full, Join::new().natural().full(), drizzle_core::AfterFullJoin);
75 join_impl!(full, Join::new().full(), drizzle_core::AfterFullJoin);
76 join_impl!(full_outer, Join::new().full().outer(), drizzle_core::AfterFullJoin);
77 join_impl!(natural_full_outer, Join::new().natural().full().outer(), drizzle_core::AfterFullJoin);
78 join_impl!(inner, Join::new().inner(), drizzle_core::AfterJoin);
79 join_impl!(cross, Join::new().cross(), drizzle_core::AfterJoin);
80
81 join_using_impl!(left, drizzle_core::AfterLeftJoin);
83 join_using_impl!(left_outer, drizzle_core::AfterLeftJoin);
84 join_using_impl!(right, drizzle_core::AfterRightJoin);
85 join_using_impl!(right_outer, drizzle_core::AfterRightJoin);
86 join_using_impl!(full, drizzle_core::AfterFullJoin);
87 join_using_impl!(full_outer, drizzle_core::AfterFullJoin);
88 join_using_impl!(inner, drizzle_core::AfterJoin);
89 join_using_impl!(); };
91 ($type:ident, $join_expr:expr, $join_trait:path) => {
92 paste! {
93 pub fn [<$type _join>]<J: crate::helpers::JoinArg<'a, T>>(
95 self,
96 arg: J,
97 ) -> SelectBuilder<'a, S, SelectJoinSet, J::JoinedTable, <M as drizzle_core::ScopePush<J::JoinedTable>>::Out, <M as $join_trait<R, J::JoinedTable>>::NewRow, G>
98 where
99 M: $join_trait<R, J::JoinedTable> + drizzle_core::ScopePush<J::JoinedTable>,
100 {
101 use drizzle_core::Join;
102 SelectBuilder {
103 sql: self.sql.append(arg.into_join_sql($join_expr)),
104 schema: PhantomData,
105 state: PhantomData,
106 table: PhantomData,
107 marker: PhantomData,
108 row: PhantomData,
109 grouped: PhantomData,
110 }
111 }
112 }
113 };
114}
115
116macro_rules! join_using_impl {
117 () => {
118 pub fn join_using<U: PostgresTable<'a>>(
120 self,
121 table: U,
122 columns: impl ToSQL<'a, PostgresValue<'a>>,
123 ) -> SelectBuilder<
124 'a,
125 S,
126 SelectJoinSet,
127 U,
128 <M as drizzle_core::ScopePush<U>>::Out,
129 <M as drizzle_core::AfterJoin<R, U>>::NewRow,
130 G,
131 >
132 where
133 M: drizzle_core::AfterJoin<R, U> + drizzle_core::ScopePush<U>,
134 {
135 SelectBuilder {
136 sql: self.sql.append(helpers::join_using(table, columns)),
137 schema: PhantomData,
138 state: PhantomData,
139 table: PhantomData,
140 marker: PhantomData,
141 row: PhantomData,
142 grouped: PhantomData,
143 }
144 }
145 };
146 ($type:ident, $join_trait:path) => {
147 paste! {
148 pub fn [<$type _join_using>]<U: PostgresTable<'a>>(
150 self,
151 table: U,
152 columns: impl ToSQL<'a, PostgresValue<'a>>,
153 ) -> SelectBuilder<
154 'a,
155 S,
156 SelectJoinSet,
157 U,
158 <M as drizzle_core::ScopePush<U>>::Out,
159 <M as $join_trait<R, U>>::NewRow,
160 G,
161 >
162 where
163 M: $join_trait<R, U> + drizzle_core::ScopePush<U>,
164 {
165 SelectBuilder {
166 sql: self.sql.append(helpers::[<$type _join_using>](table, columns)),
167 schema: PhantomData,
168 state: PhantomData,
169 table: PhantomData,
170 marker: PhantomData,
171 row: PhantomData,
172 grouped: PhantomData,
173 }
174 }
175 }
176 };
177}
178
179impl ExecutableState for SelectFromSet {}
185impl ExecutableState for SelectWhereSet {}
186impl ExecutableState for SelectLimitSet {}
187impl ExecutableState for SelectOffsetSet {}
188impl ExecutableState for SelectOrderSet {}
189impl ExecutableState for SelectGroupSet {}
190impl ExecutableState for SelectJoinSet {}
191impl ExecutableState for SelectSetOpSet {}
192impl ExecutableState for SelectForSet {}
193
194impl drizzle_core::WhereAllowed for SelectFromSet {}
196impl drizzle_core::WhereAllowed for SelectJoinSet {}
197
198impl drizzle_core::GroupByAllowed for SelectFromSet {}
200impl drizzle_core::GroupByAllowed for SelectJoinSet {}
201impl drizzle_core::GroupByAllowed for SelectWhereSet {}
202
203impl drizzle_core::OrderByAllowed for SelectFromSet {}
205impl drizzle_core::OrderByAllowed for SelectJoinSet {}
206impl drizzle_core::OrderByAllowed for SelectWhereSet {}
207impl drizzle_core::OrderByAllowed for SelectGroupSet {}
208impl drizzle_core::OrderByAllowed for SelectSetOpSet {}
209
210impl drizzle_core::LimitAllowed for SelectFromSet {}
212impl drizzle_core::LimitAllowed for SelectJoinSet {}
213impl drizzle_core::LimitAllowed for SelectWhereSet {}
214impl drizzle_core::LimitAllowed for SelectGroupSet {}
215impl drizzle_core::LimitAllowed for SelectOrderSet {}
216impl drizzle_core::LimitAllowed for SelectSetOpSet {}
217
218impl drizzle_core::OffsetAllowed for SelectFromSet {}
220impl drizzle_core::OffsetAllowed for SelectLimitSet {}
221impl drizzle_core::OffsetAllowed for SelectSetOpSet {}
222
223impl drizzle_core::JoinAllowed for SelectFromSet {}
225impl drizzle_core::JoinAllowed for SelectJoinSet {}
226
227impl drizzle_core::HavingAllowed for SelectGroupSet {}
229
230impl drizzle_core::GroupByApplied for SelectGroupSet {}
232impl drizzle_core::GroupByApplied for SelectOrderSet {}
233impl drizzle_core::GroupByApplied for SelectLimitSet {}
234impl drizzle_core::GroupByApplied for SelectOffsetSet {}
235impl drizzle_core::GroupByApplied for SelectSetOpSet {}
236
237#[doc(hidden)]
238pub trait AsCteState {}
239
240impl AsCteState for SelectFromSet {}
241impl AsCteState for SelectJoinSet {}
242impl AsCteState for SelectWhereSet {}
243impl AsCteState for SelectGroupSet {}
244impl AsCteState for SelectOrderSet {}
245impl AsCteState for SelectLimitSet {}
246impl AsCteState for SelectOffsetSet {}
247
248pub type SelectBuilder<'a, Schema, State, Table = (), Marker = (), Row = (), Grouped = ()> =
254 super::QueryBuilder<'a, Schema, State, Table, Marker, Row, Grouped>;
255
256impl<'a, S, M> SelectBuilder<'a, S, SelectInitial, (), M> {
261 #[inline]
263 #[allow(clippy::type_complexity)]
264 pub fn from<T>(
265 self,
266 query: T,
267 ) -> SelectBuilder<
268 'a,
269 S,
270 SelectFromSet,
271 T,
272 drizzle_core::Scoped<M, drizzle_core::Cons<T, drizzle_core::Nil>>,
273 <M as drizzle_core::ResolveRow<T>>::Row,
274 >
275 where
276 T: ToSQL<'a, PostgresValue<'a>>,
277 M: drizzle_core::ResolveRow<T>,
278 {
279 SelectBuilder {
280 sql: self.sql.append(helpers::from(query)),
281 schema: PhantomData,
282 state: PhantomData,
283 table: PhantomData,
284 marker: PhantomData,
285 row: PhantomData,
286 grouped: PhantomData,
287 }
288 }
289}
290
291impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
297where
298 State: drizzle_core::JoinAllowed,
299{
300 #[inline]
302 #[allow(clippy::type_complexity)]
303 pub fn join<J: crate::helpers::JoinArg<'a, T>>(
304 self,
305 arg: J,
306 ) -> SelectBuilder<
307 'a,
308 S,
309 SelectJoinSet,
310 J::JoinedTable,
311 <M as drizzle_core::ScopePush<J::JoinedTable>>::Out,
312 <M as drizzle_core::AfterJoin<R, J::JoinedTable>>::NewRow,
313 G,
314 >
315 where
316 M: drizzle_core::AfterJoin<R, J::JoinedTable> + drizzle_core::ScopePush<J::JoinedTable>,
317 {
318 use drizzle_core::Join;
319 SelectBuilder {
320 sql: self.sql.append(arg.into_join_sql(Join::new())),
321 schema: PhantomData,
322 state: PhantomData,
323 table: PhantomData,
324 marker: PhantomData,
325 row: PhantomData,
326 grouped: PhantomData,
327 }
328 }
329
330 join_impl!();
331}
332
333impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
335where
336 State: drizzle_core::WhereAllowed,
337{
338 #[inline]
340 pub fn r#where<E>(self, condition: E) -> SelectBuilder<'a, S, SelectWhereSet, T, M, R, G>
341 where
342 E: drizzle_core::expr::Expr<'a, PostgresValue<'a>>,
343 E::SQLType: drizzle_core::types::BooleanLike,
344 {
345 SelectBuilder {
346 sql: self.sql.append(helpers::r#where(condition)),
347 schema: PhantomData,
348 state: PhantomData,
349 table: PhantomData,
350 marker: PhantomData,
351 row: PhantomData,
352 grouped: PhantomData,
353 }
354 }
355}
356
357impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
359where
360 State: drizzle_core::GroupByAllowed,
361{
362 pub fn group_by<Gr>(
364 self,
365 columns: Gr,
366 ) -> SelectBuilder<'a, S, SelectGroupSet, T, M, R, Gr::Columns>
367 where
368 Gr: drizzle_core::IntoGroupBy<'a, PostgresValue<'a>>,
369 {
370 SelectBuilder {
371 sql: self.sql.append(helpers::group_by_expr(columns)),
372 schema: PhantomData,
373 state: PhantomData,
374 table: PhantomData,
375 marker: PhantomData,
376 row: PhantomData,
377 grouped: PhantomData,
378 }
379 }
380}
381
382impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
384where
385 State: drizzle_core::HavingAllowed,
386{
387 pub fn having<E>(self, condition: E) -> SelectBuilder<'a, S, SelectGroupSet, T, M, R, G>
389 where
390 E: drizzle_core::expr::Expr<'a, PostgresValue<'a>>,
391 E::SQLType: drizzle_core::types::BooleanLike,
392 {
393 SelectBuilder {
394 sql: self.sql.append(helpers::having(condition)),
395 schema: PhantomData,
396 state: PhantomData,
397 table: PhantomData,
398 marker: PhantomData,
399 row: PhantomData,
400 grouped: PhantomData,
401 }
402 }
403}
404
405impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
407where
408 State: drizzle_core::OrderByAllowed,
409{
410 #[inline]
412 pub fn order_by<TOrderBy>(
413 self,
414 expressions: TOrderBy,
415 ) -> SelectBuilder<'a, S, SelectOrderSet, T, M, R, G>
416 where
417 TOrderBy: ToSQL<'a, PostgresValue<'a>>,
418 {
419 SelectBuilder {
420 sql: self.sql.append(helpers::order_by(expressions)),
421 schema: PhantomData,
422 state: PhantomData,
423 table: PhantomData,
424 marker: PhantomData,
425 row: PhantomData,
426 grouped: PhantomData,
427 }
428 }
429}
430
431impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
433where
434 State: drizzle_core::LimitAllowed,
435{
436 #[inline]
438 #[must_use]
439 pub fn limit(self, limit: usize) -> SelectBuilder<'a, S, SelectLimitSet, T, M, R, G> {
440 SelectBuilder {
441 sql: self.sql.append(helpers::limit(limit)),
442 schema: PhantomData,
443 state: PhantomData,
444 table: PhantomData,
445 marker: PhantomData,
446 row: PhantomData,
447 grouped: PhantomData,
448 }
449 }
450}
451
452impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
454where
455 State: drizzle_core::OffsetAllowed,
456{
457 #[inline]
459 #[must_use]
460 pub fn offset(self, offset: usize) -> SelectBuilder<'a, S, SelectOffsetSet, T, M, R, G> {
461 SelectBuilder {
462 sql: self.sql.append(helpers::offset(offset)),
463 schema: PhantomData,
464 state: PhantomData,
465 table: PhantomData,
466 marker: PhantomData,
467 row: PhantomData,
468 grouped: PhantomData,
469 }
470 }
471}
472
473impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
478where
479 State: AsCteState,
480 T: SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>,
481{
482 #[inline]
484 #[must_use]
485 pub fn into_cte<Tag: drizzle_core::Tag + 'static>(
486 self,
487 ) -> super::CTEView<
488 'a,
489 <T as SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>>::Aliased<Tag>,
490 Self,
491 > {
492 let name = Tag::NAME;
493 super::CTEView::new(
494 <T as SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>>::alias::<Tag>(),
495 name,
496 self,
497 )
498 }
499}
500
501impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
506where
507 State: ExecutableState,
508{
509 pub fn union(
511 self,
512 other: impl IntoSelect<'a, S, M, R>,
513 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
514 SelectBuilder {
515 sql: helpers::union(self.sql, other.into_select()),
516 schema: PhantomData,
517 state: PhantomData,
518 table: PhantomData,
519 marker: PhantomData,
520 row: PhantomData,
521 grouped: PhantomData,
522 }
523 }
524
525 pub fn union_all(
527 self,
528 other: impl IntoSelect<'a, S, M, R>,
529 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
530 SelectBuilder {
531 sql: helpers::union_all(self.sql, other.into_select()),
532 schema: PhantomData,
533 state: PhantomData,
534 table: PhantomData,
535 marker: PhantomData,
536 row: PhantomData,
537 grouped: PhantomData,
538 }
539 }
540
541 pub fn intersect(
543 self,
544 other: impl IntoSelect<'a, S, M, R>,
545 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
546 SelectBuilder {
547 sql: helpers::intersect(self.sql, other.into_select()),
548 schema: PhantomData,
549 state: PhantomData,
550 table: PhantomData,
551 marker: PhantomData,
552 row: PhantomData,
553 grouped: PhantomData,
554 }
555 }
556
557 pub fn intersect_all(
559 self,
560 other: impl IntoSelect<'a, S, M, R>,
561 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
562 SelectBuilder {
563 sql: helpers::intersect_all(self.sql, other.into_select()),
564 schema: PhantomData,
565 state: PhantomData,
566 table: PhantomData,
567 marker: PhantomData,
568 row: PhantomData,
569 grouped: PhantomData,
570 }
571 }
572
573 pub fn except(
575 self,
576 other: impl IntoSelect<'a, S, M, R>,
577 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
578 SelectBuilder {
579 sql: helpers::except(self.sql, other.into_select()),
580 schema: PhantomData,
581 state: PhantomData,
582 table: PhantomData,
583 marker: PhantomData,
584 row: PhantomData,
585 grouped: PhantomData,
586 }
587 }
588
589 pub fn except_all(
591 self,
592 other: impl IntoSelect<'a, S, M, R>,
593 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
594 SelectBuilder {
595 sql: helpers::except_all(self.sql, other.into_select()),
596 schema: PhantomData,
597 state: PhantomData,
598 table: PhantomData,
599 marker: PhantomData,
600 row: PhantomData,
601 grouped: PhantomData,
602 }
603 }
604}
605
606impl<'a, S, State, T, M, R, G> drizzle_core::expr::Expr<'a, PostgresValue<'a>>
611 for SelectBuilder<'a, S, State, T, M, R, G>
612where
613 State: ExecutableState,
614 M: drizzle_core::expr::SubqueryType<'a, PostgresValue<'a>>,
615{
616 type SQLType = <M as drizzle_core::expr::SubqueryType<'a, PostgresValue<'a>>>::SQLType;
617 type Nullable = drizzle_core::expr::Null;
618 type Aggregate = drizzle_core::expr::Scalar;
619}
620
621pub trait IntoSelect<'a, S, M, R> {
628 type State: ExecutableState;
629 type Table;
630 fn into_select(self) -> SelectBuilder<'a, S, Self::State, Self::Table, M, R>;
631}
632
633impl<'a, S, State: ExecutableState, T, M, R, G> IntoSelect<'a, S, M, R>
634 for SelectBuilder<'a, S, State, T, M, R, G>
635{
636 type State = State;
637 type Table = T;
638 fn into_select(self) -> SelectBuilder<'a, S, State, T, M, R> {
639 SelectBuilder {
640 sql: self.sql,
641 schema: PhantomData,
642 state: PhantomData,
643 table: PhantomData,
644 marker: PhantomData,
645 row: PhantomData,
646 grouped: PhantomData,
647 }
648 }
649}
650
651pub trait ForLockableState {}
657
658impl ForLockableState for SelectFromSet {}
659impl ForLockableState for SelectWhereSet {}
660impl ForLockableState for SelectOrderSet {}
661impl ForLockableState for SelectLimitSet {}
662impl ForLockableState for SelectOffsetSet {}
663impl ForLockableState for SelectJoinSet {}
664impl ForLockableState for SelectGroupSet {}
665
666impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
667where
668 State: ForLockableState,
669{
670 #[must_use]
672 pub fn for_update(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
673 SelectBuilder {
674 sql: self.sql.append(helpers::for_update()),
675 schema: PhantomData,
676 state: PhantomData,
677 table: PhantomData,
678 marker: PhantomData,
679 row: PhantomData,
680 grouped: PhantomData,
681 }
682 }
683
684 #[must_use]
686 pub fn for_share(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
687 SelectBuilder {
688 sql: self.sql.append(helpers::for_share()),
689 schema: PhantomData,
690 state: PhantomData,
691 table: PhantomData,
692 marker: PhantomData,
693 row: PhantomData,
694 grouped: PhantomData,
695 }
696 }
697
698 #[must_use]
700 pub fn for_no_key_update(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
701 SelectBuilder {
702 sql: self.sql.append(helpers::for_no_key_update()),
703 schema: PhantomData,
704 state: PhantomData,
705 table: PhantomData,
706 marker: PhantomData,
707 row: PhantomData,
708 grouped: PhantomData,
709 }
710 }
711
712 #[must_use]
714 pub fn for_key_share(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
715 SelectBuilder {
716 sql: self.sql.append(helpers::for_key_share()),
717 schema: PhantomData,
718 state: PhantomData,
719 table: PhantomData,
720 marker: PhantomData,
721 row: PhantomData,
722 grouped: PhantomData,
723 }
724 }
725
726 pub fn for_update_of<U: PostgresTable<'a>>(
728 self,
729 table: U,
730 ) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
731 SelectBuilder {
732 sql: self.sql.append(helpers::for_update_of(table.name())),
733 schema: PhantomData,
734 state: PhantomData,
735 table: PhantomData,
736 marker: PhantomData,
737 row: PhantomData,
738 grouped: PhantomData,
739 }
740 }
741
742 pub fn for_share_of<U: PostgresTable<'a>>(
744 self,
745 table: U,
746 ) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
747 SelectBuilder {
748 sql: self.sql.append(helpers::for_share_of(table.name())),
749 schema: PhantomData,
750 state: PhantomData,
751 table: PhantomData,
752 marker: PhantomData,
753 row: PhantomData,
754 grouped: PhantomData,
755 }
756 }
757}
758
759impl<S, T, M, R, G> SelectBuilder<'_, S, SelectForSet, T, M, R, G> {
764 #[must_use]
766 pub fn nowait(self) -> Self {
767 SelectBuilder {
768 sql: self.sql.append(helpers::nowait()),
769 schema: PhantomData,
770 state: PhantomData,
771 table: PhantomData,
772 marker: PhantomData,
773 row: PhantomData,
774 grouped: PhantomData,
775 }
776 }
777
778 #[must_use]
780 pub fn skip_locked(self) -> Self {
781 SelectBuilder {
782 sql: self.sql.append(helpers::skip_locked()),
783 schema: PhantomData,
784 state: PhantomData,
785 table: PhantomData,
786 marker: PhantomData,
787 row: PhantomData,
788 grouped: PhantomData,
789 }
790 }
791}
792
793#[cfg(test)]
794mod tests {
795 use super::*;
796 use drizzle_core::{SQL, ToSQL};
797
798 #[test]
799 fn test_select_builder_creation() {
800 let builder = SelectBuilder::<(), SelectInitial> {
801 sql: SQL::raw("SELECT *"),
802 schema: PhantomData,
803 state: PhantomData,
804 table: PhantomData,
805 marker: PhantomData,
806 row: PhantomData,
807 grouped: PhantomData,
808 };
809
810 assert_eq!(builder.to_sql().sql(), "SELECT *");
811 }
812}