summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_13/4923.rst17
-rw-r--r--lib/sqlalchemy/dialects/mssql/base.py4
-rw-r--r--test/dialect/mssql/test_reflection.py12
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()