Skip to content

Commit

Permalink
feat(sqllab): Add a configuration option to disable data preview (#19104
Browse files Browse the repository at this point in the history
)
  • Loading branch information
cccs-Dustin committed Mar 17, 2022
1 parent cfb967f commit 02ef9ca
Show file tree
Hide file tree
Showing 18 changed files with 168 additions and 35 deletions.
14 changes: 10 additions & 4 deletions docs/static/resources/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,9 @@
"allows_virtual_table_explore": {
"type": "boolean"
},
"disable_data_preview": {
"type": "boolean"
},
"backend": {
"type": "string"
},
Expand Down Expand Up @@ -2472,6 +2475,9 @@
"allows_virtual_table_explore": {
"readOnly": true
},
"disable_data_preview": {
"readOnly": true
},
"backend": {
"readOnly": true
},
Expand Down Expand Up @@ -2571,7 +2577,7 @@
"type": "boolean"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"force_ctas_schema": {
Expand Down Expand Up @@ -2663,7 +2669,7 @@
"type": "boolean"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"force_ctas_schema": {
Expand Down Expand Up @@ -2720,7 +2726,7 @@
"type": "string"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"impersonate_user": {
Expand Down Expand Up @@ -2768,7 +2774,7 @@
"type": "string"
},
"extra": {
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown.</p>",
"description": "<p>JSON string containing extra configuration elements.<br>1. The <code>engine_params</code> object gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine\">sqlalchemy.create_engine</a> call, while the <code>metadata_params</code> gets unpacked into the <a href=\"https://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData\">sqlalchemy.MetaData</a> call.<br>2. The <code>metadata_cache_timeout</code> is a cache timeout setting in seconds for metadata fetch of this database. Specify it as <strong>\"metadata_cache_timeout\": {\"schema_cache_timeout\": 600, \"table_cache_timeout\": 600}</strong>. If unset, cache will not be enabled for the functionality. A timeout of 0 indicates that the cache never expires.<br>3. The <code>schemas_allowed_for_csv_upload</code> is a comma separated list of schemas that CSVs are allowed to upload to. Specify it as <strong>\"schemas_allowed_for_csv_upload\": [\"public\", \"csv_upload\"]</strong>. If database flavor does not support schema or any schema is allowed to be accessed, just leave the list empty<br>4. the <code>version</code> field is a string specifying the this db's version. This should be used with Presto DBs so that the syntax is correct<br>5. The <code>allows_virtual_table_explore</code> field is a boolean specifying whether or not the Explore button in SQL Lab results is shown<br>6. The <code>disable_data_preview</code> field is a boolean specifying whether or not data preview queries will be run when fetching table metadata in SQL Lab.</p>",
"type": "string"
},
"impersonate_user": {
Expand Down
45 changes: 28 additions & 17 deletions superset-frontend/src/SqlLab/actions/sqlLab.js
Original file line number Diff line number Diff line change
Expand Up @@ -1018,28 +1018,13 @@ function getTableMetadata(table, query, dispatch) {
),
})
.then(({ json }) => {
const dataPreviewQuery = {
id: shortid.generate(),
dbId: query.dbId,
sql: json.selectStar,
tableName: table.name,
sqlEditorId: null,
tab: '',
runAsync: false,
ctas: false,
isDataPreview: true,
};
const newTable = {
...table,
...json,
expanded: true,
isMetadataLoading: false,
dataPreviewQueryId: dataPreviewQuery.id,
};
Promise.all([
dispatch(mergeTable(newTable, dataPreviewQuery)), // Merge table to tables in state
dispatch(runQuery(dataPreviewQuery)), // Run query to get preview data for table
]);
dispatch(mergeTable(newTable)); // Merge table to tables in state
return newTable;
})
.catch(() =>
Expand Down Expand Up @@ -1082,7 +1067,7 @@ function getTableExtendedMetadata(table, query, dispatch) {
);
}

export function addTable(query, tableName, schemaName) {
export function addTable(query, database, tableName, schemaName) {
return function (dispatch) {
const table = {
dbId: query.dbId,
Expand Down Expand Up @@ -1110,6 +1095,32 @@ export function addTable(query, tableName, schemaName) {
})
: Promise.resolve({ json: { id: shortid.generate() } });

if (!database.disable_data_preview && database.id === query.dbId) {
const dataPreviewQuery = {
id: shortid.generate(),
dbId: query.dbId,
sql: newTable.selectStar,
tableName: table.name,
sqlEditorId: null,
tab: '',
runAsync: database.allow_run_async,
ctas: false,
isDataPreview: true,
};
Promise.all([
dispatch(
mergeTable(
{
...newTable,
dataPreviewQueryId: dataPreviewQuery.id,
},
dataPreviewQuery,
),
),
dispatch(runQuery(dataPreviewQuery)),
]);
}

return sync
.then(({ json: resultJson }) =>
dispatch(mergeTable({ ...table, id: resultJson.id })),
Expand Down
41 changes: 36 additions & 5 deletions superset-frontend/src/SqlLab/actions/sqlLab.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -727,28 +727,60 @@ describe('async actions', () => {
it('updates the table schema state in the backend', () => {
expect.assertions(5);

const database = { disable_data_preview: true };
const tableName = 'table';
const schemaName = 'schema';
const store = mockStore({});
const expectedActionTypes = [
actions.MERGE_TABLE, // addTable
actions.MERGE_TABLE, // getTableMetadata
actions.MERGE_TABLE, // getTableExtendedMetadata
actions.MERGE_TABLE, // addTable
];
return store
.dispatch(actions.addTable(query, database, tableName, schemaName))
.then(() => {
expect(store.getActions().map(a => a.type)).toEqual(
expectedActionTypes,
);
expect(fetchMock.calls(updateTableSchemaEndpoint)).toHaveLength(1);
expect(fetchMock.calls(getTableMetadataEndpoint)).toHaveLength(1);
expect(fetchMock.calls(getExtraTableMetadataEndpoint)).toHaveLength(
1,
);

// tab state is not updated, since no query was run
expect(fetchMock.calls(updateTabStateEndpoint)).toHaveLength(0);
});
});

it('updates and runs data preview query when configured', () => {
expect.assertions(5);

const results = {
data: mockBigNumber,
query: { sqlEditorId: 'null' },
query: { sqlEditorId: 'null', dbId: 1 },
query_id: 'efgh',
};
fetchMock.post(runQueryEndpoint, JSON.stringify(results), {
overwriteRoutes: true,
});

const database = { disable_data_preview: false, id: 1 };
const tableName = 'table';
const schemaName = 'schema';
const store = mockStore({});
const expectedActionTypes = [
actions.MERGE_TABLE, // addTable
actions.MERGE_TABLE, // getTableMetadata
actions.START_QUERY, // runQuery (data preview)
actions.MERGE_TABLE, // getTableExtendedMetadata
actions.QUERY_SUCCESS, // querySuccess
actions.MERGE_TABLE, // addTable (data preview)
actions.START_QUERY, // runQuery (data preview)
actions.MERGE_TABLE, // addTable
actions.QUERY_SUCCESS, // querySuccess
];
return store
.dispatch(actions.addTable(query, tableName, schemaName))
.dispatch(actions.addTable(query, database, tableName, schemaName))
.then(() => {
expect(store.getActions().map(a => a.type)).toEqual(
expectedActionTypes,
Expand All @@ -758,7 +790,6 @@ describe('async actions', () => {
expect(fetchMock.calls(getExtraTableMetadataEndpoint)).toHaveLength(
1,
);

// tab state is not updated, since the query is a data preview
expect(fetchMock.calls(updateTabStateEndpoint)).toHaveLength(0);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,17 @@ interface Props {
actions: {
queryEditorSetSelectedText: (edit: any, text: null | string) => void;
queryEditorSetFunctionNames: (queryEditor: object, dbId: number) => void;
addTable: (queryEditor: any, value: any, schema: any) => void;
addTable: (
queryEditor: any,
database: any,
value: any,
schema: any,
) => void;
};
autocomplete: boolean;
onBlur: (sql: string) => void;
sql: string;
database: any;
schemas: any[];
tables: any[];
functionNames: string[];
Expand Down Expand Up @@ -210,6 +216,7 @@ class AceEditorWrapper extends React.PureComponent<Props, State> {
if (data.meta === 'table') {
this.props.actions.addTable(
this.props.queryEditor,
this.props.database,
data.value,
this.props.queryEditor.schema,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ class SqlEditor extends React.PureComponent {
onChange={this.onSqlChanged}
queryEditor={this.props.queryEditor}
sql={this.props.queryEditor.sql}
database={this.props.database}
schemas={this.props.queryEditor.schemaOptions}
tables={this.props.queryEditor.tableOptions}
functionNames={this.props.queryEditor.functionNames}
Expand Down

0 comments on commit 02ef9ca

Please sign in to comment.