Code

Opened 6 years ago

Closed 6 years ago

#6940 closed (duplicate)

Bug in count() when string formats in select

Reported by: m.gajda@… Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: bug count orm string format qs-rf
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Hi!

I have found a bug in Django ORM. This very rare situation, it occured in my application code. I have created complex query using extra() function on query set. This query contains some formatting strings in "select" clause, which will be filled up using "params" clause.

In this case, query set's count() function fails. The reason is in file django/db/models/query.py, in count() method. This method invokes query, but it completely omits the "SELECT" part of generated query. However - all formatting parameters are still passed to the query executing function. Below the example:

> from django.contrib.auth.models import User

> User.objects.filter( pk = 1 ).extra( select = { "foo" : "%s" } , params = ( "bar" , ) ).count()
...
<type 'exceptions.TypeError'>: not all arguments converted during string formatting

I've have created simple patch fixing this bug. It just counts the number of string formats in "select" clause and removed respecting parameters from "params" clause.

I hope, that you will fix the bug soon.

Best regards,
--
Marcin Gajda

Attachments (1)

orm-count-fix.patch (1.1 KB) - added by m.gajda@… 6 years ago.

Download all attachments as: .zip

Change History (4)

Changed 6 years ago by m.gajda@…

comment:1 Changed 6 years ago by mtredinnick

  • Keywords qs-rf added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

Not worth fixing in trunk, since parameters in extra(select=...) don't work reliably there in any case (dictionaries don't maintain their order). Will fix on queryset-refactor, though.

comment:2 Changed 6 years ago by anonymous

Hm.. I do not understand. What do you mean, when you write about ordering maintenance of dictionaries? This bug does not depend on any of "select" dictionary property, because it relies on while "select" dictionary, intependently of its elements. It sufficient to have just one "%s" formatting in one of "select" dictionary values to make django ORM fail.

Two minutes ago I have tested this issue of stable Django version (0.96.1) - it fails too. I think - it is a big issue, which does not allow to write complex queries.

comment:3 Changed 6 years ago by mtredinnick

  • Resolution set to duplicate
  • Status changed from new to closed

Putting parameters in extra(select=...) in trunk is entirely unsupported. The parameters are a list, the select dictionary is a dictionary and hence arbitrarily ordered. Thus when you have more than one item expecting parameters, the order of the placeholders in the dictionary is not going to match up with the parameters list. Thus fixing a "bug" for something this isn't supported and is known not to work in almost all cases (it only works in the very special case of one parameter in extra(select=...)) isn't worth it.

Queryset-refactor will be merged into trunk very soon and it will be fixed prior to that merge.

I've just noticed that this is, in fact, already covered in a ticket (#3141), so I'm closing as a dupe of that (it also relies on the fix for #2902, updated in [7340]).

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.