diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 7292be489135f..955dbb473724e 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -758,7 +758,8 @@ def get_from_clause( raise QueryObjectValidationError( _("Virtual dataset query cannot consist of multiple statements") ) - if not ParsedQuery(from_sql).is_readonly(): + parsed_query = ParsedQuery(from_sql) + if not (parsed_query.is_unknown() or parsed_query.is_readonly()): raise QueryObjectValidationError( _("Virtual dataset query must be read-only") ) diff --git a/superset/sql_parse.py b/superset/sql_parse.py index e532a5eef6f65..0bc20c1bf3298 100644 --- a/superset/sql_parse.py +++ b/superset/sql_parse.py @@ -113,6 +113,9 @@ def is_select(self) -> bool: def is_explain(self) -> bool: return self.stripped().upper().startswith("EXPLAIN") + def is_unknown(self) -> bool: + return self._parsed[0].get_type() == "UNKNOWN" + def is_readonly(self) -> bool: """Pessimistic readonly, 100% sure statement won't mutate anything""" return self.is_select() or self.is_explain()