From: Gord Thompson Date: Sat, 18 Jul 2020 00:06:41 +0000 (-0600) Subject: Fix mssql dialect escaping object names containing ']' X-Git-Tag: rel_1_3_19~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1fc759d3b17eafb612f072cf64d4f13a568e5281;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Fix mssql dialect escaping object names containing ']' Fixes: #5467 Change-Id: I054ec219717ba62847a9daf1214e215dd6b70633 (cherry picked from commit 547e959157f841f4f6d1e405ceed14755fcbd0bd) --- diff --git a/doc/build/changelog/unreleased_13/5467.rst b/doc/build/changelog/unreleased_13/5467.rst new file mode 100644 index 0000000000..241bdb7ff7 --- /dev/null +++ b/doc/build/changelog/unreleased_13/5467.rst @@ -0,0 +1,6 @@ +.. change:: + :tags: bug, mssql, sql + :tickets: 5467 + + Fixed bug where the mssql dialect incorrectly escaped object names that + contained ']' character(s). diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 87959856ff..53a8fc8b5e 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -2142,7 +2142,10 @@ class MSIdentifierPreparer(compiler.IdentifierPreparer): ) def _escape_identifier(self, value): - return value + return value.replace("]", "]]") + + def _unescape_identifier(self, value): + return value.replace("]]", "]") def quote_schema(self, schema, force=None): """Prepare a quoted table and schema name.""" diff --git a/test/dialect/mssql/test_compiler.py b/test/dialect/mssql/test_compiler.py index 3656ed9b30..34fd20076d 100644 --- a/test/dialect/mssql/test_compiler.py +++ b/test/dialect/mssql/test_compiler.py @@ -41,10 +41,23 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): self.assert_compile(sql.false(), "0") self.assert_compile(sql.true(), "1") - def test_select(self): - t = table("sometable", column("somecolumn")) + @testing.combinations( + ("plain", "sometable", "sometable"), + ("matched_square_brackets", "colo[u]r", "[colo[u]]r]"), + ("unmatched_left_square_bracket", "colo[ur", "[colo[ur]"), + ("unmatched_right_square_bracket", "colou]r", "[colou]]r]"), + ("double quotes", 'Edwin "Buzz" Aldrin', '[Edwin "Buzz" Aldrin]'), + ("dash", "Dash-8", "[Dash-8]"), + ("slash", "tl/dr", "[tl/dr]"), + ("space", "Red Deer", "[Red Deer]"), + ("question mark", "OK?", "[OK?]"), + ("percent", "GST%", "[GST%]"), + id_="iaa", + ) + def test_identifier_rendering(self, table_name, rendered_name): + t = table(table_name, column("somecolumn")) self.assert_compile( - t.select(), "SELECT sometable.somecolumn FROM sometable" + t.select(), "SELECT {0}.somecolumn FROM {0}".format(rendered_name) ) def test_select_with_nolock(self):