diff options
| -rw-r--r-- | doc/build/changelog/unreleased_13/4923.rst | 17 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/mssql/base.py | 4 | ||||
| -rw-r--r-- | test/dialect/mssql/test_reflection.py | 12 |
3 files changed, 32 insertions, 1 deletions
diff --git a/doc/build/changelog/unreleased_13/4923.rst b/doc/build/changelog/unreleased_13/4923.rst new file mode 100644 index 000000000..e5318f51f --- /dev/null +++ b/doc/build/changelog/unreleased_13/4923.rst @@ -0,0 +1,17 @@ +.. change:: + :tags: bug, mssql + :tickets: 4923 + + Fixed an issue in the :meth:`.Engine.table_names` method where it would + feed the dialect's default schema name back into the dialect level table + function, which in the case of SQL Server would interpret it as a + dot-tokenized schema name as viewed by the mssql dialect, which would + cause the method to fail in the case where the database username actually + had a dot inside of it. In 1.3, this method is still used by the + :meth:`.MetaData.reflect` function so is a prominent codepath. In 1.4, + which is the current master development branch, this issue doesn't exist, + both because :meth:`.MetaData.reflect` isn't using this method nor does the + method pass the default schema name explicitly. The fix nonetheless + guards against the default server name value returned by the dialect from + being interpreted as dot-tokenized name under any circumstances by + wrapping it in quoted_name(). diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 2f24bb3f4..6c7b732ce 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -2428,7 +2428,9 @@ class MSDialect(default.DefaultDialect): query = sql.text("SELECT schema_name()") default_schema_name = connection.scalar(query) if default_schema_name is not None: - return util.text_type(default_schema_name) + # guard against the case where the default_schema_name is being + # fed back into a table reflection function. + return quoted_name(default_schema_name, quote=True) else: return self.schema_name diff --git a/test/dialect/mssql/test_reflection.py b/test/dialect/mssql/test_reflection.py index 24c4a6455..794588dce 100644 --- a/test/dialect/mssql/test_reflection.py +++ b/test/dialect/mssql/test_reflection.py @@ -421,6 +421,18 @@ class ReflectHugeViewTest(fixtures.TestBase): class OwnerPlusDBTest(fixtures.TestBase): + def test_default_schema_name_not_interpreted_as_tokenized(self): + dialect = mssql.dialect() + dialect.server_version_info = base.MS_2014_VERSION + + mock_connection = mock.Mock(scalar=lambda sql: "Jonah.The.Whale") + schema_name = dialect._get_default_schema_name(mock_connection) + eq_(schema_name, "Jonah.The.Whale") + eq_( + base._owner_plus_db(dialect, schema_name), + (None, "Jonah.The.Whale"), + ) + def test_owner_database_pairs_dont_use_for_same_db(self): dialect = mssql.dialect() |
