oxedyne/fe2o3/fe2o3_text/tests/annealer_corpus/diesel_query.rs
15.6 KiB, 1 run
created by r1870400018:11728, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | //! Contains traits responsible for the actual construction of SQL statements |
| 2 | //! |
| 3 | //! The types in this module are part of Diesel's public API, but are generally |
| 4 | //! only useful for implementing Diesel plugins. Applications should generally |
| 5 | //! not need to care about the types inside of this module. |
| 6 | |
| 7 | #[macro_use] |
| 8 | mod query_id; |
| 9 | #[macro_use] |
| 10 | mod clause_macro; |
| 11 | |
| 12 | pub(crate) mod ast_pass; |
| 13 | pub mod bind_collector; |
| 14 | mod collected_query; |
| 15 | pub(crate) mod combination_clause; |
| 16 | mod debug_query; |
| 17 | mod delete_statement; |
| 18 | mod distinct_clause; |
| 19 | pub(crate) mod from_clause; |
| 20 | pub(crate) mod functions; |
| 21 | pub(crate) mod group_by_clause; |
| 22 | mod having_clause; |
| 23 | pub(crate) mod insert_statement; |
| 24 | pub(crate) mod limit_clause; |
| 25 | pub(crate) mod limit_offset_clause; |
| 26 | pub(crate) mod locking_clause; |
| 27 | pub(crate) mod nodes; |
| 28 | pub(crate) mod offset_clause; |
| 29 | pub(crate) mod order_clause; |
| 30 | pub(crate) mod returning_clause; |
| 31 | pub(crate) mod select_clause; |
| 32 | pub(crate) mod select_statement; |
| 33 | mod sql_query; |
| 34 | pub(crate) mod update_statement; |
| 35 | pub(crate) mod upsert; |
| 36 | pub(crate) mod where_clause; |
| 37 | |
| 38 | #[doc(inline)] |
| 39 | pub use self::ast_pass::AstPass; |
| 40 | #[doc(inline)] |
| 41 | pub use self::bind_collector::{BindCollector, MoveableBindCollector}; |
| 42 | #[doc(inline)] |
| 43 | pub use self::collected_query::CollectedQuery; |
| 44 | #[doc(inline)] |
| 45 | pub use self::debug_query::DebugQuery; |
| 46 | #[doc(inline)] |
| 47 | pub use self::delete_statement::{BoxedDeleteStatement, DeleteStatement}; |
| 48 | #[doc(inline)] |
| 49 | pub use self::insert_statement::{ |
| 50 | IncompleteInsertOrIgnoreStatement, IncompleteInsertStatement, IncompleteReplaceStatement, |
| 51 | InsertOrIgnoreStatement, InsertStatement, ReplaceStatement, |
| 52 | }; |
| 53 | #[doc(inline)] |
| 54 | pub use self::query_id::QueryId; |
| 55 | #[doc(inline)] |
| 56 | pub use self::sql_query::{BoxedSqlQuery, SqlQuery}; |
| 57 | #[doc(inline)] |
| 58 | pub use self::upsert::into_conflict_clause::IntoConflictValueClause; |
| 59 | #[doc(inline)] |
| 60 | pub use self::upsert::on_conflict_target::{ConflictTarget, OnConflictTarget}; |
| 61 | #[doc(inline)] |
| 62 | pub use self::upsert::on_conflict_target_decorations::DecoratableTarget; |
| 63 | |
| 64 | #[doc(inline)] |
| 65 | pub use self::update_statement::changeset::AsChangeset; |
| 66 | #[doc(inline)] |
| 67 | pub use self::update_statement::target::{IntoUpdateTarget, UpdateTarget}; |
| 68 | #[doc(inline)] |
| 69 | pub use self::update_statement::{BoxedUpdateStatement, UpdateStatement}; |
| 70 | |
| 71 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 72 | pub use self::combination_clause::{ |
| 73 | All, Distinct, Except, Intersect, ParenthesisWrapper, SupportsCombinationClause, Union, |
| 74 | }; |
| 75 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 76 | pub use self::limit_clause::{LimitClause, NoLimitClause}; |
| 77 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 78 | pub use self::limit_offset_clause::{BoxedLimitOffsetClause, LimitOffsetClause}; |
| 79 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 80 | pub use self::offset_clause::{NoOffsetClause, OffsetClause}; |
| 81 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 82 | pub use self::order_clause::{NoOrderClause, OrderClause}; |
| 83 | |
| 84 | #[diesel_derives::__diesel_public_if( |
| 85 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 86 | )] |
| 87 | #[doc(inline)] |
| 88 | pub(crate) use self::insert_statement::batch_insert::BatchInsert; |
| 89 | #[diesel_derives::__diesel_public_if( |
| 90 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 91 | )] |
| 92 | pub(crate) use self::insert_statement::{UndecoratedInsertRecord, ValuesClause}; |
| 93 | |
| 94 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 95 | #[doc(inline)] |
| 96 | pub use self::insert_statement::{DefaultValues, InsertOrIgnore, Replace}; |
| 97 | |
| 98 | #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")] |
| 99 | #[doc(inline)] |
| 100 | pub use self::returning_clause::ReturningClause; |
| 101 | |
| 102 | #[doc(inline)] |
| 103 | #[diesel_derives::__diesel_public_if( |
| 104 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 105 | )] |
| 106 | pub(crate) use self::ast_pass::AstPassToSqlOptions; |
| 107 | |
| 108 | #[doc(inline)] |
| 109 | #[diesel_derives::__diesel_public_if( |
| 110 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 111 | )] |
| 112 | pub(crate) use self::select_clause::SelectClauseExpression; |
| 113 | |
| 114 | #[doc(inline)] |
| 115 | #[diesel_derives::__diesel_public_if( |
| 116 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 117 | )] |
| 118 | pub(crate) use self::from_clause::{FromClause, NoFromClause}; |
| 119 | #[diesel_derives::__diesel_public_if( |
| 120 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 121 | )] |
| 122 | #[doc(inline)] |
| 123 | pub(crate) use self::select_statement::BoxedSelectStatement; |
| 124 | |
| 125 | #[diesel_derives::__diesel_public_if( |
| 126 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 127 | )] |
| 128 | #[doc(inline)] |
| 129 | pub(crate) use self::select_statement::SelectStatement; |
| 130 | |
| 131 | pub(crate) use self::insert_statement::ColumnList; |
| 132 | |
| 133 | #[cfg(feature = "postgres_backend")] |
| 134 | pub use crate::pg::query_builder::only::Only; |
| 135 | |
| 136 | #[cfg(feature = "postgres_backend")] |
| 137 | pub use crate::pg::query_builder::tablesample::{Tablesample, TablesampleMethod}; |
| 138 | |
| 139 | #[cfg(feature = "postgres_backend")] |
| 140 | pub(crate) use self::bind_collector::ByteWrapper; |
| 141 | use crate::backend::Backend; |
| 142 | use crate::result::QueryResult; |
| 143 | use alloc::boxed::Box; |
| 144 | use alloc::string::String; |
| 145 | use alloc::vec::Vec; |
| 146 | use core::error::Error; |
| 147 | |
| 148 | pub(crate) use self::private::NotSpecialized; |
| 149 | |
| 150 | #[doc(hidden)] |
| 151 | pub type Binds = Vec<Option<Vec<u8>>>; |
| 152 | /// A specialized Result type used with the query builder. |
| 153 | pub type BuildQueryResult = Result<(), Box<dyn Error + Send + Sync>>; |
| 154 | |
| 155 | /// Constructs a SQL query from a Diesel AST. |
| 156 | /// |
| 157 | /// The only reason you should ever need to interact with this trait is if you |
| 158 | /// are extending Diesel with support for a new backend. Plugins which extend |
| 159 | /// the query builder with new capabilities will interact with [`AstPass`] |
| 160 | /// instead. |
| 161 | pub trait QueryBuilder<DB: Backend> { |
| 162 | /// Add `sql` to the end of the query being constructed. |
| 163 | fn push_sql(&mut self, sql: &str); |
| 164 | |
| 165 | /// Quote `identifier`, and add it to the end of the query being |
| 166 | /// constructed. |
| 167 | fn push_identifier(&mut self, identifier: &str) -> QueryResult<()>; |
| 168 | |
| 169 | /// Add a placeholder for a bind parameter to the end of the query being |
| 170 | /// constructed. |
| 171 | fn push_bind_param(&mut self); |
| 172 | |
| 173 | /// Increases the internal counter for bind parameters without adding the |
| 174 | /// bind parameter itself to the query |
| 175 | fn push_bind_param_value_only(&mut self) {} |
| 176 | |
| 177 | /// Returns the constructed SQL query. |
| 178 | fn finish(self) -> String; |
| 179 | } |
| 180 | |
| 181 | /// A complete SQL query with a return type. |
| 182 | /// |
| 183 | /// This can be a select statement, or a command such as `update` or `insert` |
| 184 | /// with a `RETURNING` clause. Unlike [`Expression`], types implementing this |
| 185 | /// trait are guaranteed to be executable on their own. |
| 186 | /// |
| 187 | /// A type which doesn't implement this trait may still represent a complete SQL |
| 188 | /// query. For example, an `INSERT` statement without a `RETURNING` clause will |
| 189 | /// not implement this trait, but can still be executed. |
| 190 | /// |
| 191 | /// [`Expression`]: crate::expression::Expression |
| 192 | pub trait Query { |
| 193 | /// The SQL type that this query represents. |
| 194 | /// |
| 195 | /// This is the SQL type of the `SELECT` clause for select statements, and |
| 196 | /// the SQL type of the `RETURNING` clause for insert, update, or delete |
| 197 | /// statements. |
| 198 | type SqlType; |
| 199 | } |
| 200 | |
| 201 | impl<T: Query> Query for &T { |
| 202 | type SqlType = T::SqlType; |
| 203 | } |
| 204 | |
| 205 | /// Indicates that a type is a `SELECT` statement. |
| 206 | /// |
| 207 | /// This trait differs from `Query` in two ways: |
| 208 | /// - It is implemented only for select statements, rather than all queries |
| 209 | /// which return a value. |
| 210 | /// - It has looser constraints. A type implementing `SelectQuery` is known to |
| 211 | /// be potentially valid if used as a subselect, but it is not necessarily |
| 212 | /// able to be executed. |
| 213 | pub trait SelectQuery { |
| 214 | /// The SQL type of the `SELECT` clause |
| 215 | type SqlType; |
| 216 | } |
| 217 | |
| 218 | /// An untyped fragment of SQL. |
| 219 | /// |
| 220 | /// This may be a complete SQL command (such as an update statement without a |
| 221 | /// `RETURNING` clause), or a subsection (such as our internal types used to |
| 222 | /// represent a `WHERE` clause). Implementations of [`ExecuteDsl`] and |
| 223 | /// [`LoadQuery`] will generally require that this trait be implemented. |
| 224 | /// |
| 225 | /// [`ExecuteDsl`]: crate::query_dsl::methods::ExecuteDsl |
| 226 | /// [`LoadQuery`]: crate::query_dsl::methods::LoadQuery |
| 227 | #[diagnostic::on_unimplemented( |
| 228 | message = "`{Self}` is no valid SQL fragment for the `{DB}` backend", |
| 229 | note = "this usually means that the `{DB}` database system does not support \n\ |
| 230 | this SQL syntax" |
| 231 | )] |
| 232 | pub trait QueryFragment<DB: Backend, SP = self::private::NotSpecialized> { |
| 233 | /// Walk over this `QueryFragment` for all passes. |
| 234 | /// |
| 235 | /// This method is where the actual behavior of an AST node is implemented. |
| 236 | /// This method will contain the behavior required for all possible AST |
| 237 | /// passes. See [`AstPass`] for more details. |
| 238 | fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()>; |
| 239 | |
| 240 | /// Converts this `QueryFragment` to its SQL representation. |
| 241 | /// |
| 242 | /// This method should only be called by implementations of `Connection`. |
| 243 | #[diesel_derives::__diesel_public_if( |
| 244 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 245 | )] |
| 246 | fn to_sql(&self, out: &mut DB::QueryBuilder, backend: &DB) -> QueryResult<()> { |
| 247 | let mut options = AstPassToSqlOptions::default(); |
| 248 | self.walk_ast(AstPass::to_sql(out, &mut options, backend)) |
| 249 | } |
| 250 | |
| 251 | /// Serializes all bind parameters in this query. |
| 252 | /// |
| 253 | /// A bind parameter is a value which is sent separately from the query |
| 254 | /// itself. It is represented in SQL with a placeholder such as `?` or `$1`. |
| 255 | /// |
| 256 | /// This method should only be called by implementations of `Connection`. |
| 257 | #[diesel_derives::__diesel_public_if( |
| 258 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 259 | )] |
| 260 | fn collect_binds<'b>( |
| 261 | &'b self, |
| 262 | out: &mut DB::BindCollector<'b>, |
| 263 | metadata_lookup: &mut DB::MetadataLookup, |
| 264 | backend: &'b DB, |
| 265 | ) -> QueryResult<()> { |
| 266 | self.walk_ast(AstPass::collect_binds(out, metadata_lookup, backend)) |
| 267 | } |
| 268 | |
| 269 | /// Is this query safe to store in the prepared statement cache? |
| 270 | /// |
| 271 | /// In order to keep our prepared statement cache at a reasonable size, we |
| 272 | /// avoid caching any queries which represent a potentially unbounded number |
| 273 | /// of SQL queries. Generally this will only return `true` for queries for |
| 274 | /// which `to_sql` will always construct exactly identical SQL. |
| 275 | /// |
| 276 | /// Some examples of where this method will return `false` are: |
| 277 | /// |
| 278 | /// - `SqlLiteral` (We don't know if the SQL was constructed dynamically, so |
| 279 | /// we must assume that it was) |
| 280 | /// - `In` and `NotIn` (Each value requires a separate bind param |
| 281 | /// placeholder) |
| 282 | /// |
| 283 | /// This method should only be called by implementations of `Connection`. |
| 284 | #[diesel_derives::__diesel_public_if( |
| 285 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 286 | )] |
| 287 | fn is_safe_to_cache_prepared(&self, backend: &DB) -> QueryResult<bool> { |
| 288 | let mut result = true; |
| 289 | self.walk_ast(AstPass::is_safe_to_cache_prepared(&mut result, backend))?; |
| 290 | Ok(result) |
| 291 | } |
| 292 | |
| 293 | /// Does walking this AST have any effect? |
| 294 | #[diesel_derives::__diesel_public_if( |
| 295 | feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes" |
| 296 | )] |
| 297 | fn is_noop(&self, backend: &DB) -> QueryResult<bool> { |
| 298 | let mut result = true; |
| 299 | self.walk_ast(AstPass::is_noop(&mut result, backend))?; |
| 300 | Ok(result) |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | impl<T: ?Sized, DB> QueryFragment<DB> for Box<T> |
| 305 | where |
| 306 | DB: Backend, |
| 307 | T: QueryFragment<DB>, |
| 308 | { |
| 309 | fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> { |
| 310 | QueryFragment::walk_ast(&**self, pass) |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | impl<T: ?Sized, DB> QueryFragment<DB> for &T |
| 315 | where |
| 316 | DB: Backend, |
| 317 | T: QueryFragment<DB>, |
| 318 | { |
| 319 | fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> { |
| 320 | QueryFragment::walk_ast(&**self, pass) |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | impl<DB: Backend> QueryFragment<DB> for () { |
| 325 | fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> { |
| 326 | Ok(()) |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | impl<T, DB> QueryFragment<DB> for Option<T> |
| 331 | where |
| 332 | DB: Backend, |
| 333 | T: QueryFragment<DB>, |
| 334 | { |
| 335 | fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, DB>) -> QueryResult<()> { |
| 336 | match *self { |
| 337 | Some(ref c) => c.walk_ast(out), |
| 338 | None => Ok(()), |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | /// A trait used to construct type erased boxed variant of the current query node |
| 344 | /// |
| 345 | /// Mainly useful for implementing third party backends |
| 346 | #[diagnostic::on_unimplemented( |
| 347 | note = "this usually means that `{Self}` is no valid SQL for `{DB}`" |
| 348 | )] |
| 349 | pub trait IntoBoxedClause<'a, DB> { |
| 350 | /// Resulting type |
| 351 | type BoxedClause; |
| 352 | |
| 353 | /// Convert the given query node in it's boxed representation |
| 354 | fn into_boxed(self) -> Self::BoxedClause; |
| 355 | } |
| 356 | |
| 357 | /// Types that can be converted into a complete, typed SQL query. |
| 358 | /// |
| 359 | /// This is used internally to automatically add the right select clause when |
| 360 | /// none is specified, or to automatically add `RETURNING *` in certain contexts. |
| 361 | /// |
| 362 | /// A type which implements this trait is guaranteed to be valid for execution. |
| 363 | pub trait AsQuery { |
| 364 | /// The SQL type of `Self::Query` |
| 365 | type SqlType; |
| 366 | |
| 367 | /// What kind of query does this type represent? |
| 368 | type Query: Query<SqlType = Self::SqlType>; |
| 369 | |
| 370 | /// Converts a type which semantically represents a SQL query into the |
| 371 | /// actual query being executed. See the trait level docs for more. |
| 372 | // This method is part of our public API, |
| 373 | // so we won't change the name to just appease clippy |
| 374 | // (Also the trait is literally named `AsQuery` so |
| 375 | // naming the method similarity is fine) |
| 376 | #[allow(clippy::wrong_self_convention)] |
| 377 | fn as_query(self) -> Self::Query; |
| 378 | } |
| 379 | |
| 380 | impl<T: Query> AsQuery for T { |
| 381 | type SqlType = <T as Query>::SqlType; |
| 382 | type Query = T; |
| 383 | |
| 384 | fn as_query(self) -> <T as AsQuery>::Query { |
| 385 | self |
| 386 | } |
| 387 | } |
| 388 | |
| 389 | /// Takes a query `QueryFragment` expression as an argument and returns a type |
| 390 | /// that implements `fmt::Display` and `fmt::Debug` to show the query. |
| 391 | /// |
| 392 | /// The `Display` implementation will show the exact query being sent to the |
| 393 | /// server, with a comment showing the values of the bind parameters. The |
| 394 | /// `Debug` implementation will include the same information in a more |
| 395 | /// structured form, and respects pretty printing. |
| 396 | /// |
| 397 | /// # Example |
| 398 | /// |
| 399 | /// ### Returning SQL from a count statement: |
| 400 | /// |
| 401 | /// ```rust |
| 402 | /// # include!("../doctest_setup.rs"); |
| 403 | /// # |
| 404 | /// # use diesel::*; |
| 405 | /// # use schema::*; |
| 406 | /// # |
| 407 | /// # fn main() { |
| 408 | /// # use schema::users::dsl::*; |
| 409 | /// let sql = debug_query::<DB, _>(&users.count()).to_string(); |
| 410 | /// # if cfg!(feature = "postgres") { |
| 411 | /// # assert_eq!(sql, r#"SELECT COUNT(*) FROM "users" -- binds: []"#); |
| 412 | /// # } else { |
| 413 | /// assert_eq!(sql, "SELECT COUNT(*) FROM `users` -- binds: []"); |
| 414 | /// # } |
| 415 | /// |
| 416 | /// let query = users.find(1); |
| 417 | /// let debug = debug_query::<DB, _>(&query); |
| 418 | /// # if cfg!(feature = "postgres") { |
| 419 | /// # assert_eq!(debug.to_string(), "SELECT \"users\".\"id\", \"users\".\"name\" \ |
| 420 | /// # FROM \"users\" WHERE (\"users\".\"id\" = $1) -- binds: [1]"); |
| 421 | /// # } else { |
| 422 | /// assert_eq!( |
| 423 | /// debug.to_string(), |
| 424 | /// "SELECT `users`.`id`, `users`.`name` FROM `users` \ |
| 425 | /// WHERE (`users`.`id` = ?) -- binds: [1]" |
| 426 | /// ); |
| 427 | /// # } |
| 428 | /// |
| 429 | /// let debug = format!("{:?}", debug); |
| 430 | /// # if !cfg!(feature = "postgres") { // Escaping that string is a pain |
| 431 | /// let expected = "Query { \ |
| 432 | /// sql: \"SELECT `users`.`id`, `users`.`name` FROM `users` WHERE \ |
| 433 | /// (`users`.`id` = ?)\", \ |
| 434 | /// binds: [1] \ |
| 435 | /// }"; |
| 436 | /// assert_eq!(debug, expected); |
| 437 | /// # } |
| 438 | /// # } |
| 439 | /// ``` |
| 440 | pub fn debug_query<DB, T>(query: &T) -> DebugQuery<'_, T, DB> { |
| 441 | DebugQuery::new(query) |
| 442 | } |
| 443 | |
| 444 | mod private { |
| 445 | #[allow(missing_debug_implementations, missing_copy_implementations)] |
| 446 | pub struct NotSpecialized; |
| 447 | } |
| 448 | |
| 449 | pub(crate) mod has_query; |