From e39b98ca7ba8f791f5a359132adf3c9ff8e715c1 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 1 Feb 2009 18:20:20 +0000 Subject: [PATCH] - Fixed missing _label attribute on Function object, others when used in a select() with use_labels (such as when used in an ORM column_property()). [ticket:1302] --- CHANGES | 4 ++++ lib/sqlalchemy/orm/query.py | 7 ++++++- lib/sqlalchemy/sql/expression.py | 3 ++- test/sql/functions.py | 6 +++++- test/sql/select.py | 24 ++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 5753d30f60..bc3ce8df60 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,10 @@ CHANGES determined. - sql + - Fixed missing _label attribute on Function object, others + when used in a select() with use_labels (such as when used + in an ORM column_property()). [ticket:1302] + - the __selectable__() interface has been replaced entirely by __clause_element__(). diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 87019521be..50f51355f4 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -2006,7 +2006,12 @@ class _ColumnEntity(_QueryEntity): if not isinstance(column, sql.ColumnElement): raise sa_exc.InvalidRequestError("Invalid column expression '%r'" % column) - if not hasattr(column, '_label'): + # if the Column is unnamed, give it a + # label() so that mutable column expressions + # can be located in the result even + # if the expression's identity has been changed + # due to adaption + if not column._label: column = column.label(None) query._entities.append(self) diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 1eada57dc7..f790555bc9 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -1566,7 +1566,8 @@ class ColumnElement(ClauseElement, _CompareMixin): primary_key = False foreign_keys = [] quote = None - + _label = None + @property def _select_iterable(self): return (self, ) diff --git a/test/sql/functions.py b/test/sql/functions.py index ac9b7e3292..1519575036 100644 --- a/test/sql/functions.py +++ b/test/sql/functions.py @@ -37,7 +37,11 @@ class CompileTest(TestBase, AssertsCompiledSQL): GenericFunction.__init__(self, args=[arg], **kwargs) self.assert_compile(fake_func('foo'), "fake_func(%s)" % bindtemplate % {'name':'param_1', 'position':1}, dialect=dialect) - + + def test_use_labels(self): + self.assert_compile(select([func.foo()], use_labels=True), + "SELECT foo() AS foo_1" + ) def test_underscores(self): self.assert_compile(func.if_(), "if()") diff --git a/test/sql/select.py b/test/sql/select.py index 2b721ba102..aeb53bf195 100644 --- a/test/sql/select.py +++ b/test/sql/select.py @@ -131,6 +131,30 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A select([ClauseList(column('a'), column('b'))]).select_from('sometable'), 'SELECT a, b FROM sometable' ) + + def test_use_labels(self): + self.assert_compile( + select([table1.c.myid==5], use_labels=True), + "SELECT mytable.myid = :myid_1 AS anon_1 FROM mytable" + ) + + self.assert_compile( + select([func.foo()], use_labels=True), + "SELECT foo() AS foo_1" + ) + + self.assert_compile( + select([not_(True)], use_labels=True), + "SELECT NOT :param_1" # TODO: should this make an anon label ?? + ) + + self.assert_compile( + select([cast("data", sqlite.SLInteger)], use_labels=True), # this will work with plain Integer in 0.6 + "SELECT CAST(:param_1 AS INTEGER) AS anon_1" + ) + + + def test_nested_uselabels(self): """test nested anonymous label generation. this essentially tests the ANONYMOUS_LABEL regex. -- 2.47.2