From: Mike Bayer Date: Sat, 14 Nov 2020 00:35:25 +0000 (-0500) Subject: don't check standard_conforming_strings less than server version 8.2 X-Git-Tag: rel_1_4_0b2~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=415ddce1e3b429bdc1180c5b5f7750a08d226525;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git don't check standard_conforming_strings less than server version 8.2 Fixed a small regression where the query for "show standard_conforming_strings" upon initialization would be emitted even if the server version info were detected as less than version 8.2, previously it would only occur for server version 8.2 or greater. The query fails on Amazon Redshift which reports a PG server version older than this value. Fixes: #5698 Change-Id: Ib27ce4b05106d986a618597e4cf253504f981bf1 --- diff --git a/doc/build/changelog/unreleased_14/5698.rst b/doc/build/changelog/unreleased_14/5698.rst new file mode 100644 index 0000000000..a011d8bc44 --- /dev/null +++ b/doc/build/changelog/unreleased_14/5698.rst @@ -0,0 +1,10 @@ +.. change:: + :tags: bug, postgresql + :tickets: 5698 + + Fixed a small regression where the query for "show + standard_conforming_strings" upon initialization would be emitted even if + the server version info were detected as less than version 8.2, previously + it would only occur for server version 8.2 or greater. The query fails on + Amazon Redshift which reports a PG server version older than this value. + diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index bf257ab3fd..d738393e78 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -2922,12 +2922,15 @@ class PGDialect(default.DefaultDialect): # http://www.postgresql.org/docs/9.3/static/release-9-2.html#AEN116689 self.supports_smallserial = self.server_version_info >= (9, 2) - std_string = connection.exec_driver_sql( - "show standard_conforming_strings" - ).scalar() - self._backslash_escapes = ( - self.server_version_info < (8, 2) or std_string == "off" - ) + if self.server_version_info < (8, 2): + self._backslash_escapes = False + else: + # ensure this query is not emitted on server version < 8.2 + # as it will fail + std_string = connection.exec_driver_sql( + "show standard_conforming_strings" + ).scalar() + self._backslash_escapes = std_string == "off" self._supports_create_index_concurrently = ( self.server_version_info >= (8, 2) diff --git a/test/dialect/postgresql/test_dialect.py b/test/dialect/postgresql/test_dialect.py index d1e9c2e6de..bfdd148454 100644 --- a/test/dialect/postgresql/test_dialect.py +++ b/test/dialect/postgresql/test_dialect.py @@ -103,6 +103,12 @@ class DialectTest(fixtures.TestBase): "(Red Hat 4.8.5-11), 64-bit", (10,), ), + ( + "PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc " + "(GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), " + "Redshift 1.0.12103", + (8, 0, 2), + ), ]: eq_(dialect._get_server_version_info(mock_conn(string)), version) @@ -764,6 +770,38 @@ class MiscBackendTest( ".".join(str(x) for x in v) ) + @testing.combinations( + ((8, 1), False, False), + ((8, 1), None, False), + ((11, 5), True, False), + ((11, 5), False, True), + ) + def test_backslash_escapes_detection( + self, version, explicit_setting, expected + ): + engine = engines.testing_engine() + + def _server_version(conn): + return version + + if explicit_setting is not None: + + @event.listens_for(engine, "connect", insert=True) + @event.listens_for(engine, "first_connect", insert=True) + def connect(dbapi_connection, connection_record): + cursor = dbapi_connection.cursor() + cursor.execute( + "SET SESSION standard_conforming_strings = %s" + % ("off" if not explicit_setting else "on") + ) + dbapi_connection.commit() + + with mock.patch.object( + engine.dialect, "_get_server_version_info", _server_version + ): + with engine.connect(): + eq_(engine.dialect._backslash_escapes, expected) + def test_readonly_flag_connection(self): with testing.db.connect() as conn: # asyncpg requires serializable for readonly..