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]
443 #[must_use]
444 #[track_caller]
445 pub fn limit<P>(self, limit: P) -> SelectBuilder<'a, S, SelectLimitSet, T, M, R, G>
446 where
447 P: drizzle_core::PaginationArg<'a, PostgresValue<'a>>,
448 {
449 SelectBuilder {
450 sql: self.sql.append(helpers::limit(limit)),
451 schema: PhantomData,
452 state: PhantomData,
453 table: PhantomData,
454 marker: PhantomData,
455 row: PhantomData,
456 grouped: PhantomData,
457 }
458 }
459}
460
461impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
463where
464 State: drizzle_core::OffsetAllowed,
465{
466 #[inline]
473 #[must_use]
474 #[track_caller]
475 pub fn offset<P>(self, offset: P) -> SelectBuilder<'a, S, SelectOffsetSet, T, M, R, G>
476 where
477 P: drizzle_core::PaginationArg<'a, PostgresValue<'a>>,
478 {
479 SelectBuilder {
480 sql: self.sql.append(helpers::offset(offset)),
481 schema: PhantomData,
482 state: PhantomData,
483 table: PhantomData,
484 marker: PhantomData,
485 row: PhantomData,
486 grouped: PhantomData,
487 }
488 }
489}
490
491impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
496where
497 State: AsCteState,
498 T: SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>,
499{
500 #[inline]
502 #[must_use]
503 pub fn into_cte<Tag: drizzle_core::Tag + 'static>(
504 self,
505 ) -> super::CTEView<
506 'a,
507 <T as SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>>::Aliased<Tag>,
508 Self,
509 > {
510 let name = Tag::NAME;
511 super::CTEView::new(
512 <T as SQLTable<'a, PostgresSchemaType, PostgresValue<'a>>>::alias::<Tag>(),
513 name,
514 self,
515 )
516 }
517}
518
519impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
524where
525 State: ExecutableState,
526{
527 pub fn union(
529 self,
530 other: impl IntoSelect<'a, S, M, R>,
531 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
532 SelectBuilder {
533 sql: helpers::union(self.sql, other.into_select()),
534 schema: PhantomData,
535 state: PhantomData,
536 table: PhantomData,
537 marker: PhantomData,
538 row: PhantomData,
539 grouped: PhantomData,
540 }
541 }
542
543 pub fn union_all(
545 self,
546 other: impl IntoSelect<'a, S, M, R>,
547 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
548 SelectBuilder {
549 sql: helpers::union_all(self.sql, other.into_select()),
550 schema: PhantomData,
551 state: PhantomData,
552 table: PhantomData,
553 marker: PhantomData,
554 row: PhantomData,
555 grouped: PhantomData,
556 }
557 }
558
559 pub fn intersect(
561 self,
562 other: impl IntoSelect<'a, S, M, R>,
563 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
564 SelectBuilder {
565 sql: helpers::intersect(self.sql, other.into_select()),
566 schema: PhantomData,
567 state: PhantomData,
568 table: PhantomData,
569 marker: PhantomData,
570 row: PhantomData,
571 grouped: PhantomData,
572 }
573 }
574
575 pub fn intersect_all(
577 self,
578 other: impl IntoSelect<'a, S, M, R>,
579 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
580 SelectBuilder {
581 sql: helpers::intersect_all(self.sql, other.into_select()),
582 schema: PhantomData,
583 state: PhantomData,
584 table: PhantomData,
585 marker: PhantomData,
586 row: PhantomData,
587 grouped: PhantomData,
588 }
589 }
590
591 pub fn except(
593 self,
594 other: impl IntoSelect<'a, S, M, R>,
595 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
596 SelectBuilder {
597 sql: helpers::except(self.sql, other.into_select()),
598 schema: PhantomData,
599 state: PhantomData,
600 table: PhantomData,
601 marker: PhantomData,
602 row: PhantomData,
603 grouped: PhantomData,
604 }
605 }
606
607 pub fn except_all(
609 self,
610 other: impl IntoSelect<'a, S, M, R>,
611 ) -> SelectBuilder<'a, S, SelectSetOpSet, T, M, R, G> {
612 SelectBuilder {
613 sql: helpers::except_all(self.sql, other.into_select()),
614 schema: PhantomData,
615 state: PhantomData,
616 table: PhantomData,
617 marker: PhantomData,
618 row: PhantomData,
619 grouped: PhantomData,
620 }
621 }
622}
623
624impl<'a, S, State, T, M, R, G> drizzle_core::expr::Expr<'a, PostgresValue<'a>>
629 for SelectBuilder<'a, S, State, T, M, R, G>
630where
631 State: ExecutableState,
632 M: drizzle_core::expr::SubqueryType<'a, PostgresValue<'a>>,
633{
634 type SQLType = <M as drizzle_core::expr::SubqueryType<'a, PostgresValue<'a>>>::SQLType;
635 type Nullable = drizzle_core::expr::Null;
636 type Aggregate = drizzle_core::expr::Scalar;
637}
638
639pub trait IntoSelect<'a, S, M, R> {
646 type State: ExecutableState;
647 type Table;
648 fn into_select(self) -> SelectBuilder<'a, S, Self::State, Self::Table, M, R>;
649}
650
651impl<'a, S, State: ExecutableState, T, M, R, G> IntoSelect<'a, S, M, R>
652 for SelectBuilder<'a, S, State, T, M, R, G>
653{
654 type State = State;
655 type Table = T;
656 fn into_select(self) -> SelectBuilder<'a, S, State, T, M, R> {
657 SelectBuilder {
658 sql: self.sql,
659 schema: PhantomData,
660 state: PhantomData,
661 table: PhantomData,
662 marker: PhantomData,
663 row: PhantomData,
664 grouped: PhantomData,
665 }
666 }
667}
668
669pub trait ForLockableState {}
675
676impl ForLockableState for SelectFromSet {}
677impl ForLockableState for SelectWhereSet {}
678impl ForLockableState for SelectOrderSet {}
679impl ForLockableState for SelectLimitSet {}
680impl ForLockableState for SelectOffsetSet {}
681impl ForLockableState for SelectJoinSet {}
682impl ForLockableState for SelectGroupSet {}
683
684impl<'a, S, State, T, M, R, G> SelectBuilder<'a, S, State, T, M, R, G>
685where
686 State: ForLockableState,
687{
688 #[must_use]
690 pub fn for_update(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
691 SelectBuilder {
692 sql: self.sql.append(helpers::for_update()),
693 schema: PhantomData,
694 state: PhantomData,
695 table: PhantomData,
696 marker: PhantomData,
697 row: PhantomData,
698 grouped: PhantomData,
699 }
700 }
701
702 #[must_use]
704 pub fn for_share(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
705 SelectBuilder {
706 sql: self.sql.append(helpers::for_share()),
707 schema: PhantomData,
708 state: PhantomData,
709 table: PhantomData,
710 marker: PhantomData,
711 row: PhantomData,
712 grouped: PhantomData,
713 }
714 }
715
716 #[must_use]
718 pub fn for_no_key_update(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
719 SelectBuilder {
720 sql: self.sql.append(helpers::for_no_key_update()),
721 schema: PhantomData,
722 state: PhantomData,
723 table: PhantomData,
724 marker: PhantomData,
725 row: PhantomData,
726 grouped: PhantomData,
727 }
728 }
729
730 #[must_use]
732 pub fn for_key_share(self) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
733 SelectBuilder {
734 sql: self.sql.append(helpers::for_key_share()),
735 schema: PhantomData,
736 state: PhantomData,
737 table: PhantomData,
738 marker: PhantomData,
739 row: PhantomData,
740 grouped: PhantomData,
741 }
742 }
743
744 pub fn for_update_of<U: PostgresTable<'a>>(
746 self,
747 table: U,
748 ) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
749 SelectBuilder {
750 sql: self.sql.append(helpers::for_update_of(table.name())),
751 schema: PhantomData,
752 state: PhantomData,
753 table: PhantomData,
754 marker: PhantomData,
755 row: PhantomData,
756 grouped: PhantomData,
757 }
758 }
759
760 pub fn for_share_of<U: PostgresTable<'a>>(
762 self,
763 table: U,
764 ) -> SelectBuilder<'a, S, SelectForSet, T, M, R, G> {
765 SelectBuilder {
766 sql: self.sql.append(helpers::for_share_of(table.name())),
767 schema: PhantomData,
768 state: PhantomData,
769 table: PhantomData,
770 marker: PhantomData,
771 row: PhantomData,
772 grouped: PhantomData,
773 }
774 }
775}
776
777impl<S, T, M, R, G> SelectBuilder<'_, S, SelectForSet, T, M, R, G> {
782 #[must_use]
784 pub fn nowait(self) -> Self {
785 SelectBuilder {
786 sql: self.sql.append(helpers::nowait()),
787 schema: PhantomData,
788 state: PhantomData,
789 table: PhantomData,
790 marker: PhantomData,
791 row: PhantomData,
792 grouped: PhantomData,
793 }
794 }
795
796 #[must_use]
798 pub fn skip_locked(self) -> Self {
799 SelectBuilder {
800 sql: self.sql.append(helpers::skip_locked()),
801 schema: PhantomData,
802 state: PhantomData,
803 table: PhantomData,
804 marker: PhantomData,
805 row: PhantomData,
806 grouped: PhantomData,
807 }
808 }
809}
810
811#[cfg(test)]
812mod tests {
813 use super::*;
814 use drizzle_core::{SQL, ToSQL};
815
816 #[test]
817 fn test_select_builder_creation() {
818 let builder = SelectBuilder::<(), SelectInitial> {
819 sql: SQL::raw("SELECT *"),
820 schema: PhantomData,
821 state: PhantomData,
822 table: PhantomData,
823 marker: PhantomData,
824 row: PhantomData,
825 grouped: PhantomData,
826 };
827
828 assert_eq!(builder.to_sql().sql(), "SELECT *");
829 }
830}