superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: [sql lab] allow EXPlAIN queries (#5558)
Date Fri, 03 Aug 2018 22:33:36 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 9331cf7  [sql lab] allow EXPlAIN queries (#5558)
9331cf7 is described below

commit 9331cf79b556fb2d04751a30566a9c6f34c6697b
Author: Maxime Beauchemin <maximebeauchemin@gmail.com>
AuthorDate: Fri Aug 3 15:33:33 2018 -0700

    [sql lab] allow EXPlAIN queries (#5558)
    
    * [sql lab] allow EXPlAIN queries
    
    closes https://github.com/andialbrecht/sqlparse/issues/421
    
    * typo
---
 superset/sql_lab.py      |  2 +-
 superset/sql_parse.py    |  7 +++++++
 tests/sql_parse_tests.py | 14 +++++++++++++-
 tests/sqllab_tests.py    |  6 ++++++
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/superset/sql_lab.py b/superset/sql_lab.py
index f674bbb..b97761d 100644
--- a/superset/sql_lab.py
+++ b/superset/sql_lab.py
@@ -130,7 +130,7 @@ def execute_sql(
     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 7b51039..ae33453 100644
--- a/superset/sql_parse.py
+++ b/superset/sql_parse.py
@@ -41,6 +41,13 @@ class SupersetQuery(object):
     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 c9368bb..71ee294 100644
--- a/tests/sql_parse_tests.py
+++ b/tests/sql_parse_tests.py
@@ -292,9 +292,21 @@ class SupersetTestCase(unittest.TestCase):
         """
         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 3d0daed..c3fd404 100644
--- a/tests/sqllab_tests.py
+++ b/tests/sqllab_tests.py
@@ -55,6 +55,12 @@ class SqlLabTests(SupersetTestCase):
         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)


Mime
View raw message