Skip to content

Commit

Permalink
Fixes #468: Tuple-value comparisons generate incorrect queries
Browse files Browse the repository at this point in the history
  • Loading branch information
kozlovsky committed Oct 21, 2019
1 parent bbf8de6 commit 397e6ac
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
7 changes: 4 additions & 3 deletions pony/orm/sqltranslation.py
Expand Up @@ -2451,9 +2451,10 @@ def getsql(monad, sqlquery=None):
if monad.translator.row_value_syntax:
return [ [ cmp_ops[op], [ 'ROW' ] + left_sql, [ 'ROW' ] + right_sql ] ]
clauses = []
for i in xrange(1, size):
clauses.append(sqland([ [ monad.EQ, left_sql[j], right_sql[j] ] for j in xrange(1, i) ]
+ [ [ cmp_ops[op[0] if i < size - 1 else op], left_sql[i], right_sql[i] ] ]))
for i in xrange(size):
clause = [ [ monad.EQ, left_sql[j], right_sql[j] ] for j in range(i) ]
clause.append([ cmp_ops[op], left_sql[i], right_sql[i] ])
clauses.append(sqland(clause))
return [ sqlor(clauses) ]
if op == '==':
return [ sqland([ [ monad.EQ, a, b ] for a, b in izip(left_sql, right_sql) ]) ]
Expand Down
57 changes: 57 additions & 0 deletions pony/orm/tests/queries.txt
Expand Up @@ -1014,3 +1014,60 @@ SELECT t.* FROM (
) t
) t WHERE "row-num" > 3

# Test row comparison:

>>> select((s1.id, s2.id) for s1 in Student for s2 in Student if (s1.name, s1.gpa, s1.tel) < (s2.name, s2.gpa, s2.tel))

SELECT DISTINCT "s1"."id", "s2"."id"
FROM "Student" "s1", "Student" "s2"
WHERE ("s1"."name" < "s2"."name" OR "s1"."name" = "s2"."name" AND "s1"."gpa" < "s2"."gpa" OR "s1"."name" = "s2"."name" AND "s1"."gpa" = "s2"."gpa" AND "s1"."tel" < "s2"."tel")

PostgreSQL:

SELECT DISTINCT "s1"."id", "s2"."id"
FROM "student" "s1", "student" "s2"
WHERE ("s1"."name", "s1"."gpa", "s1"."tel") < ("s2"."name", "s2"."gpa", "s2"."tel")

MySQL:

SELECT DISTINCT `s1`.`id`, `s2`.`id`
FROM `student` `s1`, `student` `s2`
WHERE (`s1`.`name`, `s1`.`gpa`, `s1`.`tel`) < (`s2`.`name`, `s2`.`gpa`, `s2`.`tel`)

Oracle:

SELECT DISTINCT "s1"."ID", "s2"."ID"
FROM "STUDENT" "s1", "STUDENT" "s2"
WHERE ("s1"."NAME", "s1"."GPA", "s1"."TEL") < ("s2"."NAME", "s2"."GPA", "s2"."TEL")

>>> select((s1.id, s2.id) for s1 in Student for s2 in Student if (s1.name, s1.gpa, s1.tel) == (s2.name, s2.gpa, s2.tel))

SELECT DISTINCT "s1"."id", "s2"."id"
FROM "Student" "s1", "Student" "s2"
WHERE "s1"."name" = "s2"."name"
AND "s1"."gpa" = "s2"."gpa"
AND "s1"."tel" = "s2"."tel"

PostgreSQL:

SELECT DISTINCT "s1"."id", "s2"."id"
FROM "student" "s1", "student" "s2"
WHERE "s1"."name" = "s2"."name"
AND "s1"."gpa" = "s2"."gpa"
AND "s1"."tel" = "s2"."tel"

MySQL:

SELECT DISTINCT `s1`.`id`, `s2`.`id`
FROM `student` `s1`, `student` `s2`
WHERE `s1`.`name` = `s2`.`name`
AND `s1`.`gpa` = `s2`.`gpa`
AND `s1`.`tel` = `s2`.`tel`

Oracle:

SELECT DISTINCT "s1"."ID", "s2"."ID"
FROM "STUDENT" "s1", "STUDENT" "s2"
WHERE "s1"."NAME" = "s2"."NAME"
AND "s1"."GPA" = "s2"."GPA"
AND "s1"."TEL" = "s2"."TEL"

0 comments on commit 397e6ac

Please sign in to comment.