Opened 13 years ago
Closed 13 years ago
#17877 closed Bug (fixed)
query.extra(where=...) lack parenthesis
Reported by: | Owned by: | Adrien Lemaire | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | brzoskamarek@…, eleather, lemaire.adrien@… | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
When using some_query.extra(where="some_code OR more_code") documentation says the where-clause will be ANDed with other conditions.
I believe the ANDing part does not surround the user specified where-clause with parenthesis which in this case leads to erroneous code because AND has higher priority than OR.
Attachments (1)
Change History (8)
comment:1 by , 13 years ago
Cc: | added |
---|---|
Easy pickings: | set |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 13 years ago
Owner: | changed from | to
---|
I'm looking at it. We should look at a better example for this where case, because it might incite people who read the doc fast to start using Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])
instead of Entry.objects.filter(id__in=[3, 4, 5, 20])
comment:3 by , 13 years ago
hmmm I can see 2 options:
- where becomes a string, and we force the user to write :
Thing.objects.extra(where="(foo='a' OR bar = 'a') AND baz = 'a'")
- Add a bit of code that look for the string ' OR ' in each element of the where list, and wrap the element if the string is present:
Thing.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'")
will become:
Thing.objects.extra(where=["(foo='a' OR bar = 'a')", "baz = 'a'")
in ExtraWhere.as_sql() (sql/where.py)
The first solution would be simplest, but backward-incompatible. I'll start working on the 2nd solution
comment:4 by , 13 years ago
Cc: | added |
---|---|
Has patch: | set |
Needs tests: | set |
Easy fix, I just wrapped each element with parenthesis.
Doc updated with eleather example.
Just realize that it needs tests, will work on it now
comment:5 by , 13 years ago
Needs tests: | unset |
---|
I was able to replicate what I believe is the reported issue. Marek, if you were trying to report a broader issue than interaction between where strings in a call to extra, please comment with an extended explanation.
My steps to replicate:
This confirms that that query is retrieving 'foo OR (bar AND baz)' instead of '(foo OR bar) AND baz'. This would be fixable by the reporter's suggestion that each 'extra, where' string be surrounded by parentheses when being added to the sql query.