On May 31, 2013, at 11:59 AM, Claudio Freire <klaussfre...@gmail.com> wrote:

> On Fri, May 31, 2013 at 12:46 PM, Michael Bayer
> <mike...@zzzcomputing.com> wrote:
>> this hash works for backends that can render LIMIT as a bound parameter.  It 
>> will *not* work for SQL server which cannot render LIMIT as a bound 
>> parameter.
>> 
>> If the hash is determined at the level of Query, we *do not* know whether or 
>> not the backend supports LIMIT as a bound parameter, unless we ask it.
>> 
>> So OK, we make more rules - ask the backend if LIMIT can be hashed as a 
>> bound parameter.
>> 
>> But then what if a particular backend has more restrictive "bound parameter" 
>> rules than Query is aware of?   What if we throw the Firebird backend at it, 
>> and all the sudden Firebird has some quirk where you can't put a bound 
>> parameter inside of a CASE statement inside of the columns clause?  How will 
>> Query know that suddenly another deeply embedded bound parameter can no 
>> longer be considered hashable as a bound parameter, and must be hashed as a 
>> literal value ?
> 
> 
> I see.
> 
> The solution is to create a new object type, QueryKey, that contains
> both the Query and the Dialect, and builds its hash either by invoking
> Query.hash(dialect), or by visiting it somehow.

> The underlying problem is that Query cannot decide the hash by itself.
> Then it shouldn't try to. It should only support building a hash with
> respect to a specific dialect. The only thing required of it is that
> the hash be stable within cacheable queries of that dialect, no need
> to ponder about hasheability across all dialects.

right.  which becomes - you have to entirely build out the select() statement 
*and* and run it through a system that looks very much like the compiler - 
every time!       
in order to find edge cases like, "we can't use a bound parameter inside of a 
CASE() inside the columns clause" essentially means a process that is very 
close to the complexity as the full compilation has to proceed.     All 
dialects need to be enhanced in order to support this whole new system, or if 
we piggyback it onto the existing compilation process, then we're not saving 
anything at all - and we've already lost the savings of skipping 
Query._compile_context().

OTOH, if we keep this as "bake()", forego Query producing hash keys, and just 
make it so that "bake()" can accept a string:

        q = query(Entity).filter_by(foo=bar).limit(5).bake("my_query")

then we can just have Query look up the _compile_context() result for 
"my_query", which takes you right to your dialect-compiled select() constructs 
which expose which parameters are "bound", and then you get all the savings.   
This is just a few lines different to the existing bake() recipe.







-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to