diff --git a/superset/sql_lab.py b/superset/sql_lab.py index 68e3f70fe..52b08273d 100644 --- a/superset/sql_lab.py +++ b/superset/sql_lab.py @@ -171,6 +171,7 @@ def execute_sql( # Limit enforced only for retrieving the data, not for the CTA queries. superset_query = SupersetQuery(rendered_query) executed_sql = superset_query.stripped() + SQL_MAX_ROWS = int(app.config.get('SQL_MAX_ROW', None)) if not superset_query.is_select() and not database.allow_dml: return handle_error( 'Only `SELECT` statements are allowed against this database') @@ -185,7 +186,8 @@ def execute_sql( query.user_id, start_dttm.strftime('%Y_%m_%d_%H_%M_%S')) executed_sql = superset_query.as_create_table(query.tmp_table_name) query.select_as_cta_used = True - elif (query.limit and superset_query.is_select()): + elif (not query.limit and superset_query.is_select() and SQL_MAX_ROWS): + query.limit = SQL_MAX_ROWS executed_sql = database.apply_limit_to_sql(executed_sql, query.limit) query.limit_used = True diff --git a/superset/utils.py b/superset/utils.py index 08ce0d2f3..47626aa8e 100644 --- a/superset/utils.py +++ b/superset/utils.py @@ -882,3 +882,17 @@ def split_adhoc_filters_into_base_filters(fd): fd['having_filters'] = simple_having_filters fd['filters'] = simple_where_filters del fd['adhoc_filters'] + + +def get_limit_from_sql(sql): + sql = sql.lower() + limit = None + tokens = sql.split() + try: + if 'limit' in tokens: + limit_pos = tokens.index('limit') + 1 + limit = int(tokens[limit_pos]) + except Exception as e: + # fail quietly so we can get the more intelligible error from the database. + logging.error('Non-numeric limit added.\n{}'.format(e)) + return limit diff --git a/superset/views/core.py b/superset/views/core.py index 40d24b268..84e305889 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -2394,7 +2394,7 @@ class Superset(BaseSupersetView): query = Query( database_id=int(database_id), - limit=int(app.config.get('SQL_MAX_ROW', None)), + limit=utils.get_limit_from_sql(sql), sql=sql, schema=schema, select_as_cta=request.form.get('select_as_cta') == 'true', diff --git a/tests/celery_tests.py b/tests/celery_tests.py index f6d1a2958..c785702f5 100644 --- a/tests/celery_tests.py +++ b/tests/celery_tests.py @@ -196,13 +196,11 @@ class CeleryTestCase(SupersetTestCase): self.assertEqual([{'name': 'Admin'}], df.to_dict(orient='records')) self.assertEqual(QueryStatus.SUCCESS, query.status) self.assertTrue('FROM tmp_async_1' in query.select_sql) - self.assertTrue('LIMIT 666' in query.select_sql) self.assertEqual( 'CREATE TABLE tmp_async_1 AS \nSELECT name FROM ab_role ' "WHERE name='Admin'", query.executed_sql) self.assertEqual(sql_where, query.sql) self.assertEqual(0, query.rows) - self.assertEqual(666, query.limit) self.assertEqual(False, query.limit_used) self.assertEqual(True, query.select_as_cta) self.assertEqual(True, query.select_as_cta_used)