From dfbcbcce67e808cfe36a1c554532a8d36e205812 Mon Sep 17 00:00:00 2001 From: "Hugh A. Miles II" Date: Wed, 21 Oct 2020 12:58:57 -0700 Subject: [PATCH] fix: Allow "EXPLAIN" queries when "Allow DML" setting is False (#11348) Co-authored-by: Beto Dealmeida --- superset/sql_parse.py | 8 ++++++- tests/sql_parse_tests.py | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/superset/sql_parse.py b/superset/sql_parse.py index 0bc20c1bf..9690c9fd8 100644 --- a/superset/sql_parse.py +++ b/superset/sql_parse.py @@ -111,7 +111,13 @@ class ParsedQuery: return self._parsed[0].get_type() == "SELECT" def is_explain(self) -> bool: - return self.stripped().upper().startswith("EXPLAIN") + # Remove comments + statements_without_comments = sqlparse.format( + self.stripped(), strip_comments=True + ) + + # Explain statements will only be the first statement + return statements_without_comments.startswith("EXPLAIN") def is_unknown(self) -> bool: return self._parsed[0].get_type() == "UNKNOWN" diff --git a/tests/sql_parse_tests.py b/tests/sql_parse_tests.py index f2ad795aa..0176bb6d1 100644 --- a/tests/sql_parse_tests.py +++ b/tests/sql_parse_tests.py @@ -579,3 +579,51 @@ class TestSupersetSqlParse(unittest.TestCase): reindent=True, ), ) + + def test_is_explain(self): + query = """ + -- comment + EXPLAIN select * from table + -- comment 2 + """ + parsed = ParsedQuery(query) + self.assertEqual(parsed.is_explain(), True) + + query = """ + -- comment + EXPLAIN select * from table + where col1 = 'something' + -- comment 2 + + -- comment 3 + EXPLAIN select * from table + where col1 = 'something' + -- comment 4 + """ + parsed = ParsedQuery(query) + self.assertEqual(parsed.is_explain(), True) + + query = """ + -- This is a comment + -- this is another comment but with a space in the front + EXPLAIN SELECT * FROM TABLE + """ + parsed = ParsedQuery(query) + self.assertEqual(parsed.is_explain(), True) + + query = """ + /* This is a comment + with stars instead */ + EXPLAIN SELECT * FROM TABLE + """ + parsed = ParsedQuery(query) + self.assertEqual(parsed.is_explain(), True) + + query = """ + -- comment + select * from table + where col1 = 'something' + -- comment 2 + """ + parsed = ParsedQuery(query) + self.assertEqual(parsed.is_explain(), False)