mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-16 21:57:22 -04:00
adjust MySQL view reflection for non-standard MySQL variants
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:d85b2c5b51Change-Id: I173137f0bf68639cad0d5c329055475b40ddb5e4 (cherry picked from commit9829bc43d6)
This commit is contained in:
+10
@@ -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.
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user