From eb4abda8117263f1e1775460b47076ec70e092d4 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 14 Jul 2014 18:28:07 -0400 Subject: [PATCH] - Fixed bug where multi-valued :class:`.Insert` construct would fail to check subsequent values entries beyond the first one given for literal SQL expressions. fixes #3069 --- doc/build/changelog/changelog_09.rst | 9 ++++++ lib/sqlalchemy/sql/compiler.py | 6 ++-- test/sql/test_insert.py | 41 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 862d5fb5ed..c7cacefe84 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,15 @@ :version: 0.9.7 :released: + .. change:: + :tags: bug, sql + :tickets: 3069 + :versions: 1.0.0 + + Fixed bug where multi-valued :class:`.Insert` construct would fail + to check subsequent values entries beyond the first one given + for literal SQL expressions. + .. change:: :tags: bug, sql :tickets: 3123 diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 90a65a7e26..32ecb2eaee 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -2211,10 +2211,12 @@ class SQLCompiler(Compiled): [ ( c, - self._create_crud_bind_param( + (self._create_crud_bind_param( c, row[c.key], name="%s_%d" % (c.key, i + 1) - ) + ) if elements._is_literal(row[c.key]) + else self.process( + row[c.key].self_group(), **kw)) if c.key in row else param ) for (c, param) in values_0 diff --git a/test/sql/test_insert.py b/test/sql/test_insert.py index d9f7b16292..6ee38d6a2d 100644 --- a/test/sql/test_insert.py +++ b/test/sql/test_insert.py @@ -382,6 +382,47 @@ class MultirowTest(_InsertTestBase, fixtures.TablesTest, AssertsCompiledSQL): '(%(id_2)s, %(data_2)s, foobar())', checkparams=checkparams, dialect=postgresql.dialect()) + def test_sql_functions(self): + metadata = MetaData() + table = Table('sometable', metadata, + Column('id', Integer, primary_key=True), + Column('data', String), + Column('foo', Integer)) + + values = [ + {"id": 1, "data": "foo", "foo": func.foob()}, + {"id": 2, "data": "bar", "foo": func.foob()}, + {"id": 3, "data": "bar", "foo": func.bar()}, + {"id": 4, "data": "bar", "foo": 15}, + {"id": 5, "data": "bar", "foo": func.foob()}, + ] + checkparams = { + 'id_0': 1, + 'data_0': 'foo', + + 'id_1': 2, + 'data_1': 'bar', + + 'id_2': 3, + 'data_2': 'bar', + + 'id_3': 4, + 'data_3': 'bar', + 'foo_3': 15, + + 'id_4': 5, + 'data_4': 'bar' + } + + self.assert_compile(table.insert().values(values), + "INSERT INTO sometable (id, data, foo) VALUES " + "(%(id_0)s, %(data_0)s, foob()), " + "(%(id_1)s, %(data_1)s, foob()), " + "(%(id_2)s, %(data_2)s, bar()), " + "(%(id_3)s, %(data_3)s, %(foo_3)s), " + "(%(id_4)s, %(data_4)s, foob())", + checkparams=checkparams, dialect=postgresql.dialect()) + def test_server_default(self): metadata = MetaData() table = Table('sometable', metadata, -- 2.47.3