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