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