On the None -> IS NULL issue, I presume there are, for any given use case,
not that many argument permutations of None and not None passed.  I suggest
that the PreparedStatement abstraction map to multiple actual prepared
statements, one for each None/not None permutation.  Then when executing,
you know the value, and you know to use the (None, not None) statement if
given (a=None, b=1) for example.

(This sort of mapping of object to different statements may be needed for
fallback on backends that don't support prepareds, as well.)

As for deferring get_prep_lookup until execution, do we lose any pruning or
other optimization opportunities for normal QuerySet usage if we go that
path?





On Tue, Mar 25, 2014 at 7:22 AM, Anssi Kääriäinen
<[email protected]>wrote:

> On Tuesday, March 25, 2014 2:53:42 PM UTC+2, Curtis Maloney wrote:
>>
>> ps = MyModel.objects.filter(foo__lt=Param('a').prepare()
>>
>> The result is now a callable that accepts one parameter - "a".  To invoke
>> the query:
>>
>> results = ps(a=1000)
>>
>>
>> Clearly it's early days yet - I've written no code.  And akaariai has
>> pointed out already there's some corners cases which won't work well with
>> existing behaviours (e.g. foo=None being silently translated to
>> foo__isnull=True), but it's best to get this idea under wider public
>> scrutiny earlier, rather than later.
>>
>
> I like this style of prepared statements. It is explicit, and
> implementation should be achievable without too much added code complexity.
> I prefer ps.execute(a=1000) personally, but the exact syntax isn't that
> important at this stage.
>
> There will be a couple of corner cases that will be hard to solve. The
> problems are around value preparation during .filter() calls and how
> certain special values are dealt with. Quickly thinking the value
> preparation (basically get_prep_lookup() call) shouldn't be that much of a
> problem - it is currently done during .filter() calls, but it should be
> possible to defer it to execution time.
>
> The foo=None case is something that likely can't be solved. The problem
> here is that foo=None translates to WHERE foo IS NULL, while foo=1
> translates to WHERE foo = 1. These are syntactically different queries, and
> thus single prepared statement can't handle both of these. There are also
> cases where isnull=True/False require different join promotion depending if
> True or False is supplied. These again can't be handled.
>
> I am OK for just documenting these corner cases. They aren't something
> that should happen too often. The implementation for prepared statements is
> relatively straightforward (generate SQL, prepare it once, execute using
> given values), but if the corner case needs to be handled the
> implementation will be more complex, likely so much more complex that
> nobody will implement this feature.
>
> In short: +1 for implementing this with documentation of the corner cases.
>
>  - Anssi
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/3123fda6-d7b3-46d3-82ec-28ed3003e837%40googlegroups.com<https://groups.google.com/d/msgid/django-developers/3123fda6-d7b3-46d3-82ec-28ed3003e837%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAM0i3f4JVV4%2B7fCV4%3Dj_Pn%2BqRAicVNp1YNBKYRFhEVtVQTsZRw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to