Skip to content

Parse NOT IN in sql parser - #1832

Draft
agusaldasoro wants to merge 1 commit into
masterfrom
fix/in
Draft

agusaldasoro wants to merge 1 commit into
masterfrom
fix/in

Conversation

@agusaldasoro

@agusaldasoro agusaldasoro commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

JSqlVisitor.visit(InExpression) ignored inExpression.isNot(), so NOT IN was parsed into the same SqlInCondition as IN. Each consumer then translated the condition into its opposite:

  • Z3 solver (SMTConditionVisitor): status NOT IN ('A', 'B') became (or (= STATUS "A") (= STATUS "B")). The formula is satisfiable, but the generated rows never satisfy the query. With a CHECK (... NOT IN ...) in the schema, the generated row violates the constraint and the database rejects the INSERT.
  • Search-based generation (SqlConditionTranslator): CHECK (status NOT IN ('A', 'B')) became an EnumConstraint with values A and B. The column was restricted to exactly the forbidden values.

Fix

  • SqlInCondition gets a negated flag, included in equals / hashCode and printed by toSql() as NOT IN. The existing two-argument constructor keeps negated = false.
  • JSqlVisitor passes inExpression.isNot().
  • SMTConditionVisitor translates a negated list as a conjunction of inequalities: (and (distinct STATUS "A") (distinct STATUS "B")), or a single distinct for a one-element list.
  • SqlConditionTranslator throws SqlCannotBeTranslatedException for a negated list. There is no "any value but these" constraint, so TableConstraintBuilder now reports the check as an UnsupportedTableConstraint instead of inverting it, as it already does for other untranslatable checks.

ALL was already excluded from the ANY/SOME membership rewrite, so <> ALL (ARRAY[...]) is not affected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant