Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuple-value comparisons generate incorrect queries #468

Closed
fluffy-critter opened this issue Sep 24, 2019 · 2 comments
Closed

Tuple-value comparisons generate incorrect queries #468

fluffy-critter opened this issue Sep 24, 2019 · 2 comments

Comments

@fluffy-critter
Copy link

fluffy-critter commented Sep 24, 2019

I have a lot of code where I'm trying to find values which are compared like tuples; for example, with an object Foo with fields a, b, and c, doing a comparison like

(left.a,left.b,left.c) < (right.a,right.b,right.c)

I can (clumsily, and error-proneily) do something like:

from pony import orm

r = model.Foo.get(id=5)
query = orm.select(q for q in model.Foo if
    q.field_a < r.field_a
    or (q.field_a == r.field_a and q.field_b < r.field_b)
    or (q.field_a == r.field_a and q.field_b == r.field_b and q.field_c < r.field_c))

but it would be nice to be able to instead just do:

query = orm.select(q for q in model.Foo if (q.field_a,q.field_b,q.field_c) < (r.field_a,r.field_b,r.field_c))

Pony successfully generates a query for that statement, but the resuling SQL is incorrect, in that it only compares field_c. For example (with a real, non-metasyntactic example):

>>> e=model.Entry.get(id=3982)
>>> orm.select(q for q in model.Entry if (q.local_date,q.id) < (e.local_date,e.id)).get_sql()
'SELECT "q"."id", "q"."file_path", "q"."category", "q"."status", "q"."utc_date", "q"."local_date", "q"."display_date", "q"."slug_text", "q"."entry_type", "q"."redirect_url", "q"."title", "q"."sort_title", "q"."entry_template"\nFROM "Entry" "q"\nWHERE "q"."id" < ?'

Using a lambda fares no better:

>>> model.Entry.select(lambda q: (q.local_date,q.id) < (e.local_date,e.id)).get_sql()
'SELECT "q"."id", "q"."file_path", "q"."category", "q"."status", "q"."utc_date", "q"."local_date", "q"."display_date", "q"."slug_text", "q"."entry_type", "q"."redirect_url", "q"."title", "q"."sort_title", "q"."entry_template"\nFROM "Entry" "q"\nWHERE "q"."id" < ?'

So, either the API allows a thing it shouldn't, or the implementation of that support is incorrect. Either way it'd be nice for it to work right.

@kozlovsky
Copy link
Member

Thanks for reporting, should be fixed now

@fluffy-critter
Copy link
Author

Thanks so much!

kozlovsky added a commit that referenced this issue Oct 23, 2019
# Features

* #472: Python 3.8 support
* Support of hybrid functions (inlining simple Python functions into query)
* #438: support datetime-datetime, datetime-timedelta, datetime+timedelta in queries

# Bugfixes

* #430: add ON DELETE CASCADE for many-to-many relationships
* #465: Should reconnect to MySQL on OperationalError 2013 'Lost connection to MySQL server during query'
* #468: Tuple-value comparisons generate incorrect queries
* #470 fix PendingDeprecationWarning of imp module
* Fix incorrect unpickling of objects with Json attributes
* Check value of discriminator column on object creation if set explicitly
* Correctly handle Flask current_user proxy when adding new items to collections
* Some bugs in syntax of aggregated queries were fixed
* Fix syntax of bulk delete queries
* Bulk delete queries should clear query results cache so next select will get correct result from the database
* Fix error message when hybrid method is too complex to decompile
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

No branches or pull requests

2 participants