Skip to main content

diesel/query_builder/
functions.rs

1use super::delete_statement::DeleteStatement;
2use super::distinct_clause::NoDistinctClause;
3use super::insert_statement::{Insert, InsertOrIgnore, Replace};
4use super::select_clause::SelectClause;
5use super::{
6    AsQuery, IncompleteInsertOrIgnoreStatement, IncompleteInsertStatement,
7    IncompleteReplaceStatement, IntoUpdateTarget, SelectStatement, SqlQuery, UpdateStatement,
8};
9use crate::Table;
10use crate::expression::Expression;
11use alloc::string::String;
12
13/// Creates an `UPDATE` statement.
14///
15/// When a table is passed to `update`, every row in the table will be updated.
16/// You can narrow this scope by calling [`filter`] on the table before passing it in,
17/// which will result in `UPDATE your_table SET ... WHERE args_to_filter`.
18///
19/// Passing a type which implements `Identifiable` is the same as passing
20/// `some_table.find(some_struct.id())`.
21///
22/// [`filter`]: crate::query_builder::UpdateStatement::filter()
23///
24/// # Examples
25///
26/// ```rust
27/// # include!("../doctest_setup.rs");
28/// #
29/// # #[cfg(feature = "postgres")]
30/// # fn main() {
31/// #     use schema::users::dsl::*;
32/// #     let connection = &mut establish_connection();
33/// let updated_row = diesel::update(users.filter(id.eq(1)))
34///     .set(name.eq("James"))
35///     .get_result(connection);
36/// // On backends that support it, you can call `get_result` instead of `execute`
37/// // to have `RETURNING *` automatically appended to the query. Alternatively, you
38/// // can explicitly return an expression by using the `returning` method before
39/// // getting the result.
40/// assert_eq!(Ok((1, "James".to_string())), updated_row);
41/// # }
42/// # #[cfg(not(feature = "postgres"))]
43/// # fn main() {}
44/// ```
45///
46/// To update multiple columns, give [`set`] a tuple argument:
47///
48/// [`set`]: crate::query_builder::UpdateStatement::set()
49///
50/// ```rust
51/// # include!("../doctest_setup.rs");
52/// #
53/// # table! {
54/// #     users {
55/// #         id -> Integer,
56/// #         name -> VarChar,
57/// #         surname -> VarChar,
58/// #     }
59/// # }
60/// #
61/// # #[cfg(feature = "postgres")]
62/// # fn main() {
63/// # use self::users::dsl::*;
64/// # let connection = &mut establish_connection();
65/// # diesel::sql_query("DROP TABLE users").execute(connection).unwrap();
66/// # diesel::sql_query("CREATE TABLE users (
67/// #     id SERIAL PRIMARY KEY,
68/// #     name VARCHAR,
69/// #     surname VARCHAR)").execute(connection).unwrap();
70/// # diesel::sql_query("INSERT INTO users(name, surname) VALUES('Sage', 'Griffin')").execute(connection).unwrap();
71///
72/// let updated_row = diesel::update(users.filter(id.eq(1)))
73///     .set((name.eq("James"), surname.eq("Bond")))
74///     .get_result(connection);
75///
76/// assert_eq!(Ok((1, "James".to_string(), "Bond".to_string())), updated_row);
77/// # }
78/// # #[cfg(not(feature = "postgres"))]
79/// # fn main() {}
80/// ```
81///
82/// <br/>
83///
84/// # Batch Update
85///
86/// To update a batch of rows, provide [`set`] a slice or a reference to a vector
87/// as an argument. You cannot call [`filter`], since a special `WHERE` clause
88/// will be auto-generated instead. The `WHERE` clause will use the PRIMARY KEY
89/// as an identifier to apply the changes. The update struct requires both derive
90/// macros [`AsChangeset`] and [`Identifiable`].
91///
92/// [`AsChangeset`]: crate::diesel_derives::AsChangeset
93/// [`Identifiable`]: crate::diesel_derives::Identifiable
94///
95/// Batch update using `id` as the PRIMARY KEY:
96///
97/// ```rust
98/// # include!("../doctest_setup.rs");
99/// table! {
100///     users {
101///         id -> Integer,
102///         name -> VarChar,
103///         surname -> VarChar,
104///     }
105/// }
106/// # #[cfg(feature = "postgres")]
107/// # fn main() {
108/// # let connection = &mut establish_connection();
109/// # diesel::sql_query("DROP TABLE users").execute(connection).unwrap();
110/// # diesel::sql_query("CREATE TABLE users (
111/// #     id SERIAL PRIMARY KEY,
112/// #     name VARCHAR,
113/// #     surname VARCHAR)").execute(connection).unwrap();
114/// # diesel::sql_query(
115/// #     "INSERT INTO users(name, surname) VALUES
116/// #      ('Sage', 'Griffin'), ('Jim', 'Brown'), ('Tom', 'Smith'),
117/// #      ('Lea', 'Kemp'), ('Malik', 'Wu'), ('Xavier', 'Giles')"
118/// # ).execute(connection).unwrap();
119///
120/// #[derive(Debug, Clone, AsChangeset, Identifiable)]
121/// struct User {
122///     id: i32,
123///     name: String,
124///     surname: String,
125/// }
126///
127/// let users_batch = [
128///    User { id: 1, name: "James".to_string(), surname: "Bond".to_string() },
129///    User { id: 6, name: "Mev".to_string(), surname: "Sane".to_string() },
130///    User { id: 3, name: "Kody".to_string(), surname: "Pineda".to_string() },
131///    // Previous update of `id = 6` will be overwritten in the database.
132///    User { id: 6, name: "Mev2".to_string(), surname: "Sane2".to_string() },
133/// ];
134///
135/// diesel::update(users::table).set(&users_batch).execute(connection).unwrap();
136///
137/// let updated_rows = users::table.order(users::id).load(connection);
138///
139/// assert_eq!(
140///     Ok(vec![
141///         (1, "James".to_string(), "Bond".to_string()), // updated
142///         (2, "Jim".to_string(), "Brown".to_string()),
143///         (3, "Kody".to_string(), "Pineda".to_string()), // updated
144///         (4, "Lea".to_string(), "Kemp".to_string()),
145///         (5, "Malik".to_string(), "Wu".to_string()),
146///         (6, "Mev2".to_string(), "Sane2".to_string()) // updated
147///     ]),
148///     updated_rows
149/// );
150/// # }
151/// # #[cfg(not(feature = "postgres"))]
152/// # fn main() {}
153/// ```
154///
155/// Batch update using `(id, name)` as the grouped PRIMARY KEY:
156///
157/// ```rust
158/// # include!("../doctest_setup.rs");
159/// table! {
160///     users (id, name) { // define grouped primary key
161///         id -> Integer,
162///         name -> VarChar,
163///         surname -> VarChar,
164///     }
165/// }
166/// # #[cfg(feature = "postgres")]
167/// # fn main() {
168/// # let connection = &mut establish_connection();
169/// # diesel::sql_query("DROP TABLE users").execute(connection).unwrap();
170/// # diesel::sql_query("CREATE TABLE users (
171/// #     id SERIAL PRIMARY KEY,
172/// #     name VARCHAR,
173/// #     surname VARCHAR)").execute(connection).unwrap();
174/// # diesel::sql_query(
175/// #     "INSERT INTO users(name, surname) VALUES
176/// #      ('Sage', 'Griffin'), ('Jim', 'Brown'), ('Tom', 'Smith'),
177/// #      ('Lea', 'Kemp'), ('Malik', 'Wu'), ('Xavier', 'Giles')"
178/// # ).execute(connection).unwrap();
179///
180/// #[derive(Debug, Clone, AsChangeset, Identifiable)]
181/// #[diesel(primary_key(id, name))] // mandatory: provide grouped primary key
182/// struct User {
183///     id: i32,
184///     name: String,
185///     surname: String,
186/// }
187///
188/// let users_batch = vec![
189///     User { id: 1, name: "J".to_string(), surname: "Bond".to_string() },
190///     User { id: 3, name: "K".to_string(), surname: "Pineda".to_string() },
191///     User { id: 6, name: "Xavier".to_string(), surname: "Mev".to_string() }
192/// ];
193///
194/// diesel::update(users::table).set(&users_batch).execute(connection).unwrap();
195///
196/// let updated_rows = users::table.order(users::id).load(connection);
197///
198/// assert_eq!(
199///     Ok(vec![
200///         (1, "Sage".to_string(), "Griffin".to_string()), // not updated
201///         (2, "Jim".to_string(), "Brown".to_string()),
202///         (3, "Tom".to_string(), "Smith".to_string()), // not updated
203///         (4, "Lea".to_string(), "Kemp".to_string()),
204///         (5, "Malik".to_string(), "Wu".to_string()),
205///         (6, "Xavier".to_string(), "Mev".to_string()) // updated
206///     ]),
207///     updated_rows
208/// );
209/// # }
210/// # #[cfg(not(feature = "postgres"))]
211/// # fn main() {}
212/// ```
213pub fn update<T: IntoUpdateTarget>(source: T) -> UpdateStatement<T::Table, T::WhereClause> {
214    UpdateStatement::new(source.into_update_target())
215}
216
217/// Creates a `DELETE` statement.
218///
219/// When a table is passed to `delete`,
220/// every row in the table will be deleted.
221/// This scope can be narrowed by calling [`filter`]
222/// on the table before it is passed in.
223///
224/// [`filter`]: crate::query_builder::DeleteStatement::filter()
225///
226/// # Examples
227///
228/// ### Deleting a single record:
229///
230/// ```rust
231/// # include!("../doctest_setup.rs");
232/// #
233/// # fn main() {
234/// #     delete();
235/// # }
236/// #
237/// #
238/// # fn delete() -> QueryResult<()> {
239/// #     use schema::users::dsl::*;
240/// #     let connection = &mut establish_connection();
241/// let old_count = users.count().first::<i64>(connection);
242/// diesel::delete(users.filter(id.eq(1))).execute(connection)?;
243/// assert_eq!(
244///     old_count.map(|count| count - 1),
245///     users.count().first(connection)
246/// );
247/// # Ok(())
248/// # }
249/// ```
250///
251/// ### Deleting a whole table:
252///
253/// ```rust
254/// # include!("../doctest_setup.rs");
255/// #
256/// # fn main() {
257/// #     delete();
258/// # }
259/// #
260/// # fn delete() -> QueryResult<()> {
261/// #     use schema::users::dsl::*;
262/// #     let connection = &mut establish_connection();
263/// diesel::delete(users).execute(connection)?;
264/// assert_eq!(Ok(0), users.count().first::<i64>(connection));
265/// # Ok(())
266/// # }
267/// ```
268pub fn delete<T: IntoUpdateTarget>(source: T) -> DeleteStatement<T::Table, T::WhereClause> {
269    let target = source.into_update_target();
270    DeleteStatement::new(target.table, target.where_clause)
271}
272
273/// Creates an `INSERT` statement for the target table.
274///
275/// You may add data by calling [`values()`] or [`default_values()`]
276/// as shown in the examples.
277///
278/// [`values()`]: crate::query_builder::IncompleteInsertStatement::values()
279/// [`default_values()`]: crate::query_builder::IncompleteInsertStatement::default_values()
280///
281/// Backends that support the `RETURNING` clause, such as PostgreSQL,
282/// can return the inserted rows by calling [`.get_results`] instead of [`.execute`].
283///
284/// [`.get_results`]: crate::query_dsl::RunQueryDsl::get_results()
285/// [`.execute`]: crate::query_dsl::RunQueryDsl::execute
286///
287/// # Examples
288///
289/// ```rust
290/// # include!("../doctest_setup.rs");
291/// #
292/// # fn main() {
293/// #     use schema::users::dsl::*;
294/// #     let connection = &mut establish_connection();
295/// let rows_inserted = diesel::insert_into(users)
296///     .values(&name.eq("Sean"))
297///     .execute(connection);
298///
299/// assert_eq!(Ok(1), rows_inserted);
300///
301/// let new_users = vec![name.eq("Tess"), name.eq("Jim")];
302///
303/// let rows_inserted = diesel::insert_into(users)
304///     .values(&new_users)
305///     .execute(connection);
306///
307/// assert_eq!(Ok(2), rows_inserted);
308/// # }
309/// ```
310///
311/// ### Using a tuple for values
312///
313/// ```rust
314/// # include!("../doctest_setup.rs");
315/// #
316/// # fn main() {
317/// #     use schema::users::dsl::*;
318/// #     let connection = &mut establish_connection();
319/// #     diesel::delete(users).execute(connection).unwrap();
320/// let new_user = (id.eq(1), name.eq("Sean"));
321/// let rows_inserted = diesel::insert_into(users)
322///     .values(&new_user)
323///     .execute(connection);
324///
325/// assert_eq!(Ok(1), rows_inserted);
326///
327/// let new_users = vec![(id.eq(2), name.eq("Tess")), (id.eq(3), name.eq("Jim"))];
328///
329/// let rows_inserted = diesel::insert_into(users)
330///     .values(&new_users)
331///     .execute(connection);
332///
333/// assert_eq!(Ok(2), rows_inserted);
334/// # }
335/// ```
336///
337/// ### Using struct for values
338///
339/// ```rust
340/// # include!("../doctest_setup.rs");
341/// # use schema::users;
342/// #
343/// #[derive(Insertable)]
344/// #[diesel(table_name = users)]
345/// struct NewUser<'a> {
346///     name: &'a str,
347/// }
348///
349/// # fn main() {
350/// #     use schema::users::dsl::*;
351/// #     let connection = &mut establish_connection();
352/// // Insert one record at a time
353///
354/// let new_user = NewUser { name: "Ruby Rhod" };
355///
356/// diesel::insert_into(users)
357///     .values(&new_user)
358///     .execute(connection)
359///     .unwrap();
360///
361/// // Insert many records
362///
363/// let new_users = vec![
364///     NewUser {
365///         name: "Leeloo Multipass",
366///     },
367///     NewUser {
368///         name: "Korben Dallas",
369///     },
370/// ];
371///
372/// let inserted_names = diesel::insert_into(users)
373///     .values(&new_users)
374///     .execute(connection)
375///     .unwrap();
376/// # }
377/// ```
378///
379/// ### Inserting default value for a column
380///
381/// You can use `Option<T>` to allow a column to be set to the default value when needed.
382///
383/// When the field is set to `None`, diesel inserts the default value on supported databases.
384/// When the field is set to `Some(..)`, diesel inserts the given value.
385///
386/// The column `color` in `brands` table is `NOT NULL DEFAULT 'Green'`.
387///
388/// ```rust
389/// # include!("../doctest_setup.rs");
390/// # #[cfg(not(feature = "__sqlite-shared"))]
391/// # use schema::brands;
392/// #
393/// # #[cfg(not(feature = "__sqlite-shared"))]
394/// #[derive(Insertable)]
395/// #[diesel(table_name = brands)]
396/// struct NewBrand {
397///     color: Option<String>,
398/// }
399///
400/// # #[cfg(not(feature = "__sqlite-shared"))]
401/// # fn main() {
402/// #     use schema::brands::dsl::*;
403/// #     let connection = &mut establish_connection();
404/// // Insert `Red`
405/// let new_brand = NewBrand {
406///     color: Some("Red".into()),
407/// };
408///
409/// diesel::insert_into(brands)
410///     .values(&new_brand)
411///     .execute(connection)
412///     .unwrap();
413///
414/// // Insert the default color
415/// let new_brand = NewBrand { color: None };
416///
417/// diesel::insert_into(brands)
418///     .values(&new_brand)
419///     .execute(connection)
420///     .unwrap();
421/// # }
422/// # #[cfg(feature = "__sqlite-shared")]
423/// # fn main() {}
424/// ```
425///
426/// ### Inserting default value for a nullable column
427///
428/// The column `accent` in `brands` table is `DEFAULT 'Green'`. It is a nullable column.
429///
430/// You can use `Option<Option<T>>` in this case.
431///
432/// When the field is set to `None`, diesel inserts the default value on supported databases.
433/// When the field is set to `Some(None)`, diesel inserts `NULL`.
434/// When the field is set to `Some(Some(..))` diesel inserts the given value.
435///
436/// ```rust
437/// # include!("../doctest_setup.rs");
438/// # #[cfg(not(feature = "__sqlite-shared"))]
439/// # use schema::brands;
440/// #
441/// # #[cfg(not(feature = "__sqlite-shared"))]
442/// #[derive(Insertable)]
443/// #[diesel(table_name = brands)]
444/// struct NewBrand {
445///     accent: Option<Option<String>>,
446/// }
447///
448/// # #[cfg(not(feature = "__sqlite-shared"))]
449/// # fn main() {
450/// #     use schema::brands::dsl::*;
451/// #     let connection = &mut establish_connection();
452/// // Insert `Red`
453/// let new_brand = NewBrand {
454///     accent: Some(Some("Red".into())),
455/// };
456///
457/// diesel::insert_into(brands)
458///     .values(&new_brand)
459///     .execute(connection)
460///     .unwrap();
461///
462/// // Insert the default accent
463/// let new_brand = NewBrand { accent: None };
464///
465/// diesel::insert_into(brands)
466///     .values(&new_brand)
467///     .execute(connection)
468///     .unwrap();
469///
470/// // Insert `NULL`
471/// let new_brand = NewBrand { accent: Some(None) };
472///
473/// diesel::insert_into(brands)
474///     .values(&new_brand)
475///     .execute(connection)
476///     .unwrap();
477/// # }
478/// # #[cfg(feature = "__sqlite-shared")]
479/// # fn main() {}
480/// ```
481///
482/// ### Insert from select
483///
484/// When inserting from a select statement,
485/// the column list can be specified with [`.into_columns`].
486/// (See also [`SelectStatement::insert_into`], which generally
487/// reads better for select statements)
488///
489/// [`SelectStatement::insert_into`]: crate::prelude::Insertable::insert_into()
490/// [`.into_columns`]: crate::query_builder::InsertStatement::into_columns()
491///
492/// ```rust
493/// # include!("../doctest_setup.rs");
494/// #
495/// # fn main() {
496/// #     run_test().unwrap();
497/// # }
498/// #
499/// # fn run_test() -> QueryResult<()> {
500/// #     use schema::{posts, users};
501/// #     let conn = &mut establish_connection();
502/// #     diesel::delete(posts::table).execute(conn)?;
503/// let new_posts = users::table.select((users::name.concat("'s First Post"), users::id));
504/// diesel::insert_into(posts::table)
505///     .values(new_posts)
506///     .into_columns((posts::title, posts::user_id))
507///     .execute(conn)?;
508///
509/// let inserted_posts = posts::table.select(posts::title).load::<String>(conn)?;
510/// let expected = vec!["Sean's First Post", "Tess's First Post"];
511/// assert_eq!(expected, inserted_posts);
512/// #     Ok(())
513/// # }
514/// ```
515///
516/// ### With return value
517///
518/// ```rust
519/// # include!("../doctest_setup.rs");
520/// #
521/// # #[cfg(feature = "postgres")]
522/// # fn main() {
523/// #     use schema::users::dsl::*;
524/// #     let connection = &mut establish_connection();
525/// let inserted_names = diesel::insert_into(users)
526///     .values(&vec![
527///         name.eq("Diva Plavalaguna"),
528///         name.eq("Father Vito Cornelius"),
529///     ])
530///     .returning(name)
531///     .get_results(connection);
532/// assert_eq!(
533///     Ok(vec![
534///         "Diva Plavalaguna".to_string(),
535///         "Father Vito Cornelius".to_string()
536///     ]),
537///     inserted_names
538/// );
539/// # }
540/// # #[cfg(not(feature = "postgres"))]
541/// # fn main() {}
542/// ```
543pub fn insert_into<T: Table>(target: T) -> IncompleteInsertStatement<T> {
544    IncompleteInsertStatement::new(target, Insert)
545}
546
547/// Creates an `INSERT [OR] IGNORE` statement.
548///
549/// If a constraint violation fails, the database will ignore the offending
550/// row and continue processing any subsequent rows. This function is only
551/// available with MySQL and SQLite.
552///
553/// With PostgreSQL, similar functionality is provided by [`on_conflict_do_nothing`].
554///
555/// [`on_conflict_do_nothing`]: crate::query_builder::InsertStatement::on_conflict_do_nothing()
556///
557/// # Example
558///
559/// ```rust
560/// # include!("../doctest_setup.rs");
561/// #
562/// # fn main() {
563/// #     run_test().unwrap();
564/// # }
565/// #
566/// # #[cfg(not(feature = "postgres"))]
567/// # fn run_test() -> QueryResult<()> {
568/// #     use schema::users::dsl::*;
569/// #     use diesel::{delete, insert_or_ignore_into};
570/// #
571/// #     let connection = &mut establish_connection();
572/// #     diesel::delete(users).execute(connection)?;
573/// insert_or_ignore_into(users)
574///     .values((id.eq(1), name.eq("Jim")))
575///     .execute(connection)?;
576///
577/// insert_or_ignore_into(users)
578///     .values(&vec![
579///         (id.eq(1), name.eq("Sean")),
580///         (id.eq(2), name.eq("Tess")),
581///     ])
582///     .execute(connection)?;
583///
584/// let names = users.select(name).order(id).load::<String>(connection)?;
585/// assert_eq!(vec![String::from("Jim"), String::from("Tess")], names);
586/// #     Ok(())
587/// # }
588/// #
589/// # #[cfg(feature = "postgres")]
590/// # fn run_test() -> QueryResult<()> {
591/// #     Ok(())
592/// # }
593/// ```
594pub fn insert_or_ignore_into<T: Table>(target: T) -> IncompleteInsertOrIgnoreStatement<T> {
595    IncompleteInsertStatement::new(target, InsertOrIgnore)
596}
597
598/// Creates a bare select statement, with no from clause. Primarily used for
599/// testing diesel itself, but likely useful for third party crates as well. The
600/// given expressions must be selectable from anywhere.
601pub fn select<T>(expression: T) -> crate::dsl::select<T>
602where
603    T: Expression,
604    crate::dsl::select<T>: AsQuery,
605{
606    SelectStatement::new(
607        SelectClause(expression),
608        super::NoFromClause,
609        NoDistinctClause,
610        super::where_clause::NoWhereClause,
611        super::order_clause::NoOrderClause,
612        super::limit_offset_clause::LimitOffsetClause {
613            limit_clause: super::limit_clause::NoLimitClause,
614            offset_clause: super::offset_clause::NoOffsetClause,
615        },
616        super::group_by_clause::NoGroupByClause,
617        super::having_clause::NoHavingClause,
618        super::locking_clause::NoLockingClause,
619    )
620}
621
622/// Creates a `REPLACE` statement.
623///
624/// If a constraint violation fails, the database will attempt to replace the
625/// offending row instead. This function is only available with MySQL and
626/// SQLite.
627///
628/// # Example
629///
630/// ```rust
631/// # include!("../doctest_setup.rs");
632/// #
633/// # #[cfg(not(feature = "postgres"))]
634/// # fn main() {
635/// #     use schema::users::dsl::*;
636/// #     use diesel::{insert_into, replace_into};
637/// #
638/// #     let conn = &mut establish_connection();
639/// #     diesel::sql_query("DELETE FROM users").execute(conn).unwrap();
640/// replace_into(users)
641///     .values(&vec![
642///         (id.eq(1), name.eq("Sean")),
643///         (id.eq(2), name.eq("Tess")),
644///     ])
645///     .execute(conn)
646///     .unwrap();
647///
648/// replace_into(users)
649///     .values((id.eq(1), name.eq("Jim")))
650///     .execute(conn)
651///     .unwrap();
652///
653/// let names = users.select(name).order(id).load::<String>(conn);
654/// assert_eq!(Ok(vec!["Jim".into(), "Tess".into()]), names);
655/// # }
656/// # #[cfg(feature = "postgres")] fn main() {}
657pub fn replace_into<T: Table>(target: T) -> IncompleteReplaceStatement<T> {
658    IncompleteInsertStatement::new(target, Replace)
659}
660
661/// Construct a full SQL query using raw SQL.
662///
663/// This function exists for cases where a query needs to be written that is not
664/// supported by the query builder. Unlike most queries in Diesel, `sql_query`
665/// will deserialize its data by name, not by index. That means that you cannot
666/// deserialize into a tuple, and structs which you deserialize from this
667/// function will need to have `#[derive(QueryableByName)]`.
668///
669/// This function is intended for use when you want to write the entire query
670/// using raw SQL. If you only need a small bit of raw SQL in your query, use
671/// [`sql`](crate::dsl::sql()) instead.
672///
673/// Query parameters can be bound into the raw query using [`SqlQuery::bind()`].
674///
675/// # Safety
676///
677/// The implementation of `QueryableByName` will assume that columns with a
678/// given name will have a certain type. The compiler will be unable to verify
679/// that the given type is correct. If your query returns a column of an
680/// unexpected type, the result may have the wrong value, or return an error.
681///
682/// # Examples
683///
684/// ```rust
685/// # include!("../doctest_setup.rs");
686/// #
687/// # use schema::users;
688/// #
689/// # #[derive(QueryableByName, Debug, PartialEq)]
690/// # struct User {
691/// #     id: i32,
692/// #     name: String,
693/// # }
694/// #
695/// # fn main() {
696/// #     run_test_1().unwrap();
697/// #     run_test_2().unwrap();
698/// # }
699/// #
700/// # fn run_test_1() -> QueryResult<()> {
701/// #     use diesel::sql_query;
702/// #     use diesel::sql_types::{Integer, Text};
703/// #
704/// #     let connection = &mut establish_connection();
705/// let users = sql_query("SELECT * FROM users ORDER BY id").load(connection);
706/// let expected_users = vec![
707///     User {
708///         id: 1,
709///         name: "Sean".into(),
710///     },
711///     User {
712///         id: 2,
713///         name: "Tess".into(),
714///     },
715/// ];
716/// assert_eq!(Ok(expected_users), users);
717/// #     Ok(())
718/// # }
719///
720/// # fn run_test_2() -> QueryResult<()> {
721/// #     use diesel::sql_query;
722/// #     use diesel::sql_types::{Integer, Text};
723/// #
724/// #     let connection = &mut establish_connection();
725/// #     diesel::insert_into(users::table)
726/// #         .values(users::name.eq("Jim"))
727/// #         .execute(connection).unwrap();
728/// #     #[cfg(feature = "postgres")]
729/// #     let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
730/// #     #[cfg(not(feature = "postgres"))]
731/// // Checkout the documentation of your database for the correct
732/// // bind placeholder
733/// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?");
734/// let users = users
735///     .bind::<Integer, _>(1)
736///     .bind::<Text, _>("Tess")
737///     .get_results(connection);
738/// let expected_users = vec![User {
739///     id: 3,
740///     name: "Jim".into(),
741/// }];
742/// assert_eq!(Ok(expected_users), users);
743/// #     Ok(())
744/// # }
745/// ```
746/// [`SqlQuery::bind()`]: crate::query_builder::SqlQuery::bind()
747pub fn sql_query<T: Into<String>>(query: T) -> SqlQuery {
748    SqlQuery::from_sql(query.into())
749}
750
751#[cfg(feature = "postgres_backend")]
752pub use crate::pg::query_builder::copy::copy_from::copy_from;
753#[cfg(feature = "postgres_backend")]
754pub use crate::pg::query_builder::copy::copy_to::copy_to;