diff --git a/superset/assets/javascripts/SqlLab/actions.js b/superset/assets/javascripts/SqlLab/actions.js
index 93c4afe75c4c..0edbe2f7ee48 100644
--- a/superset/assets/javascripts/SqlLab/actions.js
+++ b/superset/assets/javascripts/SqlLab/actions.js
@@ -85,8 +85,12 @@ export function fetchQueryResults(query) {
success(results) {
dispatch(querySuccess(query, results));
},
- error() {
- dispatch(queryFailed(query, 'Failed at retrieving results from the results backend'));
+ error(err) {
+ let msg = 'Failed at retrieving results from the results backend';
+ if (err.responseJSON && err.responseJSON.error) {
+ msg = err.responseJSON.error;
+ }
+ dispatch(queryFailed(query, msg));
},
});
};
diff --git a/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx b/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx
index a3ae2f2cee88..e649125facc5 100644
--- a/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx
+++ b/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx
@@ -1,5 +1,4 @@
import React from 'react';
-import { Well } from 'react-bootstrap';
import SyntaxHighlighter from 'react-syntax-highlighter';
import { github } from 'react-syntax-highlighter/dist/styles';
import ModalTrigger from '../../components/ModalTrigger';
@@ -45,11 +44,9 @@ class HighlightedSql extends React.Component {
const props = this.props;
let shownSql = props.shrink ? this.shrinkSql(props.sql) : props.sql;
return (
-
-
- {shownSql}
-
- );
+
+ {shownSql}
+ );
}
generateModal() {
const props = this.props;
diff --git a/superset/assets/javascripts/SqlLab/components/QueryTable.jsx b/superset/assets/javascripts/SqlLab/components/QueryTable.jsx
index 04c6b79ac338..9637c5d05c27 100644
--- a/superset/assets/javascripts/SqlLab/components/QueryTable.jsx
+++ b/superset/assets/javascripts/SqlLab/components/QueryTable.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import moment from 'moment';
import { Table } from 'reactable';
-import { Label, ProgressBar } from 'react-bootstrap';
+import { Label, ProgressBar, Well } from 'react-bootstrap';
import Link from './Link';
import VisualizeModal from './VisualizeModal';
import ResultSet from './ResultSet';
@@ -107,7 +107,9 @@ class QueryTable extends React.PureComponent {
);
q.sql = (
-
+
+
+
);
if (q.resultsKey) {
q.output = (
diff --git a/superset/assets/javascripts/SqlLab/components/ResultSet.jsx b/superset/assets/javascripts/SqlLab/components/ResultSet.jsx
index 847d33a07df3..003d0745dac0 100644
--- a/superset/assets/javascripts/SqlLab/components/ResultSet.jsx
+++ b/superset/assets/javascripts/SqlLab/components/ResultSet.jsx
@@ -220,7 +220,7 @@ class ResultSet extends React.PureComponent {
);
}
- return (The query returned no data);
+ return The query returned no data;
}
}
ResultSet.propTypes = propTypes;
diff --git a/superset/assets/spec/javascripts/sqllab/HighlightedSql_spec.jsx b/superset/assets/spec/javascripts/sqllab/HighlightedSql_spec.jsx
index 042f40786a44..6fb91051f0b9 100644
--- a/superset/assets/spec/javascripts/sqllab/HighlightedSql_spec.jsx
+++ b/superset/assets/spec/javascripts/sqllab/HighlightedSql_spec.jsx
@@ -24,9 +24,9 @@ describe('HighlightedSql', () => {
it('renders two SyntaxHighlighter in modal', () => {
const wrapper = mount(
);
- const well = wrapper.find('.well');
- expect(well).to.have.length(1);
- well.simulate('click');
+ const pre = wrapper.find('pre');
+ expect(pre).to.have.length(1);
+ pre.simulate('click');
const modalBody = mount(wrapper.state().modalBody);
expect(modalBody.find(SyntaxHighlighter)).to.have.length(2);
});
diff --git a/superset/sql_lab.py b/superset/sql_lab.py
index 1bb1d0b73404..6eb251e3b3d5 100644
--- a/superset/sql_lab.py
+++ b/superset/sql_lab.py
@@ -87,6 +87,9 @@ def handle_error(msg):
session.commit()
raise Exception(query.error_message)
+ if store_results and not results_backend:
+ handle_error("Results backend isn't configured.")
+
# Limit enforced only for retrieving the data, not for the CTA queries.
superset_query = sql_parse.SupersetQuery(executed_sql)
if not superset_query.is_select() and not database.allow_dml:
@@ -169,7 +172,7 @@ def handle_error(msg):
payload['query'] = query.to_dict()
payload = json.dumps(payload, default=utils.json_iso_dttm_ser)
- if store_results and results_backend:
+ if store_results:
key = '{}'.format(uuid.uuid4())
logging.info("Storing results in results backend, key: {}".format(key))
results_backend.set(key, zlib.compress(payload))
diff --git a/superset/views.py b/superset/views.py
index 85fe9a11d286..c12ffcbf70b6 100755
--- a/superset/views.py
+++ b/superset/views.py
@@ -2009,7 +2009,7 @@ def warm_up_cache(self):
models.SqlaTable.table_name == table_name)
).first()
if not table:
- json_error_response(__(
+ return json_error_response(__(
"Table %(t)s wasn't found in the database %(d)s",
t=table_name, s=db_name), status=404)
slices = session.query(models.Slice).filter_by(
@@ -2326,6 +2326,9 @@ def cached_key(self, key):
@log_this
def results(self, key):
"""Serves a key off of the results backend"""
+ if not results_backend:
+ return json_error_response("Results backend isn't configured")
+
blob = results_backend.get(key)
if blob:
json_payload = zlib.decompress(blob)
@@ -2335,7 +2338,7 @@ def results(self, key):
mydb = session.query(models.Database).filter_by(id=db_id).one()
if not self.database_access(mydb):
- json_error_response(
+ return json_error_response(
get_database_access_error_msg(mydb.database_name))
return Response(