Opened 17 years ago
Closed 17 years ago
#4855 closed (invalid)
regression: qs.extra(where="foo IN %s",params=tuple) fails with SQL syntax error in SVN 5677
Reported by: | Jörg Höhle | Owned by: | durdinator |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi,
I have just upgraded from ~svn-2007-06-26 to 5677 (on 2007-07-12) and my SELECT IN code now fails:
Bug.objects.extra(where=['parent in %s'],params=[tuple([1,2,3])])
It now obviously adds 'single quotes ' around '(1,2,3)', where there were none previously (correct syntax). So I consider this a regression.
Of course, I could rewrite my code to say where=% tuple(), but that does not feel right. Esp, what if somebody does SQL-injection into my tuple?
It seems like tuple type should be recognized (special-cased), and quotes maybe added within each element, according to the result type. But how could Django possibly guess the required type??
File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 480, in _get_data self._result_cache = list(self.iterator()) File "/usr/lib/python2.4/site-packages/django/db/models/query.py", line 188, in iterator cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) File "/usr/lib/python2.4/site-packages/django/db/backends/util.py", line 19, in execute return self.cursor.execute(sql, params) File "/usr/lib/python2.4/site-packages/django/db/backends/postgresql/base.py", line 53, in execute return self.cursor.execute(smart_str(sql, self.charset), self.format_params(params)) ProgrammingError: FEHLER: Fehler »Syntaxfehler« bei »'(1, 2, 3)'« at character 101 SELECT "polls_bug"."id","polls_bug"."parent_id","polls_bug"."name" FROM "polls_bug" WHERE parent in '(1, 2, 3)'
I'm using postgresql, as seen in the backtrace.
class Bug(models.Model): parent = models.ForeignKey('self',null=True,blank=True) name = models.CharField(maxlength=30) def __str__(self): return self.name class Admin: pass
Regards,
Jörg Höhle
Change History (3)
comment:1 by , 17 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 17 years ago
Owner: | changed from | to
---|
comment:3 by , 17 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
This is not a regression.
The fact that it worked at all before was coincidence, as
str(tuple([1, 2, 3]))
will give you'(1, 2, 3)'
(calling repr() on each item in the tuple). Your code should instead be doing this:The python DB API doesn't support tuples or lists as parameters.