Skip to main content

diesel/pg/query_builder/
mod.rs

1use super::backend::Pg;
2use crate::query_builder::QueryBuilder;
3use crate::result::QueryResult;
4
5mod batch_update;
6pub(crate) mod copy;
7mod distinct_on;
8mod limit_offset;
9pub(crate) mod on_constraint;
10pub(crate) mod only;
11mod query_fragment_impls;
12pub(crate) mod tablesample;
13pub use self::copy::{CopyFormat, CopyFromQuery, CopyHeader, CopyTarget, CopyToQuery};
14pub use self::distinct_on::DistinctOnClause;
15pub use self::distinct_on::OrderDecorator;
16
17/// The PostgreSQL query builder
18#[allow(missing_debug_implementations)]
19#[derive(#[automatically_derived]
#[allow(missing_debug_implementations)]
impl ::core::default::Default for PgQueryBuilder {
    #[inline]
    fn default() -> PgQueryBuilder {
        PgQueryBuilder {
            sql: ::core::default::Default::default(),
            bind_idx: ::core::default::Default::default(),
        }
    }
}Default)]
20#[cfg(feature = "postgres_backend")]
21pub struct PgQueryBuilder {
22    sql: String,
23    bind_idx: u32,
24}
25
26impl PgQueryBuilder {
27    /// Constructs a new query builder with an empty query
28    pub fn new() -> Self {
29        PgQueryBuilder::default()
30    }
31}
32
33impl QueryBuilder<Pg> for PgQueryBuilder {
34    fn push_sql(&mut self, sql: &str) {
35        self.sql.push_str(sql);
36    }
37
38    fn push_identifier(&mut self, identifier: &str) -> QueryResult<()> {
39        self.push_sql("\"");
40        self.push_sql(&identifier.replace('"', "\"\""));
41        self.push_sql("\"");
42        Ok(())
43    }
44
45    fn push_bind_param(&mut self) {
46        self.push_bind_param_value_only();
47        self.sql += "$";
48        let mut buffer = itoa::Buffer::new();
49        self.sql += buffer.format(self.bind_idx);
50    }
51
52    fn push_bind_param_value_only(&mut self) {
53        self.bind_idx += 1;
54    }
55
56    fn finish(self) -> String {
57        self.sql
58    }
59}
60
61#[cfg(test)]
62#[diesel_test_helper::test]
63fn check_sql_query_increments_bind_count() {
64    use crate::query_builder::{AstPass, AstPassToSqlOptions, QueryFragment};
65    use crate::sql_types::*;
66
67    let query = crate::sql_query("SELECT $1, $2, $3")
68        .bind::<Integer, _>(42)
69        .bind::<Integer, _>(3)
70        .bind::<Integer, _>(342);
71
72    let mut query_builder = PgQueryBuilder::default();
73
74    {
75        let mut options = AstPassToSqlOptions::default();
76        let ast_pass = AstPass::<crate::pg::Pg>::to_sql(&mut query_builder, &mut options, &Pg);
77
78        query.walk_ast(ast_pass).unwrap();
79    }
80
81    assert_eq!(query_builder.bind_idx, 3);
82    assert_eq!(query_builder.sql, "SELECT $1, $2, $3");
83}