summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-11-07 21:41:11 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2016-11-07 22:03:16 -0500
commit942c2429c033255979b6a55de836b9b26370673e (patch)
tree6d0d97312a67814cda5d39cf23d09b1360b5884b
parentc4a8afa4c6bf5e76c24e8ed0b5c11acc0c8904e3 (diff)
downloadsqlalchemy-942c2429c033255979b6a55de836b9b26370673e.tar.gz
Put include_table=True for DO UPDATE..WHERE, but not ON CONFLICT
Fixed regression caused by the fix in :ticket:`3807` (version 1.1.0) where we ensured that the tablename was qualified in the WHERE clause of the DO UPDATE portion of PostgreSQL's ON CONFLICT, however you *cannot* put the table name in the WHERE clause in the actual ON CONFLICT itself. This was an incorrect assumption, so that portion of the change in :ticket:`3807` is rolled back. Change-Id: I442d8629496a8e405b54711cfcf487761810ae8a Fixes: #3846 Fixes: #3807
-rw-r--r--doc/build/changelog/changelog_11.rst11
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py1
-rw-r--r--test/dialect/postgresql/test_compiler.py12
-rw-r--r--test/dialect/postgresql/test_on_conflict.py44
4 files changed, 62 insertions, 6 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst
index afa4389a8..d8f785556 100644
--- a/doc/build/changelog/changelog_11.rst
+++ b/doc/build/changelog/changelog_11.rst
@@ -22,6 +22,17 @@
:version: 1.1.4
.. change::
+ :tags: bug, postgresql
+ :tickets: 3846, 3807
+
+ Fixed regression caused by the fix in :ticket:`3807` (version 1.1.0)
+ where we ensured that the tablename was qualified in the WHERE clause
+ of the DO UPDATE portion of PostgreSQL's ON CONFLICT, however you
+ *cannot* put the table name in the WHERE clause in the actual ON
+ CONFLICT itself. This was an incorrect assumption, so that portion
+ of the change in :ticket:`3807` is rolled back.
+
+ .. change::
:tags: bug, orm
:tickets: 3845
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index 9898e4ba4..4c82325f5 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -1433,6 +1433,7 @@ class PGCompiler(compiler.SQLCompiler):
target_text += ' WHERE %s' % \
self.process(
clause.inferred_target_whereclause,
+ include_table=False,
use_schema=False
)
else:
diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py
index 52dd699fc..3e7f584bf 100644
--- a/test/dialect/postgresql/test_compiler.py
+++ b/test/dialect/postgresql/test_compiler.py
@@ -1205,7 +1205,7 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(i,
'INSERT INTO mytable (name) VALUES '
"(%(name)s) ON CONFLICT (name) "
- "WHERE mytable.name > %(name_1)s "
+ "WHERE name > %(name_1)s "
'DO UPDATE SET name = excluded.name')
def test_do_update_index_elements_where_target_multivalues(self):
@@ -1223,7 +1223,7 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
"INSERT INTO mytable (name) "
"VALUES (%(name_m0)s), (%(name_m1)s), (%(name_m2)s) "
"ON CONFLICT (name) "
- "WHERE mytable.name > %(name_1)s "
+ "WHERE name > %(name_1)s "
"DO UPDATE SET name = excluded.name",
checkparams={
'name_1': 'm', 'name_m0': 'foo',
@@ -1246,7 +1246,7 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(i,
'INSERT INTO mytable (name) VALUES '
"(%(name)s) ON CONFLICT (name) "
- "WHERE mytable.name > %(name_1)s "
+ "WHERE name > %(name_1)s "
'DO UPDATE SET name = excluded.name')
def test_do_update_unnamed_exclude_constraint_target(self):
@@ -1259,7 +1259,7 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(i,
'INSERT INTO mytable (name) VALUES '
"(%(name)s) ON CONFLICT (name, description) "
- "WHERE mytable.description != %(description_1)s "
+ "WHERE description != %(description_1)s "
'DO UPDATE SET name = excluded.name')
def test_do_update_add_whereclause(self):
@@ -1275,7 +1275,7 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(i,
'INSERT INTO mytable (name) VALUES '
"(%(name)s) ON CONFLICT (name, description) "
- "WHERE mytable.description != %(description_1)s "
+ "WHERE description != %(description_1)s "
'DO UPDATE SET name = excluded.name '
"WHERE mytable.name != %(name_1)s "
"AND mytable.description != %(description_2)s")
@@ -1292,7 +1292,7 @@ class InsertOnConflictTest(fixtures.TestBase, AssertsCompiledSQL):
self.assert_compile(i,
'INSERT INTO mytable (name) VALUES '
"(%(name)s) ON CONFLICT (name, description) "
- "WHERE mytable.description != %(description_1)s "
+ "WHERE description != %(description_1)s "
'DO UPDATE SET name = excluded.name '
"WHERE mytable.name != excluded.name")
diff --git a/test/dialect/postgresql/test_on_conflict.py b/test/dialect/postgresql/test_on_conflict.py
index 154d3fe58..9cfe4432a 100644
--- a/test/dialect/postgresql/test_on_conflict.py
+++ b/test/dialect/postgresql/test_on_conflict.py
@@ -28,6 +28,12 @@ class OnConflictTest(fixtures.TablesTest):
Column('login_email', String(50)),
Column('lets_index_this', String(50))
)
+ cls.unique_partial_index = schema.Index(
+ 'idx_unique_partial_name',
+ users_xtra.c.name, users_xtra.c.lets_index_this,
+ unique=True,
+ postgresql_where=users_xtra.c.lets_index_this == 'unique_name')
+
cls.unique_constraint = schema.UniqueConstraint(
users_xtra.c.login_email, name='uq_login_email')
cls.bogus_index = schema.Index(
@@ -405,6 +411,44 @@ class OnConflictTest(fixtures.TablesTest):
lets_index_this='bogus')
)
+ def test_on_conflict_do_update_exotic_targets_six(self):
+ users = self.tables.users_xtra
+
+ with testing.db.connect() as conn:
+ conn.execute(
+ insert(users),
+ dict(
+ id=1, name='name1',
+ login_email='mail1@gmail.com',
+ lets_index_this='unique_name'
+ )
+ )
+
+ i = insert(users)
+ i = i.on_conflict_do_update(
+ index_elements=self.unique_partial_index.columns,
+ index_where=self.unique_partial_index.dialect_options
+ ['postgresql']['where'],
+ set_=dict(
+ name=i.excluded.name,
+ login_email=i.excluded.login_email),
+ )
+
+ conn.execute(
+ i,
+ [
+ dict(name='name1', login_email='mail2@gmail.com',
+ lets_index_this='unique_name'),
+ ]
+ )
+
+ eq_(
+ conn.execute(users.select()).fetchall(),
+ [
+ (1, 'name1', 'mail2@gmail.com', 'unique_name'),
+ ]
+ )
+
def test_on_conflict_do_update_no_row_actually_affected(self):
users = self.tables.users_xtra