Repository navigation
Parenthesize in expressions used as operands - #760
Merged
Merged
Conversation
On PostgreSQL, `x == (y in ^list)` generated `x = y = ANY($1)`, which is a syntax error because comparison operators are non-associative. On MySQL, `(x in [1, 2]) in [true]` generated `x IN (1,2) IN (TRUE)`, which is also a syntax error. Wrap in/2 in parentheses when it is an operand, as is already done for binary operators, is_nil/1 and not/1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
in/2was not wrapped in parentheses when it appeared as an operand, unlike binary operators,is_nil/1andnot/1(see #753 and #754). Two cases produce invalid SQL:select: p.public == (p.visits in ^[1, 2])generatesp0."public" = p0."visits" = ANY($1). Comparison operators are non-associative in PostgreSQL, so this fails withsyntax error at or near "=". The same happens withinon a column (= ANY(p0."w")).select: (p.visits in [1, 2]) in [true]generatesp0.visits IN (1,2) IN (TRUE), which MySQL rejects with error 1064.This adds an
inclause tomaybe_paren/3(Postgres) andop_to_binary/3(MySQL). Two existing assertions change only by the added parentheses around theinoperand ofor.Checks run:
mix test: 707 passedmix format --check-formatted: cleanECTO_ADAPTER=pg mix testagainst PostgreSQL 17 (docker) andECTO_ADAPTER=myxql mix testagainst MySQL 8.4 (docker). The sameStorageTestcases fail with and without this change (15 on pg, 11 on myxql), becausepg_dump/psql/mysqlclient binaries aren't installed locally. Nothing else fails.TestRepoagainst those databases. Before the change, each one raised the syntax error quoted above. After it, they returned[true, false](pg) and[1, 0](myxql).Not run: the MSSQL adapter (unchanged) and the earthly CI matrix.