]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
adjust MySQL view reflection for non-standard MySQL variants
authorJohn Bodley <4567245+john-bodley@users.noreply.github.com>
Fri, 30 Sep 2022 01:58:58 +0000 (21:58 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 4 Oct 2022 02:45:49 +0000 (22:45 -0400)
Adjusted the regular expression used to match "CREATE VIEW" when
testing for views to work more flexibly, no longer requiring the
special keyword "ALGORITHM" in the middle, which was intended to be
optional but was not working correctly.  The change allows view reflection
to work more completely on MySQL-compatible variants such as StarRocks.
Pull request courtesy John Bodley.

Fixes: #8588
Closes: #8589
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8589
Pull-request-sha: d85b2c5b51e45cec543c9ae9d62d6d659b063354

Change-Id: I173137f0bf68639cad0d5c329055475b40ddb5e4
(cherry picked from commit 9829bc43d69ea5e714014f5ac5f036a94d13bc08)

doc/build/changelog/unreleased_14/8588.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/dialects/mysql/reflection.py
test/dialect/mysql/test_reflection.py

diff --git a/doc/build/changelog/unreleased_14/8588.rst b/doc/build/changelog/unreleased_14/8588.rst
new file mode 100644 (file)
index 0000000..879b8b2
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, mysql
+    :tickets: 8588
+
+    Adjusted the regular expression used to match "CREATE VIEW" when
+    testing for views to work more flexibly, no longer requiring the
+    special keyword "ALGORITHM" in the middle, which was intended to be
+    optional but was not working correctly.  The change allows view reflection
+    to work more completely on MySQL-compatible variants such as StarRocks.
+    Pull request courtesy John Bodley.
\ No newline at end of file
index 111c63bff162804e5f4b26672a14171c3f70b9cf..70b60a0a0fe9d696b814a70639d5f0ba2f6374bd 100644 (file)
@@ -3107,7 +3107,7 @@ class MySQLDialect(default.DefaultDialect):
         sql = self._show_create_table(
             connection, None, charset, full_name=full_name
         )
-        if re.match(r"^CREATE (?:ALGORITHM)?.* VIEW", sql):
+        if parser._check_view(sql):
             # Adapt views to something table-like.
             columns = self._describe_table(
                 connection, None, charset, full_name=full_name
index 27394bbe9fc78257ad4595d489e789a5e28e5d4a..f536496d4697a1b65dba8cee7d29a6346051acc5 100644 (file)
@@ -70,6 +70,9 @@ class MySQLTableDefinitionParser(object):
                     pass
         return state
 
+    def _check_view(self, sql):
+        return bool(self._re_is_view.match(sql))
+
     def _parse_constraints(self, line):
         """Parse a KEY or CONSTRAINT line.
 
@@ -349,6 +352,8 @@ class MySQLTableDefinitionParser(object):
             self.preparer._unescape_identifier,
         )
 
+        self._re_is_view = _re_compile(r"^CREATE(?! TABLE)(\s.*)?\sVIEW")
+
         # `col`,`col2`(32),`col3`(15) DESC
         #
         self._re_keyexprs = _re_compile(
index 4c763a6483b6b0ad6f603c6670f8544647fbb0ec..529d352a2aee0f36b3e6b3072d92f59dbc75c353 100644 (file)
@@ -1122,8 +1122,6 @@ class ReflectionTest(fixtures.TestBase, AssertsCompiledSQL):
 
 
 class RawReflectionTest(fixtures.TestBase):
-    __backend__ = True
-
     def setup_test(self):
         dialect = mysql.dialect()
         self.parser = _reflection.MySQLTableDefinitionParser(
@@ -1249,3 +1247,18 @@ class RawReflectionTest(fixtures.TestBase):
                 "SET NULL",
             ),
         )
+
+    @testing.combinations(
+        (
+            "CREATE ALGORITHM=UNDEFINED DEFINER=`scott`@`%` "
+            "SQL SECURITY DEFINER VIEW `v1` AS SELECT",
+            True,
+        ),
+        ("CREATE VIEW `v1` AS SELECT", True),
+        ("CREATE TABLE `v1`", False),
+        ("CREATE TABLE `VIEW`", False),
+        ("CREATE TABLE `VIEW_THINGS`", False),
+        ("CREATE TABLE `A VIEW`", False),
+    )
+    def test_is_view(self, sql, expected):
+        is_(self.parser._check_view(sql), expected)