Skip to main content

drizzle_postgres/
builder.rs

1//! Query builders for `PostgreSQL` statements.
2//!
3//! [`QueryBuilder`] builds `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `WITH` and
4//! `REFRESH MATERIALIZED VIEW` statements as SQL text plus bound parameters,
5//! without a connection. The driver integrations in the `drizzle` crate wrap
6//! it to run the statements. Each statement kind has a submodule with its
7//! builder states.
8
9use drizzle_core::Token;
10// Re-export common enums and traits from core
11pub use drizzle_core::builder::{BuilderInit, ExecutableState};
12pub use drizzle_core::{
13    OrderBy, SQL, ToSQL,
14    traits::{SQLSchema, SQLTable},
15};
16
17// Local imports
18use crate::{common::PostgresSchemaType, traits::PostgresTable, values::PostgresValue};
19use core::{fmt::Debug, marker::PhantomData};
20
21// Import modules - these provide specific builder types
22pub mod cte;
23pub mod delete;
24pub mod insert;
25pub mod prepared;
26pub mod refresh;
27pub mod select;
28pub mod update;
29
30// Re-export CTE types
31pub use cte::{CTEDefinition, CTEView};
32
33// Export state markers for easier use
34pub use delete::{DeleteInitial, DeleteReturningSet, DeleteWhereSet};
35pub use insert::{
36    InsertColumnsSet, InsertDoUpdateSet, InsertInitial, InsertOnConflictSet, InsertReturningSet,
37    InsertValuesSet, OnConflictBuilder,
38};
39pub use refresh::{
40    RefreshConcurrently, RefreshInitial, RefreshMaterializedView, RefreshWithNoData,
41    refresh_materialized_view,
42};
43pub use select::{
44    SelectForSet, SelectFromSet, SelectGroupSet, SelectInitial, SelectJoinSet, SelectLimitSet,
45    SelectOffsetSet, SelectOrderSet, SelectSetOpSet, SelectWhereSet,
46};
47pub use update::{
48    UpdateFromSet, UpdateInitial, UpdateReturningSet, UpdateSetClauseSet, UpdateWhereSet,
49};
50
51// Re-export SQLViewInfo for convenience when using refresh_materialized_view
52pub use drizzle_core::traits::SQLViewInfo;
53
54/// Builder state after `.with(cte)`: the next call starts the main statement.
55#[derive(Debug, Clone)]
56pub struct CTEInit;
57
58impl ExecutableState for CTEInit {
59    type Rows<R: drizzle_core::row::RowCount> = drizzle_core::row::ZeroOrMore;
60}
61
62/// Builds `PostgreSQL` statements as SQL plus bound parameters, without a connection.
63///
64/// Create one with [`QueryBuilder::new`], then start a statement with
65/// [`select`](QueryBuilder::select), [`insert`](QueryBuilder::insert),
66/// [`update`](QueryBuilder::update), [`delete`](QueryBuilder::delete) or
67/// [`with`](QueryBuilder::with). Each call returns a builder whose type
68/// tracks the clauses added so far, so out-of-order clauses (such as
69/// `.where()` before `.from()`) do not compile. Call `.to_sql()` to get the
70/// statement. The driver crates wrap this builder to run the query.
71///
72/// `Schema` is the schema type from `#[derive(PostgresSchema)]`. The other
73/// type parameters are builder state and are inferred.
74///
75/// # Examples
76///
77/// ```rust
78/// # extern crate self as drizzle;
79/// # mod _drizzle {
80/// #     pub mod core { pub use drizzle_core::*; }
81/// #     pub mod error { pub use drizzle_core::error::*; }
82/// #     pub mod types { pub use drizzle_types::*; }
83/// #     pub mod migrations { pub use drizzle_migrations::*; }
84/// #     pub use drizzle_types::Dialect;
85/// #     pub use drizzle_types as ddl;
86/// #     pub mod postgres {
87/// #         pub mod values { pub use drizzle_postgres::values::*; }
88/// #         pub mod traits { pub use drizzle_postgres::traits::*; }
89/// #         pub mod common { pub use drizzle_postgres::common::*; }
90/// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
91/// #         pub mod builder { pub use drizzle_postgres::builder::*; }
92/// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
93/// #         pub mod expr { pub use drizzle_postgres::expr::*; }
94/// #         pub mod types { pub use drizzle_postgres::types::*; }
95/// #         #[cfg(feature = "aws-data-api")]
96/// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
97/// #         pub struct Row;
98/// #         impl Row {
99/// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
100/// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
101/// #             pub fn len(&self) -> usize { unimplemented!() }
102/// #         }
103/// #         pub mod prelude {
104/// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
105/// #             pub use drizzle_postgres::attrs::*;
106/// #             pub use drizzle_postgres::common::PostgresSchemaType;
107/// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
108/// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
109/// #             pub use drizzle_core::*;
110/// #         }
111/// #     }
112/// # }
113/// # pub use _drizzle::*;
114/// # pub use const_format;
115/// # fn main() {
116/// # use drizzle::postgres::prelude::*;
117/// # use drizzle::postgres::builder::QueryBuilder;
118/// # #[PostgresTable(name = "users")]
119/// # struct User {
120/// #     #[column(serial, primary)]
121/// #     id: i32,
122/// #     name: String,
123/// #     email: Option<String>,
124/// # }
125/// # #[PostgresTable(name = "posts")]
126/// # struct Post {
127/// #     #[column(serial, primary)]
128/// #     id: i32,
129/// #     #[column(references = User::id)]
130/// #     author_id: i32,
131/// #     title: String,
132/// # }
133/// # #[derive(PostgresSchema)]
134/// # struct Schema {
135/// #     user: User,
136/// #     post: Post,
137/// # }
138/// # let db = QueryBuilder::new::<Schema>();
139/// # let Schema { user, post } = Schema::new();
140/// use drizzle::core::expr::eq;
141///
142/// let query = db
143///     .select((user.id, user.name))
144///     .from(user)
145///     .r#where(eq(user.name, "Alice"));
146///
147/// assert_eq!(
148///     query.to_sql().sql(),
149///     r#"SELECT "users"."id", "users"."name" FROM "users" WHERE "users"."name" = $1"#
150/// );
151/// # }
152/// ```
153#[derive(Debug, Clone, Default)]
154pub struct QueryBuilder<
155    'a,
156    Schema = (),
157    State = (),
158    Table = (),
159    Marker = (),
160    Row = (),
161    Grouped = (),
162> {
163    /// The SQL built so far.
164    pub sql: SQL<'a, PostgresValue<'a>>,
165    schema: PhantomData<Schema>,
166    state: PhantomData<State>,
167    table: PhantomData<Table>,
168    marker: PhantomData<Marker>,
169    row: PhantomData<Row>,
170    grouped: PhantomData<Grouped>,
171}
172
173//------------------------------------------------------------------------------
174// QueryBuilder Implementation
175//------------------------------------------------------------------------------
176
177impl<'a, Schema, State, Table, Marker, Row, Grouped> ToSQL<'a, PostgresValue<'a>>
178    for QueryBuilder<'a, Schema, State, Table, Marker, Row, Grouped>
179{
180    fn to_sql(&self) -> SQL<'a, PostgresValue<'a>> {
181        self.sql.clone()
182    }
183}
184
185impl<'a, Schema, State, Table, Marker, Row, Grouped>
186    QueryBuilder<'a, Schema, State, Table, Marker, Row, Grouped>
187where
188    State: ExecutableState,
189{
190    /// Prepends a [sqlcommenter](https://google.github.io/sqlcommenter/) comment
191    /// to the statement.
192    ///
193    /// The text is wrapped in `/* ... */`. Any `/*` or `*/` in the input is
194    /// neutralised so it cannot end the comment early. Empty text adds nothing.
195    ///
196    /// # Examples
197    ///
198    /// ```rust
199    /// # extern crate self as drizzle;
200    /// # mod _drizzle {
201    /// #     pub mod core { pub use drizzle_core::*; }
202    /// #     pub mod error { pub use drizzle_core::error::*; }
203    /// #     pub mod types { pub use drizzle_types::*; }
204    /// #     pub mod migrations { pub use drizzle_migrations::*; }
205    /// #     pub use drizzle_types::Dialect;
206    /// #     pub use drizzle_types as ddl;
207    /// #     pub mod postgres {
208    /// #         pub mod values { pub use drizzle_postgres::values::*; }
209    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
210    /// #         pub mod common { pub use drizzle_postgres::common::*; }
211    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
212    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
213    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
214    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
215    /// #         pub mod types { pub use drizzle_postgres::types::*; }
216    /// #         #[cfg(feature = "aws-data-api")]
217    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
218    /// #         pub struct Row;
219    /// #         impl Row {
220    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
221    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
222    /// #             pub fn len(&self) -> usize { unimplemented!() }
223    /// #         }
224    /// #         pub mod prelude {
225    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
226    /// #             pub use drizzle_postgres::attrs::*;
227    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
228    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
229    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
230    /// #             pub use drizzle_core::*;
231    /// #         }
232    /// #     }
233    /// # }
234    /// # pub use _drizzle::*;
235    /// # pub use const_format;
236    /// # fn main() {
237    /// # use drizzle::postgres::prelude::*;
238    /// # use drizzle::postgres::builder::QueryBuilder;
239    /// # #[PostgresTable(name = "users")]
240    /// # struct User {
241    /// #     #[column(serial, primary)]
242    /// #     id: i32,
243    /// #     name: String,
244    /// #     email: Option<String>,
245    /// # }
246    /// # #[PostgresTable(name = "posts")]
247    /// # struct Post {
248    /// #     #[column(serial, primary)]
249    /// #     id: i32,
250    /// #     #[column(references = User::id)]
251    /// #     author_id: i32,
252    /// #     title: String,
253    /// # }
254    /// # #[derive(PostgresSchema)]
255    /// # struct Schema {
256    /// #     user: User,
257    /// #     post: Post,
258    /// # }
259    /// # let db = QueryBuilder::new::<Schema>();
260    /// # let Schema { user, post } = Schema::new();
261    /// let query = db.select(user.id).from(user).comment("list-users");
262    /// assert_eq!(query.to_sql().sql(), r#"/*list-users*/ SELECT "users"."id" FROM "users""#);
263    /// # }
264    /// ```
265    #[must_use]
266    pub fn comment(mut self, text: impl AsRef<str>) -> Self {
267        let fragment = drizzle_core::sql::comment::<PostgresValue<'a>>(text);
268        if fragment.chunks.is_empty() {
269            return self;
270        }
271        let existing = core::mem::replace(&mut self.sql, fragment);
272        self.sql.append_mut(existing);
273        self
274    }
275
276    /// Prepends a key-value [sqlcommenter](https://google.github.io/sqlcommenter/)
277    /// comment to the statement.
278    ///
279    /// Each pair renders as `key='value'`, URL-encoded. Pairs are sorted by
280    /// key, joined with `,` and wrapped in `/* ... */`. Pairs with an empty
281    /// value are skipped; if none remain, nothing is added.
282    ///
283    /// # Examples
284    ///
285    /// ```rust
286    /// # extern crate self as drizzle;
287    /// # mod _drizzle {
288    /// #     pub mod core { pub use drizzle_core::*; }
289    /// #     pub mod error { pub use drizzle_core::error::*; }
290    /// #     pub mod types { pub use drizzle_types::*; }
291    /// #     pub mod migrations { pub use drizzle_migrations::*; }
292    /// #     pub use drizzle_types::Dialect;
293    /// #     pub use drizzle_types as ddl;
294    /// #     pub mod postgres {
295    /// #         pub mod values { pub use drizzle_postgres::values::*; }
296    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
297    /// #         pub mod common { pub use drizzle_postgres::common::*; }
298    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
299    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
300    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
301    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
302    /// #         pub mod types { pub use drizzle_postgres::types::*; }
303    /// #         #[cfg(feature = "aws-data-api")]
304    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
305    /// #         pub struct Row;
306    /// #         impl Row {
307    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
308    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
309    /// #             pub fn len(&self) -> usize { unimplemented!() }
310    /// #         }
311    /// #         pub mod prelude {
312    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
313    /// #             pub use drizzle_postgres::attrs::*;
314    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
315    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
316    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
317    /// #             pub use drizzle_core::*;
318    /// #         }
319    /// #     }
320    /// # }
321    /// # pub use _drizzle::*;
322    /// # pub use const_format;
323    /// # fn main() {
324    /// # use drizzle::postgres::prelude::*;
325    /// # use drizzle::postgres::builder::QueryBuilder;
326    /// # #[PostgresTable(name = "users")]
327    /// # struct User {
328    /// #     #[column(serial, primary)]
329    /// #     id: i32,
330    /// #     name: String,
331    /// #     email: Option<String>,
332    /// # }
333    /// # #[PostgresTable(name = "posts")]
334    /// # struct Post {
335    /// #     #[column(serial, primary)]
336    /// #     id: i32,
337    /// #     #[column(references = User::id)]
338    /// #     author_id: i32,
339    /// #     title: String,
340    /// # }
341    /// # #[derive(PostgresSchema)]
342    /// # struct Schema {
343    /// #     user: User,
344    /// #     post: Post,
345    /// # }
346    /// # let db = QueryBuilder::new::<Schema>();
347    /// # let Schema { user, post } = Schema::new();
348    /// let query = db
349    ///     .select(user.id)
350    ///     .from(user)
351    ///     .comment_tags([("route", "/users"), ("action", "list")]);
352    /// let sql = query.to_sql().sql();
353    /// assert!(sql.starts_with("/*action='list',route='%2Fusers'*/"));
354    /// # }
355    /// ```
356    #[must_use]
357    pub fn comment_tags<I, K, V>(mut self, pairs: I) -> Self
358    where
359        I: IntoIterator<Item = (K, V)>,
360        K: AsRef<str>,
361        V: AsRef<str>,
362    {
363        let fragment = drizzle_core::sql::comment_tags::<PostgresValue<'a>, _, _, _>(pairs);
364        if fragment.chunks.is_empty() {
365            return self;
366        }
367        let existing = core::mem::replace(&mut self.sql, fragment);
368        self.sql.append_mut(existing);
369        self
370    }
371}
372
373impl<'a> QueryBuilder<'a> {
374    /// Creates a query builder for schema `S`.
375    ///
376    /// # Examples
377    ///
378    /// ```rust
379    /// # extern crate self as drizzle;
380    /// # mod _drizzle {
381    /// #     pub mod core { pub use drizzle_core::*; }
382    /// #     pub mod error { pub use drizzle_core::error::*; }
383    /// #     pub mod types { pub use drizzle_types::*; }
384    /// #     pub mod migrations { pub use drizzle_migrations::*; }
385    /// #     pub use drizzle_types::Dialect;
386    /// #     pub use drizzle_types as ddl;
387    /// #     pub mod postgres {
388    /// #         pub mod values { pub use drizzle_postgres::values::*; }
389    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
390    /// #         pub mod common { pub use drizzle_postgres::common::*; }
391    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
392    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
393    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
394    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
395    /// #         pub mod types { pub use drizzle_postgres::types::*; }
396    /// #         #[cfg(feature = "aws-data-api")]
397    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
398    /// #         pub struct Row;
399    /// #         impl Row {
400    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
401    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
402    /// #             pub fn len(&self) -> usize { unimplemented!() }
403    /// #         }
404    /// #         pub mod prelude {
405    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
406    /// #             pub use drizzle_postgres::attrs::*;
407    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
408    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
409    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
410    /// #             pub use drizzle_core::*;
411    /// #         }
412    /// #     }
413    /// # }
414    /// # pub use _drizzle::*;
415    /// # pub use const_format;
416    /// # fn main() {
417    /// # use drizzle::postgres::prelude::*;
418    /// # use drizzle::postgres::builder::QueryBuilder;
419    /// # #[PostgresTable(name = "users")]
420    /// # struct User {
421    /// #     #[column(serial, primary)]
422    /// #     id: i32,
423    /// #     name: String,
424    /// #     email: Option<String>,
425    /// # }
426    /// # #[PostgresTable(name = "posts")]
427    /// # struct Post {
428    /// #     #[column(serial, primary)]
429    /// #     id: i32,
430    /// #     #[column(references = User::id)]
431    /// #     author_id: i32,
432    /// #     title: String,
433    /// # }
434    /// # #[derive(PostgresSchema)]
435    /// # struct Schema {
436    /// #     user: User,
437    /// #     post: Post,
438    /// # }
439    /// # let Schema { user, post } = Schema::new();
440    /// let db = QueryBuilder::new::<Schema>();
441    /// let query = db.select(()).from(user);
442    /// assert_eq!(
443    ///     query.to_sql().sql(),
444    ///     r#"SELECT "users"."id", "users"."name", "users"."email" FROM "users""#
445    /// );
446    /// # }
447    /// ```
448    #[must_use]
449    pub const fn new<S>() -> QueryBuilder<'a, S, BuilderInit> {
450        QueryBuilder {
451            sql: SQL::empty(),
452            schema: PhantomData,
453            state: PhantomData,
454            table: PhantomData,
455            marker: PhantomData,
456            row: PhantomData,
457            grouped: PhantomData,
458        }
459    }
460}
461
462impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
463    /// Starts a `SELECT` of the given columns.
464    ///
465    /// Pass one column or expression, a tuple of them, or `()` for every
466    /// column of the `FROM` table. Continue with `.from(table)`.
467    ///
468    /// # Examples
469    ///
470    /// ```rust
471    /// # extern crate self as drizzle;
472    /// # mod _drizzle {
473    /// #     pub mod core { pub use drizzle_core::*; }
474    /// #     pub mod error { pub use drizzle_core::error::*; }
475    /// #     pub mod types { pub use drizzle_types::*; }
476    /// #     pub mod migrations { pub use drizzle_migrations::*; }
477    /// #     pub use drizzle_types::Dialect;
478    /// #     pub use drizzle_types as ddl;
479    /// #     pub mod postgres {
480    /// #         pub mod values { pub use drizzle_postgres::values::*; }
481    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
482    /// #         pub mod common { pub use drizzle_postgres::common::*; }
483    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
484    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
485    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
486    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
487    /// #         pub mod types { pub use drizzle_postgres::types::*; }
488    /// #         #[cfg(feature = "aws-data-api")]
489    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
490    /// #         pub struct Row;
491    /// #         impl Row {
492    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
493    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
494    /// #             pub fn len(&self) -> usize { unimplemented!() }
495    /// #         }
496    /// #         pub mod prelude {
497    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
498    /// #             pub use drizzle_postgres::attrs::*;
499    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
500    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
501    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
502    /// #             pub use drizzle_core::*;
503    /// #         }
504    /// #     }
505    /// # }
506    /// # pub use _drizzle::*;
507    /// # pub use const_format;
508    /// # fn main() {
509    /// # use drizzle::postgres::prelude::*;
510    /// # use drizzle::postgres::builder::QueryBuilder;
511    /// # #[PostgresTable(name = "users")]
512    /// # struct User {
513    /// #     #[column(serial, primary)]
514    /// #     id: i32,
515    /// #     name: String,
516    /// #     email: Option<String>,
517    /// # }
518    /// # #[PostgresTable(name = "posts")]
519    /// # struct Post {
520    /// #     #[column(serial, primary)]
521    /// #     id: i32,
522    /// #     #[column(references = User::id)]
523    /// #     author_id: i32,
524    /// #     title: String,
525    /// # }
526    /// # #[derive(PostgresSchema)]
527    /// # struct Schema {
528    /// #     user: User,
529    /// #     post: Post,
530    /// # }
531    /// # let db = QueryBuilder::new::<Schema>();
532    /// # let Schema { user, post } = Schema::new();
533    /// use drizzle::core::expr::eq;
534    ///
535    /// let query = db
536    ///     .select((user.name, post.title))
537    ///     .from(user)
538    ///     .join((post, eq(post.author_id, user.id)));
539    /// assert_eq!(
540    ///     query.to_sql().sql(),
541    ///     r#"SELECT "users"."name", "posts"."title" FROM "users" JOIN "posts" ON "posts"."author_id" = "users"."id""#
542    /// );
543    /// # }
544    /// ```
545    pub fn select<T>(
546        &self,
547        columns: T,
548    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
549    where
550        T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
551    {
552        let sql = crate::helpers::select(columns);
553        select::SelectBuilder {
554            sql,
555            schema: PhantomData,
556            state: PhantomData,
557            table: PhantomData,
558            marker: PhantomData,
559            row: PhantomData,
560            grouped: PhantomData,
561        }
562    }
563
564    /// Starts a `SELECT DISTINCT`, which drops duplicate rows.
565    ///
566    /// # Examples
567    ///
568    /// ```rust
569    /// # extern crate self as drizzle;
570    /// # mod _drizzle {
571    /// #     pub mod core { pub use drizzle_core::*; }
572    /// #     pub mod error { pub use drizzle_core::error::*; }
573    /// #     pub mod types { pub use drizzle_types::*; }
574    /// #     pub mod migrations { pub use drizzle_migrations::*; }
575    /// #     pub use drizzle_types::Dialect;
576    /// #     pub use drizzle_types as ddl;
577    /// #     pub mod postgres {
578    /// #         pub mod values { pub use drizzle_postgres::values::*; }
579    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
580    /// #         pub mod common { pub use drizzle_postgres::common::*; }
581    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
582    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
583    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
584    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
585    /// #         pub mod types { pub use drizzle_postgres::types::*; }
586    /// #         #[cfg(feature = "aws-data-api")]
587    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
588    /// #         pub struct Row;
589    /// #         impl Row {
590    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
591    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
592    /// #             pub fn len(&self) -> usize { unimplemented!() }
593    /// #         }
594    /// #         pub mod prelude {
595    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
596    /// #             pub use drizzle_postgres::attrs::*;
597    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
598    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
599    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
600    /// #             pub use drizzle_core::*;
601    /// #         }
602    /// #     }
603    /// # }
604    /// # pub use _drizzle::*;
605    /// # pub use const_format;
606    /// # fn main() {
607    /// # use drizzle::postgres::prelude::*;
608    /// # use drizzle::postgres::builder::QueryBuilder;
609    /// # #[PostgresTable(name = "users")]
610    /// # struct User {
611    /// #     #[column(serial, primary)]
612    /// #     id: i32,
613    /// #     name: String,
614    /// #     email: Option<String>,
615    /// # }
616    /// # #[PostgresTable(name = "posts")]
617    /// # struct Post {
618    /// #     #[column(serial, primary)]
619    /// #     id: i32,
620    /// #     #[column(references = User::id)]
621    /// #     author_id: i32,
622    /// #     title: String,
623    /// # }
624    /// # #[derive(PostgresSchema)]
625    /// # struct Schema {
626    /// #     user: User,
627    /// #     post: Post,
628    /// # }
629    /// # let db = QueryBuilder::new::<Schema>();
630    /// # let Schema { user, post } = Schema::new();
631    /// let query = db.select_distinct(user.name).from(user);
632    /// assert_eq!(query.to_sql().sql(), r#"SELECT DISTINCT "users"."name" FROM "users""#);
633    /// # }
634    /// ```
635    pub fn select_distinct<T>(
636        &self,
637        columns: T,
638    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
639    where
640        T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
641    {
642        let sql = crate::helpers::select_distinct(columns);
643        select::SelectBuilder {
644            sql,
645            schema: PhantomData,
646            state: PhantomData,
647            table: PhantomData,
648            marker: PhantomData,
649            row: PhantomData,
650            grouped: PhantomData,
651        }
652    }
653
654    /// Starts a `SELECT DISTINCT ON (...)`, which keeps one row per distinct
655    /// value of `on`.
656    ///
657    /// The first row of each group wins, so add an `order_by` that starts
658    /// with the `on` columns to choose which row is kept.
659    ///
660    /// # Examples
661    ///
662    /// ```rust
663    /// # extern crate self as drizzle;
664    /// # mod _drizzle {
665    /// #     pub mod core { pub use drizzle_core::*; }
666    /// #     pub mod error { pub use drizzle_core::error::*; }
667    /// #     pub mod types { pub use drizzle_types::*; }
668    /// #     pub mod migrations { pub use drizzle_migrations::*; }
669    /// #     pub use drizzle_types::Dialect;
670    /// #     pub use drizzle_types as ddl;
671    /// #     pub mod postgres {
672    /// #         pub mod values { pub use drizzle_postgres::values::*; }
673    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
674    /// #         pub mod common { pub use drizzle_postgres::common::*; }
675    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
676    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
677    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
678    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
679    /// #         pub mod types { pub use drizzle_postgres::types::*; }
680    /// #         #[cfg(feature = "aws-data-api")]
681    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
682    /// #         pub struct Row;
683    /// #         impl Row {
684    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
685    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
686    /// #             pub fn len(&self) -> usize { unimplemented!() }
687    /// #         }
688    /// #         pub mod prelude {
689    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
690    /// #             pub use drizzle_postgres::attrs::*;
691    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
692    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
693    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
694    /// #             pub use drizzle_core::*;
695    /// #         }
696    /// #     }
697    /// # }
698    /// # pub use _drizzle::*;
699    /// # pub use const_format;
700    /// # fn main() {
701    /// # use drizzle::postgres::prelude::*;
702    /// # use drizzle::postgres::builder::QueryBuilder;
703    /// # #[PostgresTable(name = "users")]
704    /// # struct User {
705    /// #     #[column(serial, primary)]
706    /// #     id: i32,
707    /// #     name: String,
708    /// #     email: Option<String>,
709    /// # }
710    /// # #[PostgresTable(name = "posts")]
711    /// # struct Post {
712    /// #     #[column(serial, primary)]
713    /// #     id: i32,
714    /// #     #[column(references = User::id)]
715    /// #     author_id: i32,
716    /// #     title: String,
717    /// # }
718    /// # #[derive(PostgresSchema)]
719    /// # struct Schema {
720    /// #     user: User,
721    /// #     post: Post,
722    /// # }
723    /// # let db = QueryBuilder::new::<Schema>();
724    /// # let Schema { user, post } = Schema::new();
725    /// let query = db
726    ///     .select_distinct_on(user.email, (user.id, user.email))
727    ///     .from(user)
728    ///     .order_by(user.email);
729    /// assert_eq!(
730    ///     query.to_sql().sql(),
731    ///     r#"SELECT DISTINCT ON ("users"."email") "users"."id", "users"."email" FROM "users" ORDER BY "users"."email""#
732    /// );
733    /// # }
734    /// ```
735    pub fn select_distinct_on<On, Columns>(
736        &self,
737        on: On,
738        columns: Columns,
739    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), Columns::Marker>
740    where
741        On: ToSQL<'a, PostgresValue<'a>>,
742        Columns: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
743    {
744        let sql = crate::helpers::select_distinct_on(on, columns);
745        select::SelectBuilder {
746            sql,
747            schema: PhantomData,
748            state: PhantomData,
749            table: PhantomData,
750            marker: PhantomData,
751            row: PhantomData,
752            grouped: PhantomData,
753        }
754    }
755}
756
757impl<'a, Schema> QueryBuilder<'a, Schema, CTEInit> {
758    /// Starts the main `SELECT` after `WITH ...`. See [`QueryBuilder::with`].
759    pub fn select<T>(
760        &self,
761        columns: T,
762    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
763    where
764        T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
765    {
766        let sql = self.sql.clone().append(crate::helpers::select(columns));
767        select::SelectBuilder {
768            sql,
769            schema: PhantomData,
770            state: PhantomData,
771            table: PhantomData,
772            marker: PhantomData,
773            row: PhantomData,
774            grouped: PhantomData,
775        }
776    }
777
778    /// Starts the main `SELECT DISTINCT` after `WITH ...`.
779    pub fn select_distinct<T>(
780        &self,
781        columns: T,
782    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), T::Marker>
783    where
784        T: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
785    {
786        let sql = self
787            .sql
788            .clone()
789            .append(crate::helpers::select_distinct(columns));
790        select::SelectBuilder {
791            sql,
792            schema: PhantomData,
793            state: PhantomData,
794            table: PhantomData,
795            marker: PhantomData,
796            row: PhantomData,
797            grouped: PhantomData,
798        }
799    }
800
801    /// Starts the main `SELECT DISTINCT ON (...)` after `WITH ...`.
802    pub fn select_distinct_on<On, Columns>(
803        &self,
804        on: On,
805        columns: Columns,
806    ) -> select::SelectBuilder<'a, Schema, select::SelectInitial, (), Columns::Marker>
807    where
808        On: ToSQL<'a, PostgresValue<'a>>,
809        Columns: ToSQL<'a, PostgresValue<'a>> + drizzle_core::IntoSelectTarget,
810    {
811        let sql = self
812            .sql
813            .clone()
814            .append(crate::helpers::select_distinct_on(on, columns));
815        select::SelectBuilder {
816            sql,
817            schema: PhantomData,
818            state: PhantomData,
819            table: PhantomData,
820            marker: PhantomData,
821            row: PhantomData,
822            grouped: PhantomData,
823        }
824    }
825
826    /// Starts the main `INSERT` after `WITH ...`.
827    pub fn insert<Table>(
828        &self,
829        table: Table,
830    ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
831    where
832        Table: PostgresTable<'a>,
833    {
834        let sql = self
835            .sql
836            .clone()
837            .append(crate::helpers::insert::<Table>(&table));
838
839        insert::InsertBuilder {
840            sql,
841            schema: PhantomData,
842            state: PhantomData,
843            table: PhantomData,
844            marker: PhantomData,
845            row: PhantomData,
846            grouped: PhantomData,
847        }
848    }
849
850    /// Starts the main `UPDATE` after `WITH ...`.
851    pub fn update<Table>(
852        &self,
853        table: Table,
854    ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
855    where
856        Table: PostgresTable<'a>,
857    {
858        let sql = self.sql.clone().append(crate::helpers::update::<
859            Table,
860            PostgresSchemaType,
861            PostgresValue<'a>,
862        >(&table));
863
864        update::UpdateBuilder {
865            sql,
866            schema: PhantomData,
867            state: PhantomData,
868            table: PhantomData,
869            marker: PhantomData,
870            row: PhantomData,
871            grouped: PhantomData,
872        }
873    }
874
875    /// Starts the main `DELETE` after `WITH ...`.
876    pub fn delete<Table>(
877        &self,
878        table: Table,
879    ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
880    where
881        Table: PostgresTable<'a>,
882    {
883        let sql = self.sql.clone().append(crate::helpers::delete::<
884            Table,
885            PostgresSchemaType,
886            PostgresValue<'a>,
887        >(&table));
888
889        delete::DeleteBuilder {
890            sql,
891            schema: PhantomData,
892            state: PhantomData,
893            table: PhantomData,
894            marker: PhantomData,
895            row: PhantomData,
896            grouped: PhantomData,
897        }
898    }
899
900    /// Adds another common table expression to the `WITH` list.
901    #[must_use]
902    pub fn with<C>(&self, cte: &C) -> Self
903    where
904        C: CTEDefinition<'a>,
905    {
906        let sql = self
907            .sql
908            .clone()
909            .push(Token::COMMA)
910            .append(cte.cte_definition());
911        QueryBuilder {
912            sql,
913            schema: PhantomData,
914            state: PhantomData,
915            table: PhantomData,
916            marker: PhantomData,
917            row: PhantomData,
918            grouped: PhantomData,
919        }
920    }
921}
922
923impl<'a, Schema> QueryBuilder<'a, Schema, BuilderInit> {
924    /// Starts an `INSERT INTO table`. Continue with `.values(...)` or `.select(...)`.
925    ///
926    /// # Examples
927    ///
928    /// ```rust
929    /// # extern crate self as drizzle;
930    /// # mod _drizzle {
931    /// #     pub mod core { pub use drizzle_core::*; }
932    /// #     pub mod error { pub use drizzle_core::error::*; }
933    /// #     pub mod types { pub use drizzle_types::*; }
934    /// #     pub mod migrations { pub use drizzle_migrations::*; }
935    /// #     pub use drizzle_types::Dialect;
936    /// #     pub use drizzle_types as ddl;
937    /// #     pub mod postgres {
938    /// #         pub mod values { pub use drizzle_postgres::values::*; }
939    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
940    /// #         pub mod common { pub use drizzle_postgres::common::*; }
941    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
942    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
943    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
944    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
945    /// #         pub mod types { pub use drizzle_postgres::types::*; }
946    /// #         #[cfg(feature = "aws-data-api")]
947    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
948    /// #         pub struct Row;
949    /// #         impl Row {
950    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
951    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
952    /// #             pub fn len(&self) -> usize { unimplemented!() }
953    /// #         }
954    /// #         pub mod prelude {
955    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
956    /// #             pub use drizzle_postgres::attrs::*;
957    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
958    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
959    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
960    /// #             pub use drizzle_core::*;
961    /// #         }
962    /// #     }
963    /// # }
964    /// # pub use _drizzle::*;
965    /// # pub use const_format;
966    /// # fn main() {
967    /// # use drizzle::postgres::prelude::*;
968    /// # use drizzle::postgres::builder::QueryBuilder;
969    /// # #[PostgresTable(name = "users")]
970    /// # struct User {
971    /// #     #[column(serial, primary)]
972    /// #     id: i32,
973    /// #     name: String,
974    /// #     email: Option<String>,
975    /// # }
976    /// # #[PostgresTable(name = "posts")]
977    /// # struct Post {
978    /// #     #[column(serial, primary)]
979    /// #     id: i32,
980    /// #     #[column(references = User::id)]
981    /// #     author_id: i32,
982    /// #     title: String,
983    /// # }
984    /// # #[derive(PostgresSchema)]
985    /// # struct Schema {
986    /// #     user: User,
987    /// #     post: Post,
988    /// # }
989    /// # let db = QueryBuilder::new::<Schema>();
990    /// # let Schema { user, post } = Schema::new();
991    /// let query = db.insert(user).values([InsertUser::new("Alice")]);
992    /// assert_eq!(query.to_sql().sql(), r#"INSERT INTO "users" ("name") VALUES ($1)"#);
993    /// # }
994    /// ```
995    pub fn insert<Table>(
996        &self,
997        table: Table,
998    ) -> insert::InsertBuilder<'a, Schema, insert::InsertInitial, Table>
999    where
1000        Table: PostgresTable<'a>,
1001    {
1002        let sql = crate::helpers::insert::<Table>(&table);
1003
1004        insert::InsertBuilder {
1005            sql,
1006            schema: PhantomData,
1007            state: PhantomData,
1008            table: PhantomData,
1009            marker: PhantomData,
1010            row: PhantomData,
1011            grouped: PhantomData,
1012        }
1013    }
1014
1015    /// Starts an `UPDATE table`. Continue with `.set(...)`.
1016    ///
1017    /// # Examples
1018    ///
1019    /// ```rust
1020    /// # extern crate self as drizzle;
1021    /// # mod _drizzle {
1022    /// #     pub mod core { pub use drizzle_core::*; }
1023    /// #     pub mod error { pub use drizzle_core::error::*; }
1024    /// #     pub mod types { pub use drizzle_types::*; }
1025    /// #     pub mod migrations { pub use drizzle_migrations::*; }
1026    /// #     pub use drizzle_types::Dialect;
1027    /// #     pub use drizzle_types as ddl;
1028    /// #     pub mod postgres {
1029    /// #         pub mod values { pub use drizzle_postgres::values::*; }
1030    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
1031    /// #         pub mod common { pub use drizzle_postgres::common::*; }
1032    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
1033    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
1034    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
1035    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
1036    /// #         pub mod types { pub use drizzle_postgres::types::*; }
1037    /// #         #[cfg(feature = "aws-data-api")]
1038    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
1039    /// #         pub struct Row;
1040    /// #         impl Row {
1041    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
1042    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
1043    /// #             pub fn len(&self) -> usize { unimplemented!() }
1044    /// #         }
1045    /// #         pub mod prelude {
1046    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
1047    /// #             pub use drizzle_postgres::attrs::*;
1048    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
1049    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
1050    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
1051    /// #             pub use drizzle_core::*;
1052    /// #         }
1053    /// #     }
1054    /// # }
1055    /// # pub use _drizzle::*;
1056    /// # pub use const_format;
1057    /// # fn main() {
1058    /// # use drizzle::postgres::prelude::*;
1059    /// # use drizzle::postgres::builder::QueryBuilder;
1060    /// # #[PostgresTable(name = "users")]
1061    /// # struct User {
1062    /// #     #[column(serial, primary)]
1063    /// #     id: i32,
1064    /// #     name: String,
1065    /// #     email: Option<String>,
1066    /// # }
1067    /// # #[PostgresTable(name = "posts")]
1068    /// # struct Post {
1069    /// #     #[column(serial, primary)]
1070    /// #     id: i32,
1071    /// #     #[column(references = User::id)]
1072    /// #     author_id: i32,
1073    /// #     title: String,
1074    /// # }
1075    /// # #[derive(PostgresSchema)]
1076    /// # struct Schema {
1077    /// #     user: User,
1078    /// #     post: Post,
1079    /// # }
1080    /// # let db = QueryBuilder::new::<Schema>();
1081    /// # let Schema { user, post } = Schema::new();
1082    /// use drizzle::core::expr::eq;
1083    ///
1084    /// let query = db
1085    ///     .update(user)
1086    ///     .set(UpdateUser::default().with_name("Bob"))
1087    ///     .r#where(eq(user.id, 1));
1088    /// assert_eq!(
1089    ///     query.to_sql().sql(),
1090    ///     r#"UPDATE "users" SET "name" = $1 WHERE "users"."id" = $2"#
1091    /// );
1092    /// # }
1093    /// ```
1094    pub fn update<Table>(
1095        &self,
1096        table: Table,
1097    ) -> update::UpdateBuilder<'a, Schema, update::UpdateInitial, Table>
1098    where
1099        Table: PostgresTable<'a>,
1100    {
1101        let sql = crate::helpers::update::<Table, PostgresSchemaType, PostgresValue<'a>>(&table);
1102
1103        update::UpdateBuilder {
1104            sql,
1105            schema: PhantomData,
1106            state: PhantomData,
1107            table: PhantomData,
1108            marker: PhantomData,
1109            row: PhantomData,
1110            grouped: PhantomData,
1111        }
1112    }
1113
1114    /// Starts a `DELETE FROM table`.
1115    ///
1116    /// Without `.where(...)` the statement deletes every row.
1117    ///
1118    /// # Examples
1119    ///
1120    /// ```rust
1121    /// # extern crate self as drizzle;
1122    /// # mod _drizzle {
1123    /// #     pub mod core { pub use drizzle_core::*; }
1124    /// #     pub mod error { pub use drizzle_core::error::*; }
1125    /// #     pub mod types { pub use drizzle_types::*; }
1126    /// #     pub mod migrations { pub use drizzle_migrations::*; }
1127    /// #     pub use drizzle_types::Dialect;
1128    /// #     pub use drizzle_types as ddl;
1129    /// #     pub mod postgres {
1130    /// #         pub mod values { pub use drizzle_postgres::values::*; }
1131    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
1132    /// #         pub mod common { pub use drizzle_postgres::common::*; }
1133    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
1134    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
1135    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
1136    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
1137    /// #         pub mod types { pub use drizzle_postgres::types::*; }
1138    /// #         #[cfg(feature = "aws-data-api")]
1139    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
1140    /// #         pub struct Row;
1141    /// #         impl Row {
1142    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
1143    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
1144    /// #             pub fn len(&self) -> usize { unimplemented!() }
1145    /// #         }
1146    /// #         pub mod prelude {
1147    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
1148    /// #             pub use drizzle_postgres::attrs::*;
1149    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
1150    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
1151    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
1152    /// #             pub use drizzle_core::*;
1153    /// #         }
1154    /// #     }
1155    /// # }
1156    /// # pub use _drizzle::*;
1157    /// # pub use const_format;
1158    /// # fn main() {
1159    /// # use drizzle::postgres::prelude::*;
1160    /// # use drizzle::postgres::builder::QueryBuilder;
1161    /// # #[PostgresTable(name = "users")]
1162    /// # struct User {
1163    /// #     #[column(serial, primary)]
1164    /// #     id: i32,
1165    /// #     name: String,
1166    /// #     email: Option<String>,
1167    /// # }
1168    /// # #[PostgresTable(name = "posts")]
1169    /// # struct Post {
1170    /// #     #[column(serial, primary)]
1171    /// #     id: i32,
1172    /// #     #[column(references = User::id)]
1173    /// #     author_id: i32,
1174    /// #     title: String,
1175    /// # }
1176    /// # #[derive(PostgresSchema)]
1177    /// # struct Schema {
1178    /// #     user: User,
1179    /// #     post: Post,
1180    /// # }
1181    /// # let db = QueryBuilder::new::<Schema>();
1182    /// # let Schema { user, post } = Schema::new();
1183    /// use drizzle::core::expr::gt;
1184    ///
1185    /// let query = db.delete(user).r#where(gt(user.id, 10));
1186    /// assert_eq!(query.to_sql().sql(), r#"DELETE FROM "users" WHERE "users"."id" > $1"#);
1187    /// # }
1188    /// ```
1189    pub fn delete<Table>(
1190        &self,
1191        table: Table,
1192    ) -> delete::DeleteBuilder<'a, Schema, delete::DeleteInitial, Table>
1193    where
1194        Table: PostgresTable<'a>,
1195    {
1196        let sql = crate::helpers::delete::<Table, PostgresSchemaType, PostgresValue<'a>>(&table);
1197
1198        delete::DeleteBuilder {
1199            sql,
1200            schema: PhantomData,
1201            state: PhantomData,
1202            table: PhantomData,
1203            marker: PhantomData,
1204            row: PhantomData,
1205            grouped: PhantomData,
1206        }
1207    }
1208
1209    /// Starts a `WITH` clause from a common table expression (CTE).
1210    ///
1211    /// Build the CTE with `SelectBuilder::into_cte::<Tag>()`, then reference
1212    /// it in the main statement through its `.table` field. Chain more
1213    /// `.with(...)` calls to add more CTEs.
1214    ///
1215    /// # Examples
1216    ///
1217    /// ```rust
1218    /// # extern crate self as drizzle;
1219    /// # mod _drizzle {
1220    /// #     pub mod core { pub use drizzle_core::*; }
1221    /// #     pub mod error { pub use drizzle_core::error::*; }
1222    /// #     pub mod types { pub use drizzle_types::*; }
1223    /// #     pub mod migrations { pub use drizzle_migrations::*; }
1224    /// #     pub use drizzle_types::Dialect;
1225    /// #     pub use drizzle_types as ddl;
1226    /// #     pub mod postgres {
1227    /// #         pub mod values { pub use drizzle_postgres::values::*; }
1228    /// #         pub mod traits { pub use drizzle_postgres::traits::*; }
1229    /// #         pub mod common { pub use drizzle_postgres::common::*; }
1230    /// #         pub mod attrs { pub use drizzle_postgres::attrs::*; }
1231    /// #         pub mod builder { pub use drizzle_postgres::builder::*; }
1232    /// #         pub mod helpers { pub use drizzle_postgres::helpers::*; }
1233    /// #         pub mod expr { pub use drizzle_postgres::expr::*; }
1234    /// #         pub mod types { pub use drizzle_postgres::types::*; }
1235    /// #         #[cfg(feature = "aws-data-api")]
1236    /// #         pub mod aws_data_api { pub use drizzle_postgres::aws_data_api::*; }
1237    /// #         pub struct Row;
1238    /// #         impl Row {
1239    /// #             pub fn get<'a, I, T>(&'a self, _: I) -> T { unimplemented!() }
1240    /// #             pub fn try_get<'a, I, T>(&'a self, _: I) -> Result<T, Box<dyn std::error::Error + Sync + Send>> { unimplemented!() }
1241    /// #             pub fn len(&self) -> usize { unimplemented!() }
1242    /// #         }
1243    /// #         pub mod prelude {
1244    /// #             pub use drizzle_macros::{PostgresTable, PostgresSchema, PostgresIndex};
1245    /// #             pub use drizzle_postgres::attrs::*;
1246    /// #             pub use drizzle_postgres::common::PostgresSchemaType;
1247    /// #             pub use drizzle_postgres::traits::{PostgresColumn, PostgresTable};
1248    /// #             pub use drizzle_postgres::values::{PostgresInsertValue, PostgresUpdateValue, PostgresValue};
1249    /// #             pub use drizzle_core::*;
1250    /// #         }
1251    /// #     }
1252    /// # }
1253    /// # pub use _drizzle::*;
1254    /// # pub use const_format;
1255    /// # fn main() {
1256    /// # use drizzle::postgres::prelude::*;
1257    /// # use drizzle::postgres::builder::QueryBuilder;
1258    /// # #[PostgresTable(name = "users")]
1259    /// # struct User {
1260    /// #     #[column(serial, primary)]
1261    /// #     id: i32,
1262    /// #     name: String,
1263    /// #     email: Option<String>,
1264    /// # }
1265    /// # #[PostgresTable(name = "posts")]
1266    /// # struct Post {
1267    /// #     #[column(serial, primary)]
1268    /// #     id: i32,
1269    /// #     #[column(references = User::id)]
1270    /// #     author_id: i32,
1271    /// #     title: String,
1272    /// # }
1273    /// # #[derive(PostgresSchema)]
1274    /// # struct Schema {
1275    /// #     user: User,
1276    /// #     post: Post,
1277    /// # }
1278    /// # let db = QueryBuilder::new::<Schema>();
1279    /// # let Schema { user, post } = Schema::new();
1280    /// use drizzle::core::expr::gt;
1281    ///
1282    /// struct Recent;
1283    /// impl drizzle::core::Tag for Recent {
1284    ///     const NAME: &'static str = "recent";
1285    /// }
1286    ///
1287    /// let recent = db
1288    ///     .select((user.id, user.name))
1289    ///     .from(user)
1290    ///     .r#where(gt(user.id, 100))
1291    ///     .into_cte::<Recent>();
1292    /// let r = recent.table;
1293    ///
1294    /// let query = db.with(&recent).select(r.name).from(&recent);
1295    /// assert_eq!(
1296    ///     query.to_sql().sql(),
1297    ///     r#"WITH "recent" AS (SELECT "users"."id", "users"."name" FROM "users" WHERE "users"."id" > $1) SELECT "recent"."name" FROM "recent""#
1298    /// );
1299    /// # }
1300    /// ```
1301    pub fn with<C>(&self, cte: &C) -> QueryBuilder<'a, Schema, CTEInit>
1302    where
1303        C: CTEDefinition<'a>,
1304    {
1305        let sql = SQL::from(Token::WITH).append(cte.cte_definition());
1306        QueryBuilder {
1307            sql,
1308            schema: PhantomData,
1309            state: PhantomData,
1310            table: PhantomData,
1311            marker: PhantomData,
1312            row: PhantomData,
1313            grouped: PhantomData,
1314        }
1315    }
1316}
1317
1318#[cfg(test)]
1319mod tests {
1320    use super::*;
1321
1322    #[test]
1323    fn test_query_builder_new() {
1324        let qb = QueryBuilder::new::<()>();
1325        let sql = qb.to_sql();
1326        assert_eq!(sql.sql(), "");
1327        assert_eq!(sql.params().count(), 0);
1328    }
1329
1330    #[test]
1331    fn test_builder_init_type() {
1332        let _state = BuilderInit;
1333    }
1334}