From: Mike Bayer Date: Tue, 1 Apr 2014 17:03:52 +0000 (-0400) Subject: - Fixes to the newly enhanced boolean coercion in :ticket:`2804` where X-Git-Tag: rel_0_9_5~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2e5c8913a8e15e649322c0907199361df9698153;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixes to the newly enhanced boolean coercion in :ticket:`2804` where the new rules for "where" and "having" woudn't take effect for the "whereclause" and "having" kw arguments of the :func:`.select` construct, which is also what :class:`.Query` uses so wasn't working in the ORM either. fixes #3013 re: #2804 --- diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 6674a59a0d..fab3224168 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,16 @@ .. changelog:: :version: 0.9.5 + .. change:: + :tags: bug, orm, sql + :tickets: 3013 + + Fixes to the newly enhanced boolean coercion in :ticket:`2804` where + the new rules for "where" and "having" woudn't take effect for the + "whereclause" and "having" kw arguments of the :func:`.select` construct, + which is also what :class:`.Query` uses so wasn't working in the + ORM either. + .. change:: :tags: feature, sql :tickets: 2990 diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index afcbf3500c..827fdb5bec 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1244,6 +1244,7 @@ class Query(object): else: self._criterion = criterion + def filter_by(self, **kwargs): """apply the given filtering criterion to a copy of this :class:`.Query`, using keyword expressions. @@ -2886,7 +2887,6 @@ class Query(object): order_by=context.order_by, **self._select_args ) - statement._for_update_arg = context._for_update_arg for hint in self._with_hints: diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py index f64a70ec8d..2ce1644457 100644 --- a/lib/sqlalchemy/sql/selectable.py +++ b/lib/sqlalchemy/sql/selectable.py @@ -2191,12 +2191,12 @@ class Select(HasPrefixes, GenerativeSelect): self._raw_columns = [] if whereclause is not None: - self._whereclause = _literal_as_text(whereclause) + self._whereclause = and_(True_._singleton(), whereclause) else: self._whereclause = None if having is not None: - self._having = _literal_as_text(having) + self._having = and_(True_._singleton(), having) else: self._having = None diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 312a8bc72a..3b483b7c05 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -1,7 +1,7 @@ from sqlalchemy.sql import operators from sqlalchemy import MetaData, null, exists, text, union, literal, \ literal_column, func, between, Unicode, desc, and_, bindparam, \ - select, distinct, or_, collate, insert, Integer, String + select, distinct, or_, collate, insert, Integer, String, Boolean from sqlalchemy import inspect from sqlalchemy import exc as sa_exc, util from sqlalchemy.sql import compiler, table, column @@ -2550,3 +2550,57 @@ class ExecutionOptionsTest(QueryTest): q1.all() +class BooleanEvalTest(fixtures.TestBase, testing.AssertsCompiledSQL): + """test standalone booleans being wrapped in an AsBoolean, as well + as true/false compilation.""" + + def _dialect(self, native_boolean): + d = default.DefaultDialect() + d.supports_native_boolean = native_boolean + return d + + def test_one(self): + s = Session() + c = column('x', Boolean) + self.assert_compile( + s.query(c).filter(c), + "SELECT x AS x WHERE x", + dialect=self._dialect(True) + ) + + def test_two(self): + s = Session() + c = column('x', Boolean) + self.assert_compile( + s.query(c).filter(c), + "SELECT x AS x WHERE x = 1", + dialect=self._dialect(False) + ) + + def test_three(self): + s = Session() + c = column('x', Boolean) + self.assert_compile( + s.query(c).filter(~c), + "SELECT x AS x WHERE x = 0", + dialect=self._dialect(False) + ) + + def test_four(self): + s = Session() + c = column('x', Boolean) + self.assert_compile( + s.query(c).filter(~c), + "SELECT x AS x WHERE NOT x", + dialect=self._dialect(True) + ) + + def test_five(self): + s = Session() + c = column('x', Boolean) + self.assert_compile( + s.query(c).having(c), + "SELECT x AS x HAVING x = 1", + dialect=self._dialect(False) + ) + diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index 31af7d2730..63475fcefd 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -439,7 +439,7 @@ class BooleanEvalTest(fixtures.TestBase, testing.AssertsCompiledSQL): dialect=self._dialect(True) ) - def test_two(self): + def test_two_a(self): c = column('x', Boolean) self.assert_compile( select([c]).where(c), @@ -447,7 +447,15 @@ class BooleanEvalTest(fixtures.TestBase, testing.AssertsCompiledSQL): dialect=self._dialect(False) ) - def test_three(self): + def test_two_b(self): + c = column('x', Boolean) + self.assert_compile( + select([c], whereclause=c), + "SELECT x WHERE x = 1", + dialect=self._dialect(False) + ) + + def test_three_a(self): c = column('x', Boolean) self.assert_compile( select([c]).where(~c), @@ -455,6 +463,14 @@ class BooleanEvalTest(fixtures.TestBase, testing.AssertsCompiledSQL): dialect=self._dialect(False) ) + def test_three_b(self): + c = column('x', Boolean) + self.assert_compile( + select([c], whereclause=~c), + "SELECT x WHERE x = 0", + dialect=self._dialect(False) + ) + def test_four(self): c = column('x', Boolean) self.assert_compile( @@ -463,7 +479,7 @@ class BooleanEvalTest(fixtures.TestBase, testing.AssertsCompiledSQL): dialect=self._dialect(True) ) - def test_five(self): + def test_five_a(self): c = column('x', Boolean) self.assert_compile( select([c]).having(c), @@ -471,6 +487,14 @@ class BooleanEvalTest(fixtures.TestBase, testing.AssertsCompiledSQL): dialect=self._dialect(False) ) + def test_five_b(self): + c = column('x', Boolean) + self.assert_compile( + select([c], having=c), + "SELECT x HAVING x = 1", + dialect=self._dialect(False) + ) + def test_six(self): self.assert_compile( or_(false(), true()),