From 074ecc43761f1af1de0d29f077e93f641c73c61e Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 8 May 2010 16:25:30 -0400 Subject: [PATCH] - expr.in_() now accepts a text() construct as the argument. Grouping parenthesis are added automatically, i.e. usage is like `col.in_(text("select id from table"))`. [ticket:1793] --- CHANGES | 5 +++++ lib/sqlalchemy/sql/expression.py | 11 +++++++++-- test/sql/test_compiler.py | 9 +++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index e2d3303b1f..39326b491f 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,11 @@ CHANGES instance if that instance is "pending". [ticket:1789] - sql + - expr.in_() now accepts a text() construct as the argument. + Grouping parenthesis are added automatically, i.e. usage + is like `col.in_(text("select id from table"))`. + [ticket:1793] + - Fixed bug that prevented implicit RETURNING from functioning properly with composite primary key that contained zeroes. [ticket:1778] diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 6dd9d8baf3..440c118333 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -1522,9 +1522,10 @@ class _CompareMixin(ColumnOperators): # column selectable that does not export itself as a FROM clause return self.__compare( op, seq_or_selectable.as_scalar(), negate=negate_op) - elif isinstance(seq_or_selectable, Selectable): + elif isinstance(seq_or_selectable, (Selectable, _TextClause)): return self.__compare( op, seq_or_selectable, negate=negate_op) - + + # Handle non selectable arguments as sequences args = [] for o in seq_or_selectable: @@ -2358,6 +2359,12 @@ class _TextClause(Executable, ClauseElement): else: return None + def self_group(self, against=None): + if against is operators.in_op: + return _Grouping(self) + else: + return self + def _copy_internals(self, clone=_clone): self.bindparams = dict((b.key, clone(b)) for b in self.bindparams.values()) diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index 9490aef378..9e85d2c744 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -1589,6 +1589,15 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A self.assert_compile(~table1.c.myid.in_(select([table2.c.otherid])), "mytable.myid NOT IN (SELECT myothertable.otherid FROM myothertable)") + # text + self.assert_compile( + table1.c.myid.in_( + text("SELECT myothertable.otherid FROM myothertable") + ), + "mytable.myid IN (SELECT myothertable.otherid " + "FROM myothertable)" + ) + # test empty in clause self.assert_compile(table1.c.myid.in_([]), "mytable.myid != mytable.myid") -- 2.47.2