Calling filter() with criterion==None crashes when _aliases_tail exists

Issue #1025 resolved
Former user created an issue

I apologize for not following the guidelines but I am not knowledgeable enough to reproduce this in a standalone program.

When using a join on a self-referential table (with aliased=true), a select() call ended in a crash.

I managed to fix it but have no confidence this is the correct fix.

My fix was in sqlalchemy/orm/query.py line 529 (in filter() ).

Existing code:[BR] if self._aliases_tail:[BR] criterion = self._aliases_tail.adapt_clause(criterion)

My fix: change the condition to ensure criterion exists: [BR] if self._aliases_tail and criterion:

Comments (3)

  1. Mike Bayer repo owner
    from sqlalchemy import *
    from sqlalchemy.orm import *
    
    m = MetaData(create_engine('sqlite://'))
    t = Table('foo', m, Column('x', Integer, primary_key=True), Column('y', String(50)))
    class Foo(object):
        pass
    mapper(Foo, t)
    
    sess = create_session()
    
    q = sess.query(Foo)._from_self()
    assert bool(q._aliases_tail)
    
    print q.filter(Foo.y==None).statement
    
  2. Former user Account Deleted
    • changed status to open
    • removed status

    Your code helped me reproduce it. The crash occurs, when the last line is not as in your example but

    print q.filter(None).statement
    

    Now, I don't know if it is legal to call filter() with an argument of None, but this was called from other Sqlalchemy code and the decision to send the None could not be traced back to my code. Here is the actual full stack trace:

    File '/home/moshe/top/webapp/rma/rma/controllers/list.py', line 216 in list_sources
      c.paginator = paginate.Page(myquery, page_nr = int(c.page_nr))
    File '/home/moshe/top/webapp/rma/rma/lib/paginate.py', line 131 in __init__
      self.items = self.collection[self.first_item:self.last_item+1](self.first_item:self.last_item+1)
    File '/usr/local/lib/python2.4/site-packages/WebHelpers-0.3.2-py2.4.egg/webhelpers/pagination/orm.py', line 75 in __getitem__
      results = self(limit=limit, offset=offset)
    File '/usr/local/lib/python2.4/site-packages/WebHelpers-0.3.2-py2.4.egg/webhelpers/util.py', line 42 in __call__
      return self.fn(*(self.args + args), **d)
    File '/home/moshe/top/webapp/rma/sqlalchemy/util.py', line 1176 in func_with_warning
      return func(*args, **kwargs)
    File '/home/moshe/top/webapp/rma/sqlalchemy/orm/query.py', line 1336 in select
      return self._build_select(arg, **kwargs).all()
    File '/home/moshe/top/webapp/rma/sqlalchemy/orm/query.py', line 1318 in _build_select
      return self.filter(arg)._legacy_select_kwargs(**kwargs)
    File '/home/moshe/top/webapp/rma/sqlalchemy/orm/query.py', line 524 in filter
      criterion = self._aliases_tail.adapt_clause(criterion)
    File '/home/moshe/top/webapp/rma/sqlalchemy/orm/util.py', line 171 in adapt_clause
      return self.adapter.traverse(clause, clone=True)
    File '/home/moshe/top/webapp/rma/sqlalchemy/sql/util.py', line 234 in traverse
      return visitors.ClauseVisitor.traverse(self, obj, clone=True)
    File '/home/moshe/top/webapp/rma/sqlalchemy/sql/visitors.py', line 73 in traverse
      return self._cloned_traversal(obj)
    File '/home/moshe/top/webapp/rma/sqlalchemy/sql/visitors.py', line 108 in _cloned_traversal
      return self._cloned_traversal_impl(obj, util.Set(stop_on), {}, _clone_toplevel=True)
    File '/home/moshe/top/webapp/rma/sqlalchemy/sql/visitors.py', line 115 in _cloned_traversal_impl
      elem = self._clone_element(elem, stop_on, cloned)
    File '/home/moshe/top/webapp/rma/sqlalchemy/sql/visitors.py', line 101 in _clone_element
      cloned[elem](elem) = elem._clone()
    AttributeError: 'NoneType' object has no attribute '_clone'
    
  3. Log in to comment