Skip to content

Commit

Permalink
feat(schema-engine): don't query CHECK_CONSTRAINTS on MySQL <= 8.0.16
Browse files Browse the repository at this point in the history
  • Loading branch information
jkomyno committed Jan 19, 2024
1 parent ec17f10 commit dacf873
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 9 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions schema-engine/connectors/sql-schema-connector/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ url = "2.1.1"
either = "1.6"
sqlformat = "0.2.1"
sqlparser = "0.32.0"
versions = "6.1.0"
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use schema_connector::{
use sql_schema_describer::SqlSchema;
use std::future;
use url::Url;
use versions::Versioning;

const ADVISORY_LOCK_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
static QUALIFIED_NAME_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"`[^ ]+`\.`[^ ]+`").unwrap());
Expand Down Expand Up @@ -430,6 +431,7 @@ pub(crate) enum Circumstances {
IsMysql57,
IsMariadb,
IsVitess,
CheckConstraints,
}

fn check_datamodel_for_mysql_5_6(datamodel: &ValidatedSchema, errors: &mut Vec<String>) {
Expand Down Expand Up @@ -533,6 +535,9 @@ where
let mut circumstances = BitFlags::<Circumstances>::default();

if let Some((version, global_version)) = versions {
let semver = Versioning::new(&global_version).unwrap_or_default();
let min_check_constraints_semver = Versioning::new("8.0.16").unwrap();

if version.contains("vitess") || version.contains("Vitess") {
circumstances |= Circumstances::IsVitess;
}
Expand All @@ -548,6 +553,10 @@ where
if global_version.contains("MariaDB") {
circumstances |= Circumstances::IsMariadb;
}

if semver >= min_check_constraints_semver {
circumstances |= Circumstances::CheckConstraints;
}
}

let result_set = connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@ impl Connection {
describer_circumstances |= describer::Circumstances::MySql57;
}

if circumstances.contains(super::Circumstances::CheckConstraints)
&& !describer_circumstances.intersects(
describer::Circumstances::MySql56
| describer::Circumstances::MySql57
| describer::Circumstances::MariaDb,
)
{
// MySQL 8.0.16 and above supports check constraints.
// MySQL 5.6 and 5.7 do not have a CHECK_CONSTRAINTS table we can query.
// MariaDB, although it supports check constraints, adds them unexpectedly.
// E.g., MariaDB 10 adds the `json_valid(\`Priv\`)` check constraint on every JSON column;
// this creates a noisy, unexpected diff when comparing the introspected schema with the prisma schema.
describer_circumstances |= describer::Circumstances::CheckConstraints;
}

let mut schema = sql_schema_describer::mysql::SqlSchemaDescriber::new(&self.0, describer_circumstances)
.describe(&[params.url.dbname()])
.await
Expand Down
12 changes: 3 additions & 9 deletions schema-engine/sql-schema-describer/src/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub enum Circumstances {
MariaDb,
MySql56,
MySql57,
CheckConstraints,
}

pub struct SqlSchemaDescriber<'a> {
Expand Down Expand Up @@ -737,7 +738,7 @@ impl<'a> SqlSchemaDescriber<'a> {
table_names: &IndexMap<String, TableId>,
sql_schema: &mut SqlSchema,
) -> DescriberResult<()> {
// Only MySQL 8 and above supports check constraints and has the CHECK_CONSTRAINTS table we can query.
// Only MySQL 8.0.16 and above supports check constraints and has the CHECK_CONSTRAINTS table we can query.
if !self.supports_check_constraints() {
return Ok(());
}
Expand Down Expand Up @@ -806,14 +807,7 @@ impl<'a> SqlSchemaDescriber<'a> {

/// Tests whether the current database supports check constraints
fn supports_check_constraints(&self) -> bool {
// MySQL 8 and above supports check constraints.
// MySQL 5.6 and 5.7 do not have a CHECK_CONSTRAINTS table we can query.
// MariaDB, although it supports check constraints, adds them unexpectedly.
// E.g., MariaDB 10 adds the `json_valid(\`Priv\`)` check constraint on every JSON column;
// this creates a noisy, unexpected diff when comparing the introspected schema with the prisma schema.
!self
.circumstances
.intersects(Circumstances::MySql56 | Circumstances::MySql57 | Circumstances::MariaDb)
self.circumstances.contains(Circumstances::CheckConstraints)
}
}

Expand Down

0 comments on commit dacf873

Please sign in to comment.