Skip to content

Commit 1b4a8a4

Browse files
committed
refactor: remove IN/NOT IN normalization from PG predicate comparison, keep parens and cast handling only
1 parent 8ebaf27 commit 1b4a8a4

2 files changed

Lines changed: 4 additions & 110 deletions

File tree

  • schema-engine

schema-engine/connectors/sql-schema-connector/src/flavour/postgres/schema_differ.rs

Lines changed: 4 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ fn push_alter_enum_previous_usages_as_default(db: &DifferDatabase<'_>, alter_enu
750750
// Accounts for PG expression normalization (operator aliases, parens, implicit literal casts).
751751
fn pg_predicates_semantically_equal(a: &str, b: &str) -> bool {
752752
use sqlparser::{
753-
ast::{BinaryOperator, Value, VisitMut, VisitorMut},
753+
ast::{Value, VisitMut, VisitorMut},
754754
dialect::PostgreSqlDialect,
755755
parser::Parser,
756756
};
@@ -762,69 +762,14 @@ fn pg_predicates_semantically_equal(a: &str, b: &str) -> bool {
762762
type Break = ();
763763

764764
fn post_visit_expr(&mut self, expr: &mut Expr) -> ControlFlow<()> {
765-
if !matches!(
766-
expr,
767-
Expr::Nested(_)
768-
| Expr::AnyOp {
769-
compare_op: BinaryOperator::Eq,
770-
is_some: false,
771-
..
772-
}
773-
| Expr::AllOp {
774-
compare_op: BinaryOperator::NotEq,
775-
..
776-
}
777-
) {
765+
if !matches!(expr, Expr::Nested(_)) {
778766
return ControlFlow::Continue(());
779767
}
780768

781769
let placeholder = Expr::value(Value::Null);
782770

783-
match std::mem::replace(expr, placeholder) {
784-
Expr::Nested(inner) => *expr = *inner,
785-
// PG rewrites `x IN (v1, v2)` to `x = ANY(ARRAY[v1::t, v2::t])`.
786-
Expr::AnyOp {
787-
left,
788-
right,
789-
compare_op,
790-
is_some,
791-
} => {
792-
if let Expr::Array(arr) = *right {
793-
*expr = Expr::InList {
794-
expr: left,
795-
list: arr.elem,
796-
negated: false,
797-
};
798-
} else {
799-
*expr = Expr::AnyOp {
800-
left,
801-
compare_op,
802-
right,
803-
is_some,
804-
};
805-
}
806-
}
807-
// PG rewrites `x NOT IN (v1, v2)` to `x <> ALL(ARRAY[v1::t, v2::t])`.
808-
Expr::AllOp {
809-
left,
810-
right,
811-
compare_op,
812-
} => {
813-
if let Expr::Array(arr) = *right {
814-
*expr = Expr::InList {
815-
expr: left,
816-
list: arr.elem,
817-
negated: true,
818-
};
819-
} else {
820-
*expr = Expr::AllOp {
821-
left,
822-
compare_op,
823-
right,
824-
};
825-
}
826-
}
827-
other => *expr = other,
771+
if let Expr::Nested(inner) = std::mem::replace(expr, placeholder) {
772+
*expr = *inner;
828773
}
829774

830775
ControlFlow::Continue(())
@@ -942,21 +887,6 @@ fn exprs_semantically_eq(a: &Expr, b: &Expr) -> bool {
942887
exprs_semantically_eq(ea, eb) && exprs_semantically_eq(la, lb) && exprs_semantically_eq(ha, hb)
943888
}
944889

945-
(
946-
Expr::InList {
947-
expr: ea,
948-
list: la,
949-
negated: na,
950-
},
951-
Expr::InList {
952-
expr: eb,
953-
list: lb,
954-
negated: nb,
955-
},
956-
) if na == nb && la.len() == lb.len() => {
957-
exprs_semantically_eq(ea, eb) && la.iter().zip(lb).all(|(a, b)| exprs_semantically_eq(a, b))
958-
}
959-
960890
(
961891
Expr::Cast {
962892
kind: ka,

schema-engine/sql-migration-tests/tests/migrations/indexes/partial.rs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,39 +1009,3 @@ fn partial_index_not_with_and_or_roundtrip_postgres(api: TestApi) {
10091009
api.schema_push(&dm).send().assert_green();
10101010
api.schema_push(&dm).send().assert_no_steps();
10111011
}
1012-
1013-
#[test_connector(tags(Postgres), exclude(CockroachDb), preview_features("partialIndexes"))]
1014-
fn partial_index_with_in_list_predicate_is_idempotent_postgres(api: TestApi) {
1015-
let dm = api.datamodel_with_provider_and_features(
1016-
r#"model User {
1017-
id Int @id
1018-
email String
1019-
status String
1020-
1021-
@@index([email], where: raw("status IN ('active', 'pending')"))
1022-
}"#,
1023-
&[],
1024-
PREVIEW_FEATURES,
1025-
);
1026-
1027-
api.schema_push(&dm).send().assert_green();
1028-
api.schema_push(&dm).send().assert_no_steps();
1029-
}
1030-
1031-
#[test_connector(tags(Postgres), exclude(CockroachDb), preview_features("partialIndexes"))]
1032-
fn partial_index_with_not_in_list_predicate_is_idempotent_postgres(api: TestApi) {
1033-
let dm = api.datamodel_with_provider_and_features(
1034-
r#"model User {
1035-
id Int @id
1036-
email String
1037-
status String
1038-
1039-
@@index([email], where: raw("status NOT IN ('deleted', 'archived')"))
1040-
}"#,
1041-
&[],
1042-
PREVIEW_FEATURES,
1043-
);
1044-
1045-
api.schema_push(&dm).send().assert_green();
1046-
api.schema_push(&dm).send().assert_no_steps();
1047-
}

0 commit comments

Comments
 (0)