mirror of
https://github.com/apache/superset.git
synced 2026-04-19 16:14:52 +00:00
perf(sqllab): Rendering perf improvement using immutable state (#20877)
* perf(sqllab): Rendering perf improvement using immutable state - keep queryEditors immutable during active state - add unsavedQueryEditor to store all active changes - refactor each component to subscribe the related unsaved editor state only * revert ISaveableDatasource type cast * missing trigger prop * a default of an empty object and optional operator
This commit is contained in:
@@ -123,6 +123,17 @@ const fieldConverter = mapping => obj =>
|
||||
const convertQueryToServer = fieldConverter(queryServerMapping);
|
||||
const convertQueryToClient = fieldConverter(queryClientMapping);
|
||||
|
||||
export function getUpToDateQuery(rootState, queryEditor, key) {
|
||||
const {
|
||||
sqlLab: { unsavedQueryEditor },
|
||||
} = rootState;
|
||||
const id = key ?? queryEditor.id;
|
||||
return {
|
||||
...queryEditor,
|
||||
...(id === unsavedQueryEditor.id && unsavedQueryEditor),
|
||||
};
|
||||
}
|
||||
|
||||
export function resetState() {
|
||||
return { type: RESET_STATE };
|
||||
}
|
||||
@@ -167,24 +178,26 @@ export function scheduleQuery(query) {
|
||||
);
|
||||
}
|
||||
|
||||
export function estimateQueryCost(query) {
|
||||
const { dbId, schema, sql, templateParams } = query;
|
||||
const endpoint =
|
||||
schema === null
|
||||
? `/superset/estimate_query_cost/${dbId}/`
|
||||
: `/superset/estimate_query_cost/${dbId}/${schema}/`;
|
||||
return dispatch =>
|
||||
Promise.all([
|
||||
dispatch({ type: COST_ESTIMATE_STARTED, query }),
|
||||
export function estimateQueryCost(queryEditor) {
|
||||
return (dispatch, getState) => {
|
||||
const { dbId, schema, sql, selectedText, templateParams } =
|
||||
getUpToDateQuery(getState(), queryEditor);
|
||||
const requestSql = selectedText || sql;
|
||||
const endpoint =
|
||||
schema === null
|
||||
? `/superset/estimate_query_cost/${dbId}/`
|
||||
: `/superset/estimate_query_cost/${dbId}/${schema}/`;
|
||||
return Promise.all([
|
||||
dispatch({ type: COST_ESTIMATE_STARTED, query: queryEditor }),
|
||||
SupersetClient.post({
|
||||
endpoint,
|
||||
postPayload: {
|
||||
sql,
|
||||
sql: requestSql,
|
||||
templateParams: JSON.parse(templateParams || '{}'),
|
||||
},
|
||||
})
|
||||
.then(({ json }) =>
|
||||
dispatch({ type: COST_ESTIMATE_RETURNED, query, json }),
|
||||
dispatch({ type: COST_ESTIMATE_RETURNED, query: queryEditor, json }),
|
||||
)
|
||||
.catch(response =>
|
||||
getClientErrorObject(response).then(error => {
|
||||
@@ -194,12 +207,13 @@ export function estimateQueryCost(query) {
|
||||
t('Failed at retrieving results');
|
||||
return dispatch({
|
||||
type: COST_ESTIMATE_FAILED,
|
||||
query,
|
||||
query: queryEditor,
|
||||
error: message,
|
||||
});
|
||||
}),
|
||||
),
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
export function startQuery(query) {
|
||||
@@ -357,6 +371,34 @@ export function runQuery(query) {
|
||||
};
|
||||
}
|
||||
|
||||
export function runQueryFromSqlEditor(
|
||||
database,
|
||||
queryEditor,
|
||||
defaultQueryLimit,
|
||||
tempTable,
|
||||
ctas,
|
||||
ctasMethod,
|
||||
) {
|
||||
return function (dispatch, getState) {
|
||||
const qe = getUpToDateQuery(getState(), queryEditor, queryEditor.id);
|
||||
const query = {
|
||||
dbId: qe.dbId,
|
||||
sql: qe.selectedText || qe.sql,
|
||||
sqlEditorId: qe.id,
|
||||
tab: qe.name,
|
||||
schema: qe.schema,
|
||||
tempTable,
|
||||
templateParams: qe.templateParams,
|
||||
queryLimit: qe.queryLimit || defaultQueryLimit,
|
||||
runAsync: database ? database.allow_run_async : false,
|
||||
ctas,
|
||||
ctas_method: ctasMethod,
|
||||
updateTabState: !qe.selectedText,
|
||||
};
|
||||
dispatch(runQuery(query));
|
||||
};
|
||||
}
|
||||
|
||||
export function reRunQuery(query) {
|
||||
// run Query with a new id
|
||||
return function (dispatch) {
|
||||
@@ -364,8 +406,23 @@ export function reRunQuery(query) {
|
||||
};
|
||||
}
|
||||
|
||||
export function validateQuery(query) {
|
||||
return function (dispatch) {
|
||||
export function validateQuery(queryEditor, sql) {
|
||||
return function (dispatch, getState) {
|
||||
const {
|
||||
sqlLab: { unsavedQueryEditor },
|
||||
} = getState();
|
||||
const qe = {
|
||||
...queryEditor,
|
||||
...(queryEditor.id === unsavedQueryEditor.id && unsavedQueryEditor),
|
||||
};
|
||||
|
||||
const query = {
|
||||
dbId: qe.dbId,
|
||||
sql,
|
||||
sqlEditorId: qe.id,
|
||||
schema: qe.schema,
|
||||
templateParams: qe.templateParams,
|
||||
};
|
||||
dispatch(startQueryValidation(query));
|
||||
|
||||
const postPayload = {
|
||||
@@ -620,6 +677,7 @@ export function switchQueryEditor(queryEditor, displayLimit) {
|
||||
return function (dispatch) {
|
||||
if (
|
||||
isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE) &&
|
||||
queryEditor &&
|
||||
!queryEditor.loaded
|
||||
) {
|
||||
SupersetClient.get({
|
||||
@@ -723,6 +781,17 @@ export function removeQueryEditor(queryEditor) {
|
||||
};
|
||||
}
|
||||
|
||||
export function removeAllOtherQueryEditors(queryEditor) {
|
||||
return function (dispatch, getState) {
|
||||
const { sqlLab } = getState();
|
||||
sqlLab.queryEditors?.forEach(otherQueryEditor => {
|
||||
if (otherQueryEditor.id !== queryEditor.id) {
|
||||
dispatch(removeQueryEditor(otherQueryEditor));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function removeQuery(query) {
|
||||
return function (dispatch) {
|
||||
const sync = isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)
|
||||
@@ -921,8 +990,9 @@ export function queryEditorSetSql(queryEditor, sql) {
|
||||
return { type: QUERY_EDITOR_SET_SQL, queryEditor, sql };
|
||||
}
|
||||
|
||||
export function queryEditorSetAndSaveSql(queryEditor, sql) {
|
||||
return function (dispatch) {
|
||||
export function queryEditorSetAndSaveSql(targetQueryEditor, sql) {
|
||||
return function (dispatch, getState) {
|
||||
const queryEditor = getUpToDateQuery(getState(), targetQueryEditor);
|
||||
// saved query and set tab state use this action
|
||||
dispatch(queryEditorSetSql(queryEditor, sql));
|
||||
if (isFeatureEnabled(FeatureFlag.SQLLAB_BACKEND_PERSISTENCE)) {
|
||||
|
||||
Reference in New Issue
Block a user