From 986e82700e2ddd82a74c4b5a48fa49d4fa89bdec Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 6 Sep 2007 16:37:37 +0000 Subject: [PATCH] - column defaults and onupdates, executing inline, will add parenthesis for subqueries and other parenthesis-requiring expressions --- CHANGES | 3 +++ lib/sqlalchemy/sql/compiler.py | 4 ++-- test/sql/select.py | 26 ++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 9fa7ad5988..6282b9cdee 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,9 @@ CHANGES - Fixed reflection of the empty string for mysql enums. +- column defaults and onupdates, executing inline, will add parenthesis + for subqueries and other parenthesis-requiring expressions + 0.4.0beta5 ---------- diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index f1d0e32949..2b4786cb25 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -678,7 +678,7 @@ class DefaultCompiler(engine.Compiled, visitors.ClauseVisitor): self.prefetch.add(c) elif isinstance(c.default, schema.ColumnDefault): if isinstance(c.default.arg, sql.ClauseElement): - values.append((c, self.process(c.default.arg))) + values.append((c, self.process(c.default.arg.self_group()))) self.postfetch.add(c) else: values.append((c, create_bind_param(c, None))) @@ -693,7 +693,7 @@ class DefaultCompiler(engine.Compiled, visitors.ClauseVisitor): elif self.isupdate: if isinstance(c.onupdate, schema.ColumnDefault): if isinstance(c.onupdate.arg, sql.ClauseElement): - values.append((c, self.process(c.onupdate.arg))) + values.append((c, self.process(c.onupdate.arg.self_group()))) self.postfetch.add(c) else: values.append((c, create_bind_param(c, None))) diff --git a/test/sql/select.py b/test/sql/select.py index edca33bc0b..f0af7e238a 100644 --- a/test/sql/select.py +++ b/test/sql/select.py @@ -1187,7 +1187,33 @@ class CRUDTest(SQLCompileTest): s = select([table2.c.othername], table2.c.otherid == table1.c.myid) u = table1.delete(table1.c.name==s) self.assert_compile(u, "DELETE FROM mytable WHERE mytable.name = (SELECT myothertable.othername FROM myothertable WHERE myothertable.otherid = mytable.myid)") + +class InlineDefaultTest(SQLCompileTest): + def test_insert(self): + m = MetaData() + foo = Table('foo', m, + Column('id', Integer)) + t = Table('test', m, + Column('col1', Integer, default=func.foo(1)), + Column('col2', Integer, default=select([func.coalesce(func.max(foo.c.id))])), + ) + + self.assert_compile(t.insert(inline=True, values={}), "INSERT INTO test (col1, col2) VALUES (foo(:foo), (SELECT coalesce(max(foo.id)) FROM foo))") + + def test_update(self): + m = MetaData() + foo = Table('foo', m, + Column('id', Integer)) + + t = Table('test', m, + Column('col1', Integer, onupdate=func.foo(1)), + Column('col2', Integer, onupdate=select([func.coalesce(func.max(foo.c.id))])), + Column('col3', String(30)) + ) + + self.assert_compile(t.update(inline=True, values={'col3':'foo'}), "UPDATE test SET col1=foo(:foo), col2=(SELECT coalesce(max(foo.id)) FROM foo), col3=:col3") + class SchemaTest(SQLCompileTest): def testselect(self): # these tests will fail with the MS-SQL compiler since it will alias schema-qualified tables -- 2.47.3