mistercrunch closed pull request #5558: [sql lab] allow EXPlAIN queries
URL: https://github.com/apache/incubator-superset/pull/5558
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/superset/sql_lab.py b/superset/sql_lab.py
index f674bbb1ce..b97761d3ca 100644
--- a/superset/sql_lab.py
+++ b/superset/sql_lab.py
@@ -130,7 +130,7 @@ def handle_error(msg):
     superset_query = SupersetQuery(rendered_query)
     executed_sql = superset_query.stripped()
     SQL_MAX_ROWS = app.config.get('SQL_MAX_ROW')
-    if not superset_query.is_select() and not database.allow_dml:
+    if not superset_query.is_readonly() and not database.allow_dml:
         return handle_error(
             'Only `SELECT` statements are allowed against this database')
     if query.select_as_cta:
diff --git a/superset/sql_parse.py b/superset/sql_parse.py
index 7b5103924c..ae33453b25 100644
--- a/superset/sql_parse.py
+++ b/superset/sql_parse.py
@@ -41,6 +41,13 @@ def limit(self):
     def is_select(self):
         return self._parsed[0].get_type() == 'SELECT'
 
+    def is_explain(self):
+        return self.sql.strip().upper().startswith('EXPLAIN')
+
+    def is_readonly(self):
+        """Pessimistic readonly, 100% sure statement won't mutate anything"""
+        return self.is_select() or self.is_explain()
+
     def stripped(self):
         return self.sql.strip(' \t\n;')
 
diff --git a/tests/sql_parse_tests.py b/tests/sql_parse_tests.py
index c9368bb362..71ee29406a 100644
--- a/tests/sql_parse_tests.py
+++ b/tests/sql_parse_tests.py
@@ -292,9 +292,21 @@ def test_reusing_aliases(self):
         """
         self.assertEquals({'src'}, self.extract_tables(query))
 
-    def multistatement(self):
+    def test_multistatement(self):
         query = 'SELECT * FROM t1; SELECT * FROM t2'
         self.assertEquals({'t1', 't2'}, self.extract_tables(query))
 
         query = 'SELECT * FROM t1; SELECT * FROM t2;'
         self.assertEquals({'t1', 't2'}, self.extract_tables(query))
+
+    def test_update_not_select(self):
+        sql = sql_parse.SupersetQuery('UPDATE t1 SET col1 = NULL')
+        self.assertEquals(False, sql.is_select())
+        self.assertEquals(False, sql.is_readonly())
+
+    def test_explain(self):
+        sql = sql_parse.SupersetQuery('EXPLAIN SELECT 1')
+
+        self.assertEquals(True, sql.is_explain())
+        self.assertEquals(False, sql.is_select())
+        self.assertEquals(True, sql.is_readonly())
diff --git a/tests/sqllab_tests.py b/tests/sqllab_tests.py
index 3d0daed213..c3fd4045f7 100644
--- a/tests/sqllab_tests.py
+++ b/tests/sqllab_tests.py
@@ -55,6 +55,12 @@ def test_sql_json(self):
         data = self.run_sql('SELECT * FROM unexistant_table', '2')
         self.assertLess(0, len(data['error']))
 
+    def test_explain(self):
+        self.login('admin')
+
+        data = self.run_sql('EXPLAIN SELECT * FROM ab_user', '1')
+        self.assertLess(0, len(data['data']))
+
     def test_sql_json_has_access(self):
         main_db = self.get_main_database(db.session)
         security_manager.add_permission_view_menu('database_access', 
main_db.perm)


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to