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

> On Fri, May 31, 2013 at 11:29 AM, Michael Bayer
> <mike...@zzzcomputing.com> wrote:
>> 
>> 
>> On Friday, May 31, 2013 10:18:41 AM UTC-4, Klauss wrote:
>>> 
>>> On Thu, May 30, 2013 at 7:04 PM, Michael Bayer <mik...@zzzcomputing.com>
>>> wrote:
>>>> 
>>>> The hashing thing really has to start as a core concept first.   It's a
>>>> big job but would be very helpful for caching scenarios and would allow us
>>>> to build this feature on Query without too much difficulty.  The nice thing
>>>> about "unhashable" is that simple queries will be hashable, but as soon as
>>>> complexity increases you'd start seeing unhashables come in, preventing us
>>>> from caching something that isn't actually easy to cache.
>>> 
>>> AFAIK only py3 has support for making user classes unhashable.
>> 
>> 
>> I'm not considering using `__hash__()` for this, I'd rather keep it as a
>> special method for this purpose.
>> 
>> But after sleeping on it, I'm still pretty skeptical, because it's actually
>> pretty difficult to determine what parts of a statement will remain
>> "constant" across backends.
> 
> It's not necessary to be constant across backends. All of
> compiled_cache machinery already appends the dialect so only
> "semantically constant" would be required.

if I have a query:

        q = s.query(X).filter_by(foo='bar').limit(3)

say we have it generate a hash:

X._hash = x_hash
X.foo._hash = foo_hash
operator.eq._hash = eq_hash
bindparam('foo')._hash = bp_foo_hash
bindparam('limit')._hash = limit_hash

the hash is:   hash(x_hash, foo_hash, eq_hash, bp_foo_hash, limit_hash)

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 ?

The only way that can work generically, is if Query *never* bypasses literals.  
it means the above query would have to be hashed like this:


X._hash = x_hash
X.foo._hash = foo_hash
operator.eq._hash = eq_hash
'bar'.hash =  bar_hash
3._hash = 3_hash

the hash is:   hash(x_hash, foo_hash, eq_hash, bar_hash, 3_hash)

which means the only way you can get parameter hashing is if you write your 
Query like this:

        q = 
s.query(X).filter_by(foo=bindparam('foo')).limit(bindparam('limit')).params(foo='bar',
 limit=3)

which means the behavior isn't very transparent at all, and if we are leaning 
on the user to explicitly define that things are hashable, we might as well 
stick with bake() or something klunky like that which nobody will ever use.    
Exposing a confusing and awkward conditional performance API to the userbase is 
not good enough to warrant changing the internals.  People are confused enough 
by yield_per().














> 
> 
>> If you have a select like, "SELECT x + ? FROM q", where ? is a bound
>> parameter, that statement won't run on some backends which don't allow bound
>> parameters in the columns clause.   So a select() object "select([x + 3])",
>> we would theoretically have to include the number "3" as part of its cache
>> key...but based on where the "3" is present.   Similar things happen when
>> you say select().limit(x) - LIMIT can usually be rendered via bound
>> parameter, but not on backends like Sybase or SQL Server where it is
>> rendered in the TOP clause that can't be bound.
> 
> So yeah, you don't have to care about that. It's taken care at other
> levels. Hashing should be concerned with semantics only.
> 
> -- 
> 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.
> 
> 

-- 
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