Skip to content

Commit

Permalink
Merge branch 'master' into mysql_client_found_rows_flag
Browse files Browse the repository at this point in the history
  • Loading branch information
blackghost1987 committed Nov 2, 2021
2 parents 91a1697 + 3c9b21e commit af84cb5
Show file tree
Hide file tree
Showing 135 changed files with 4,265 additions and 1,372 deletions.
19 changes: 17 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -367,15 +367,16 @@ jobs:
args: --all -- --check

sqlite_bundled:
name: Check sqlite bundled
name: Check sqlite bundled + Sqlite with asan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: nightly
profile: minimal
override: true
components: rust-src
- name: Cache cargo registry
uses: actions/cache@v2
with:
Expand All @@ -394,6 +395,20 @@ jobs:
command: test
args: --manifest-path diesel_cli/Cargo.toml --no-default-features --features "sqlite-bundled"

- name: Run diesel_tests with ASAN enabled
env:
RUSTFLAGS: -Zsanitizer=address
ASAN_OPTIONS: detect_stack_use_after_return=1
run: cargo -Z build-std test --manifest-path diesel_tests/Cargo.toml --no-default-features --features "sqlite libsqlite3-sys libsqlite3-sys/bundled libsqlite3-sys/with-asan" --target x86_64-unknown-linux-gnu

- name: Run diesel tests with ASAN enabled
env:
RUSTDOCFLAGS: -Zsanitizer=address
RUSTFLAGS: -Zsanitizer=address
ASAN_OPTIONS: detect_stack_use_after_return=1
run: cargo -Z build-std test --manifest-path diesel/Cargo.toml --no-default-features --features "sqlite extras libsqlite3-sys libsqlite3-sys/bundled libsqlite3-sys/with-asan" --target x86_64-unknown-linux-gnu


minimal_rust_version:
name: Check Minimal supported rust version (1.51.0)
runs-on: ubuntu-latest
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/metrics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,21 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: bench
args: --manifest-path diesel_bench/Cargo.toml --no-default-features --features "${{matrix.backend}} sqlx sqlx/${{matrix.backend}} async-std sqlx/runtime-async-std-native-tls rustorm rustorm/with-${{matrix.backend}} rustorm_dao rust_postgres"
args: --manifest-path diesel_bench/Cargo.toml --no-default-features --features "${{matrix.backend}} sqlx-bench sqlx/${{matrix.backend}} async-std rust_postgres futures sea-orm sea-orm/sqlx-${{matrix.backend}} criterion/async_std"

- name: Run Benchmarks (Sqlite)
if: matrix.backend == 'sqlite'
uses: actions-rs/cargo@v1
with:
command: bench
args: --manifest-path diesel_bench/Cargo.toml --no-default-features --features "${{matrix.backend}} sqlx sqlx/${{matrix.backend}} async-std sqlx/runtime-async-std-native-tls rusqlite"
args: --manifest-path diesel_bench/Cargo.toml --no-default-features --features "${{matrix.backend}} sqlx-bench sqlx/${{matrix.backend}} async-std rusqlite futures sea-orm sea-orm/sqlx-${{matrix.backend}} criterion/async_std"

- name: Run Benchmarks (Mysql)
if: matrix.backend == 'mysql'
uses: actions-rs/cargo@v1
with:
command: bench
args: --manifest-path diesel_bench/Cargo.toml --no-default-features --features "${{matrix.backend}} sqlx sqlx/${{matrix.backend}} async-std sqlx/runtime-async-std-native-tls rustorm rustorm/with-${{matrix.backend}} rustorm_dao rust_mysql"
args: --manifest-path diesel_bench/Cargo.toml --no-default-features --features "${{matrix.backend}} sqlx-bench sqlx/${{matrix.backend}} async-std rustorm rustorm/with-${{matrix.backend}} rustorm_dao rust_mysql futures sea-orm sea-orm/sqlx-${{matrix.backend}} criterion/async_std"

- name: Push metrics
env:
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/

* Interacting with a database requires a mutable connection.

* `eq_any()` now emits a `= ANY()` expression for the postgresql backend instead of `IN()`
* `ne_all()` now emits a `!= ALL()` expression for the postgresql backend instead of `NOT IN()`
* The sqlite backend now uses a single batch insert statement if there are now default values present
in the values clause

* The MySQL connection is using the CLIENT_FOUND_ROWS from now on. This means that updating rows without changing any values will return the number of matched rows (like most other SQL servers do), as opposed to the number of changed rows.

### Fixed
Expand Down Expand Up @@ -232,6 +237,9 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/

* `diesel::pg::upsert` has been deprecated to support upsert queries on more than one backend.
Please use `diesel::upsert` instead.

* `diesel::dsl::any` and `diesel::dsl::all` are now deprecated in
favour of `ExpressionMethods::eq_any()` and `ExpressionMethods::ne_all()`

### Upgrade Notes

Expand Down
16 changes: 9 additions & 7 deletions diesel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ edition = "2018"
byteorder = "1.0"
chrono = { version = "0.4.19", optional = true, default-features = false, features = ["clock", "std"] }
libc = { version = "0.2.0", optional = true }
libsqlite3-sys = { version = ">=0.8.0, <0.23.0", optional = true, features = ["min_sqlite_version_3_7_16"] }
libsqlite3-sys = { version = ">=0.8.0, <0.24.0", optional = true, features = ["bundled_bindings"] }
mysqlclient-sys = { version = "0.2.0", optional = true }
pq-sys = { version = "0.4.0", optional = true }
quickcheck = { version = "0.9.0", optional = true }
serde_json = { version = ">=0.8.0, <2.0", optional = true }
url = { version = "2.1.0", optional = true }
percent-encoding = { version = "2.1.0", optional = true }
uuid = { version = ">=0.7.0, <0.9.0", optional = true}
uuid = { version = ">=0.7.0, <0.9.0", optional = true }
ipnetwork = { version = ">=0.12.2, <0.19.0", optional = true }
num-bigint = { version = ">=0.2.0, <0.4.0", optional = true }
num-bigint = { version = ">=0.2.0, <0.5.0", optional = true }
num-traits = { version = "0.2.0", optional = true }
num-integer = { version = "0.1.39", optional = true }
bigdecimal = { version = ">=0.0.13, < 0.3.0", optional = true }
bigdecimal = { version = ">=0.0.13, < 0.4.0", optional = true }
bitflags = { version = "1.2.0", optional = true }
r2d2 = { version = ">= 0.8.2, < 0.9.0", optional = true }
itoa = "0.4.0"
Expand All @@ -44,21 +44,23 @@ ipnetwork = ">=0.12.2, <0.19.0"
quickcheck = "0.9"

[features]
default = ["with-deprecated", "32-column-tables"]
default = ["32-column-tables", "with-deprecated"]
extras = ["chrono", "serde_json", "uuid", "network-address", "numeric", "r2d2"]
unstable = ["diesel_derives/nightly"]
large-tables = ["32-column-tables"]
huge-tables = ["64-column-tables"]
32-column-tables = []
64-column-tables = ["32-column-tables"]
128-column-tables = ["64-column-tables"]
postgres = ["pq-sys", "bitflags", "diesel_derives/postgres"]
postgres = ["pq-sys", "postgres_backend"]
sqlite = ["libsqlite3-sys", "diesel_derives/sqlite"]
mysql = ["mysqlclient-sys", "url", "percent-encoding", "diesel_derives/mysql", "bitflags"]
mysql = ["mysqlclient-sys", "url", "percent-encoding", "bitflags", "mysql_backend"]
without-deprecated = []
with-deprecated = []
network-address = ["ipnetwork", "libc"]
numeric = ["num-bigint", "bigdecimal", "num-traits", "num-integer"]
postgres_backend = ["diesel_derives/postgres", "bitflags"]
mysql_backend = ["diesel_derives/mysql"]

[package.metadata.docs.rs]
features = ["postgres", "mysql", "sqlite", "extras"]
Expand Down
213 changes: 197 additions & 16 deletions diesel/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::sql_types::{self, HasSqlType};
/// protocol used to communicated with the database.
pub trait Backend
where
Self: Sized,
Self: Sized + SqlDialect,
Self: HasSqlType<sql_types::SmallInt>,
Self: HasSqlType<sql_types::Integer>,
Self: HasSqlType<sql_types::BigInt>,
Expand Down Expand Up @@ -73,19 +73,200 @@ pub trait BinaryRawValue<'a>: HasRawValue<'a> {
/// `FromSql`. Equivalent to `<DB as Backend>::RawValue<'a>`.
pub type RawValue<'a, DB> = <DB as HasRawValue<'a>>::RawValue;

/// A trait indicating that implementing backend provides support for
/// `RETURNING` clauses.
/// This trait provides various options to configure the
/// generated SQL for a specific backend.
///
/// This trait has to be implemented in order to be able to use methods such as
/// `get_results` and `returning`. Namely, any method which leads to usage of
/// `RETURNING` clauses in SQL sent to backend will require that this trait
/// be implemented for used backend.
pub trait SupportsReturningClause {}
/// Does this backend support 'ON CONFLICT' clause?
pub trait SupportsOnConflictClause {}
/// Does this backend support 'WHERE' clauses on 'ON CONFLICT' clauses?
pub trait SupportsOnConflictTargetDecorations {}
/// Does this backend support the bare `DEFAULT` keyword?
pub trait SupportsDefaultKeyword {}
/// Does this backend use the standard `SAVEPOINT` syntax?
pub trait UsesAnsiSavepointSyntax {}
/// Accessing anything from this trait is considered to be part of the
/// public API. Implementing this trait is not considered to be part of
/// diesels public API, as future versions of diesel may add additional
/// associated constants here.
///
/// Each associated type is used to configure the behaviour
/// of one or more [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementations by providing
/// a custom `QueryFragment<YourBackend, YourSpecialSyntaxType>` implementation
/// to specialize on generic `QueryFragment<DB, DB::AssociatedType>` implementations.
///
/// See the [`sql_dialect`] module for options provided by diesel out of the box.
pub trait SqlDialect {
/// Configures how this backends supports `RETURNING` clauses
///
/// This allows backends to opt in `RETURNING` clause support and to
/// provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementation for [`ReturningClause`](crate::query_builder::ReturningClause)
type ReturningClause;
/// Configures how this backend supports `ON CONFLICT` clauses
///
/// This allows backends to opt in `ON CONFLICT` clause support
type OnConflictClause;
/// Configures how this backend handles the bare `DEFAULT` keyword for
/// inserting the default value in a `INSERT INTO` `VALUES` clause
///
/// This allows backends to opt in support for `DEFAULT` value expressions
/// for insert statements
type InsertWithDefaultKeyword;
/// Configures how this backend handles Batch insert statements
///
/// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementation for [`BatchInsert`](crate::query_builder::BatchInsert)
type BatchInsertSupport;
/// Configures how this backend handles the `DEFAULT VALUES` clause for
/// insert statements.
///
/// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementation for [`DefaultValues`](crate::query_builder::DefaultValues)
type DefaultValueClauseForInsert;
/// Configures how this backend handles empty `FROM` clauses for select statements.
///
/// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementation for [`NoFromClause`](crate::query_builder::NoFromClause)
type EmptyFromClauseSyntax;
/// Configures how this backend handles `EXISTS()` expressions.
///
/// This allows backends to provide a custom [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementation for [`Exists`](crate::expression::exists::Exists)
type ExistsSyntax;

/// Configures how this backend handles `IN()` and `NOT IN()` expressions.
///
/// This allows backends to provide custom [`QueryFragment`](crate::query_builder::QueryFragment)
/// implementations for [`In`](crate::expression::array_comparison::In),
/// [`NotIn`](crate::expression::array_comparison::NotIn) and
/// [`Many`](crate::expression::array_comparison::Many)
type ArrayComparision;
}

/// This module contains all options provided by diesel to configure the [`SqlDialect`] trait.
pub mod sql_dialect {
#[cfg(doc)]
use super::SqlDialect;

/// This module contains all diesel provided reusable options to
/// configure [`SqlDialect::OnConflictClause`]
pub mod on_conflict_clause {
/// A marker trait indicating if a `ON CONFLICT` clause is supported or not
///
/// If you use a custom type to specify specialized support for `ON CONFLICT` clauses
/// implementing this trait opts into reusing diesels existing `ON CONFLICT`
/// `QueryFragment` implementations
pub trait SupportsOnConflictClause {}

/// This marker type indicates that `ON CONFLICT` clauses are not supported for this backend
#[derive(Debug, Copy, Clone)]
pub struct DoesNotSupportOnConflictClause;
}

/// This module contains all reusable options to configure
/// [`SqlDialect::ReturningClause`]
pub mod returning_clause {
/// A marker trait indicating if a `RETURNING` clause is supported or not
///
/// If you use custom type to specify specialized support for `RETURNING` clauses
/// implementing this trait opts in supporting `RETURNING` clause syntax
pub trait SupportsReturningClause {}

/// Indicates that a backend provides support for `RETURNING` clauses
/// using the postgresql `RETURNING` syntax
#[derive(Debug, Copy, Clone)]
pub struct PgLikeReturningClause;

/// Indicates that a backend does not support `RETURNING` clauses
#[derive(Debug, Copy, Clone)]
pub struct DoesNotSupportReturningClause;

impl SupportsReturningClause for PgLikeReturningClause {}
}

/// This module contains all reusable options to configure
/// [`SqlDialect::InsertWithDefaultKeyword`]
pub mod default_keyword_for_insert {
/// A marker trait indicating if a `DEFAULT` like expression
/// is supported as part of `INSERT INTO` clauses to indicate
/// that a default value should be inserted at a specific position
///
/// If you use a custom type to specify specialized support for `DEFAULT`
/// expressions implementing this trait opts in support for `DEFAULT`
/// value expressions for inserts. Otherwise diesel will emulate this
/// behaviour.
pub trait SupportsDefaultKeyword {}

/// Indicates that a backend support `DEFAULT` value expressions
/// for `INSERT INTO` statements based on the ISO SQL standard
#[derive(Debug, Copy, Clone)]
pub struct IsoSqlDefaultKeyword;

/// Indicates that a backend does not support `DEFAULT` value
/// expressions0for `INSERT INTO` statements
#[derive(Debug, Copy, Clone)]
pub struct DoesNotSupportDefaultKeyword;

impl SupportsDefaultKeyword for IsoSqlDefaultKeyword {}
}

/// This module contains all reusable options to configure
/// [`SqlDialect::BatchInsertSupport`]
pub mod batch_insert_support {
/// A marker trait indicating if batch insert statements
/// are supported for this backend or not
pub trait SupportsBatchInsert {}

/// Indicates that this backend does not support batch
/// insert statements.
/// In this case diesel will emulate batch insert support
/// by inserting each row on it's own
#[derive(Debug, Copy, Clone)]
pub struct DoesNotSupportBatchInsert;

/// Indicates that this backend supports postgres style
/// batch insert statements to insert multiple rows using one
/// insert statement
#[derive(Debug, Copy, Clone)]
pub struct PostgresLikeBatchInsertSupport;

impl SupportsBatchInsert for PostgresLikeBatchInsertSupport {}
}

/// This module contains all reusable options to configure
/// [`SqlDialect::DefaultValueClauseForInsert`]
pub mod default_value_clause {

/// Indicates that this backend uses the
/// `DEFAULT VALUES` syntax to specify
/// that a row consisting only of default
/// values should be inserted
#[derive(Debug, Clone, Copy)]
pub struct AnsiDefaultValueClause;
}

/// This module contains all reusable options to configure
/// [`SqlDialect::EmptyFromClauseSyntax`]
pub mod from_clause_syntax {

/// Indicates that this backend skips
/// the `FROM` clause in `SELECT` statements
/// if no table/view is queried
#[derive(Debug, Copy, Clone)]
pub struct AnsiSqlFromClauseSyntax;
}

/// This module contains all reusable options to configure
/// [`SqlDialect::ExistsSyntax`]
pub mod exists_syntax {

/// Indicates that this backend
/// treats `EXIST()` as function
/// like expression
#[derive(Debug, Copy, Clone)]
pub struct AnsiSqlExistsSyntax;
}

/// This module contains all reusable options to configure
/// [`SqlDialect::ArrayComparision`]
pub mod array_comparision {

/// Indicates that this backend requires a single bind
/// per array element in `IN()` and `NOT IN()` expression
#[derive(Debug, Copy, Clone)]
pub struct AnsiSqlArrayComparison;
}
}

0 comments on commit af84cb5

Please sign in to comment.