mirror of https://github.com/apache/druid.git
Web console: make console's Explain more honest (#8327)
* fix structure * update snapshots
This commit is contained in:
parent
7362b1d8fc
commit
0d69438395
|
@ -49,6 +49,8 @@ exports[`sql view matches snapshot 1`] = `
|
|||
queryContext={Object {}}
|
||||
runeMode={false}
|
||||
setAutoRun={[Function]}
|
||||
setWrapQuery={[Function]}
|
||||
wrapQuery={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -45,7 +45,7 @@ import './column-tree.scss';
|
|||
function handleTableClick(
|
||||
tableSchema: string,
|
||||
nodeData: ITreeNode,
|
||||
onQueryStringChange: (queryString: string) => void,
|
||||
onQueryStringChange: (queryString: string, run: boolean) => void,
|
||||
): void {
|
||||
let columns: string[];
|
||||
if (nodeData.childNodes) {
|
||||
|
@ -54,12 +54,18 @@ function handleTableClick(
|
|||
columns = ['*'];
|
||||
}
|
||||
if (tableSchema === 'druid') {
|
||||
onQueryStringChange(`SELECT ${columns.join(', ')}
|
||||
onQueryStringChange(
|
||||
`SELECT ${columns.join(', ')}
|
||||
FROM ${escapeSqlIdentifier(String(nodeData.label))}
|
||||
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY`);
|
||||
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY`,
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
onQueryStringChange(`SELECT ${columns.join(', ')}
|
||||
FROM ${tableSchema}.${nodeData.label}`);
|
||||
onQueryStringChange(
|
||||
`SELECT ${columns.join(', ')}
|
||||
FROM ${tableSchema}.${nodeData.label}`,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,40 +73,49 @@ function handleColumnClick(
|
|||
columnSchema: string,
|
||||
columnTable: string,
|
||||
nodeData: ITreeNode,
|
||||
onQueryStringChange: (queryString: string) => void,
|
||||
onQueryStringChange: (queryString: string, run: boolean) => void,
|
||||
): void {
|
||||
if (columnSchema === 'druid') {
|
||||
if (nodeData.icon === IconNames.TIME) {
|
||||
onQueryStringChange(`SELECT
|
||||
onQueryStringChange(
|
||||
`SELECT
|
||||
TIME_FLOOR(${escapeSqlIdentifier(String(nodeData.label))}, 'PT1H') AS "Time",
|
||||
COUNT(*) AS "Count"
|
||||
FROM ${escapeSqlIdentifier(columnTable)}
|
||||
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY
|
||||
GROUP BY 1
|
||||
ORDER BY "Time" ASC`);
|
||||
ORDER BY "Time" ASC`,
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
onQueryStringChange(`SELECT
|
||||
onQueryStringChange(
|
||||
`SELECT
|
||||
"${nodeData.label}",
|
||||
COUNT(*) AS "Count"
|
||||
FROM ${escapeSqlIdentifier(columnTable)}
|
||||
WHERE "__time" >= CURRENT_TIMESTAMP - INTERVAL '1' DAY
|
||||
GROUP BY 1
|
||||
ORDER BY "Count" DESC`);
|
||||
ORDER BY "Count" DESC`,
|
||||
true,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
onQueryStringChange(`SELECT
|
||||
onQueryStringChange(
|
||||
`SELECT
|
||||
${escapeSqlIdentifier(String(nodeData.label))},
|
||||
COUNT(*) AS "Count"
|
||||
FROM ${columnSchema}.${columnTable}
|
||||
GROUP BY 1
|
||||
ORDER BY "Count" DESC`);
|
||||
ORDER BY "Count" DESC`,
|
||||
true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ColumnTreeProps {
|
||||
columnMetadataLoading: boolean;
|
||||
columnMetadata?: ColumnMetadata[];
|
||||
onQueryStringChange: (queryString: string) => void;
|
||||
onQueryStringChange: (queryString: string, run: boolean) => void;
|
||||
defaultSchema?: string;
|
||||
defaultTable?: string;
|
||||
addFunctionToGroupBy: (
|
||||
|
|
|
@ -173,8 +173,14 @@ export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputS
|
|||
this.setState({ editorHeight: entries[0].contentRect.height });
|
||||
};
|
||||
|
||||
private handleChange = (value: string) => {
|
||||
// This gets the event as a second arg
|
||||
const { onQueryStringChange } = this.props;
|
||||
onQueryStringChange(value);
|
||||
};
|
||||
|
||||
render(): JSX.Element {
|
||||
const { queryString, runeMode, onQueryStringChange } = this.props;
|
||||
const { queryString, runeMode } = this.props;
|
||||
const { editorHeight } = this.state;
|
||||
|
||||
// Set the key in the AceEditor to force a rebind and prevent an error that happens otherwise
|
||||
|
@ -186,7 +192,7 @@ export class QueryInput extends React.PureComponent<QueryInputProps, QueryInputS
|
|||
mode={runeMode ? 'hjson' : 'dsql'}
|
||||
theme="solarized_dark"
|
||||
name="ace-editor"
|
||||
onChange={onQueryStringChange}
|
||||
onChange={this.handleChange}
|
||||
focus
|
||||
fontSize={14}
|
||||
width="100%"
|
||||
|
|
|
@ -86,7 +86,7 @@ const parser = memoizeOne((sql: string) => {
|
|||
interface QueryWithContext {
|
||||
queryString: string;
|
||||
queryContext: QueryContext;
|
||||
wrapQuery?: boolean;
|
||||
wrapQuery: boolean;
|
||||
}
|
||||
|
||||
export interface QueryViewProps {
|
||||
|
@ -103,6 +103,8 @@ export interface QueryViewState {
|
|||
queryString: string;
|
||||
queryAst: SqlQuery;
|
||||
queryContext: QueryContext;
|
||||
wrapQuery: boolean;
|
||||
autoRun: boolean;
|
||||
|
||||
columnMetadataLoading: boolean;
|
||||
columnMetadata?: ColumnMetadata[];
|
||||
|
@ -123,8 +125,6 @@ export interface QueryViewState {
|
|||
editContextDialogOpen: boolean;
|
||||
historyDialogOpen: boolean;
|
||||
queryHistory: QueryRecord[];
|
||||
|
||||
autoRun: boolean;
|
||||
}
|
||||
|
||||
interface QueryResult {
|
||||
|
@ -139,6 +139,22 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
return query.replace(/;+((?:\s*--[^\n]*)?\s*)$/, '$1');
|
||||
}
|
||||
|
||||
static isExplainQuery(query: string): boolean {
|
||||
return /EXPLAIN\sPLAN\sFOR/i.test(query);
|
||||
}
|
||||
|
||||
static wrapInLimitIfNeeded(query: string, limit = 1000): string {
|
||||
query = QueryView.trimSemicolon(query);
|
||||
if (QueryView.isExplainQuery(query)) return query;
|
||||
return `SELECT * FROM (${query}\n) LIMIT ${limit}`;
|
||||
}
|
||||
|
||||
static wrapInExplainIfNeeded(query: string): string {
|
||||
query = QueryView.trimSemicolon(query);
|
||||
if (QueryView.isExplainQuery(query)) return query;
|
||||
return `EXPLAIN PLAN FOR (${query}\n)`;
|
||||
}
|
||||
|
||||
static isJsonLike(queryString: string): boolean {
|
||||
return queryString.trim().startsWith('{');
|
||||
}
|
||||
|
@ -186,10 +202,32 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
}
|
||||
const queryAst = queryString ? parser(queryString) : undefined;
|
||||
|
||||
const localStorageQueryHistory = localStorageGet(LocalStorageKeys.QUERY_HISTORY);
|
||||
let queryHistory = [];
|
||||
if (localStorageQueryHistory) {
|
||||
let possibleQueryHistory: unknown;
|
||||
try {
|
||||
possibleQueryHistory = JSON.parse(localStorageQueryHistory);
|
||||
} catch {}
|
||||
if (Array.isArray(possibleQueryHistory)) queryHistory = possibleQueryHistory;
|
||||
}
|
||||
|
||||
const localStorageAutoRun = localStorageGet(LocalStorageKeys.AUTO_RUN);
|
||||
let autoRun = true;
|
||||
if (localStorageAutoRun) {
|
||||
let possibleAutoRun: unknown;
|
||||
try {
|
||||
possibleAutoRun = JSON.parse(localStorageAutoRun);
|
||||
} catch {}
|
||||
if (typeof possibleAutoRun === 'boolean') autoRun = possibleAutoRun;
|
||||
}
|
||||
|
||||
this.state = {
|
||||
queryString: queryString ? queryString : '',
|
||||
queryAst,
|
||||
queryContext: {},
|
||||
wrapQuery: true,
|
||||
autoRun,
|
||||
|
||||
columnMetadataLoading: false,
|
||||
|
||||
|
@ -200,10 +238,9 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
|
||||
editContextDialogOpen: false,
|
||||
historyDialogOpen: false,
|
||||
queryHistory: [],
|
||||
|
||||
autoRun: true,
|
||||
queryHistory,
|
||||
};
|
||||
|
||||
this.metadataQueryManager = new QueryManager({
|
||||
processQuery: async () => {
|
||||
return await queryDruidSql<ColumnMetadata>({
|
||||
|
@ -244,8 +281,8 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
jsonQuery = Hjson.parse(queryString);
|
||||
} else {
|
||||
const actualQuery = wrapQuery
|
||||
? `SELECT * FROM (${QueryView.trimSemicolon(queryString)}\n) LIMIT 1000`
|
||||
: queryString;
|
||||
? QueryView.wrapInLimitIfNeeded(queryString)
|
||||
: QueryView.trimSemicolon(queryString);
|
||||
|
||||
if (wrapQuery) wrappedLimit = 1000;
|
||||
|
||||
|
@ -314,9 +351,14 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
|
||||
this.explainQueryManager = new QueryManager({
|
||||
processQuery: async (queryWithContext: QueryWithContext) => {
|
||||
const { queryString, queryContext } = queryWithContext;
|
||||
const { queryString, queryContext, wrapQuery } = queryWithContext;
|
||||
|
||||
const actualQuery = wrapQuery
|
||||
? QueryView.wrapInLimitIfNeeded(queryString)
|
||||
: QueryView.trimSemicolon(queryString);
|
||||
|
||||
const explainPayload: Record<string, any> = {
|
||||
query: `EXPLAIN PLAN FOR (${QueryView.trimSemicolon(queryString)}\n)`,
|
||||
query: QueryView.wrapInExplainIfNeeded(actualQuery),
|
||||
resultFormat: 'object',
|
||||
};
|
||||
|
||||
|
@ -337,28 +379,6 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
|
||||
componentDidMount(): void {
|
||||
this.metadataQueryManager.runQuery(null);
|
||||
|
||||
const localStorageQueryHistoy = localStorageGet(LocalStorageKeys.QUERY_HISTORY);
|
||||
let queryHistory;
|
||||
if (localStorageQueryHistoy) {
|
||||
try {
|
||||
queryHistory = JSON.parse(localStorageQueryHistoy);
|
||||
} catch {}
|
||||
if (queryHistory) {
|
||||
this.setState({ queryHistory });
|
||||
}
|
||||
}
|
||||
|
||||
const localStorageAutoRun = localStorageGet(LocalStorageKeys.AUTO_RUN);
|
||||
let autoRun;
|
||||
if (localStorageAutoRun) {
|
||||
try {
|
||||
autoRun = JSON.parse(localStorageAutoRun);
|
||||
} catch {}
|
||||
if (typeof autoRun === 'boolean') {
|
||||
this.setState({ autoRun });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount(): void {
|
||||
|
@ -454,7 +474,9 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
error,
|
||||
columnMetadata,
|
||||
autoRun,
|
||||
wrapQuery,
|
||||
} = this.state;
|
||||
|
||||
const runeMode = QueryView.isJsonLike(queryString);
|
||||
return (
|
||||
<SplitterLayout
|
||||
|
@ -477,7 +499,9 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
<div className="control-bar">
|
||||
<RunButton
|
||||
autoRun={autoRun}
|
||||
setAutoRun={(autoRun: boolean) => this.setAutoRun(autoRun)}
|
||||
setAutoRun={this.setAutoRun}
|
||||
wrapQuery={wrapQuery}
|
||||
setWrapQuery={this.setWrapQuery}
|
||||
onEditContext={() => this.setState({ editContextDialogOpen: true })}
|
||||
runeMode={runeMode}
|
||||
queryContext={queryContext}
|
||||
|
@ -515,31 +539,17 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
preferablyRun: boolean,
|
||||
alias: Alias,
|
||||
): void => {
|
||||
const { autoRun, queryAst } = this.state;
|
||||
const { queryAst } = this.state;
|
||||
if (!queryAst) return;
|
||||
const groupedAst = queryAst.addFunctionToGroupBy(functionName, spacing, argumentsArray, alias);
|
||||
const queryString = groupedAst.toString();
|
||||
this.setState({
|
||||
queryString,
|
||||
queryAst: parser(queryString),
|
||||
});
|
||||
if (autoRun && preferablyRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
const modifiedAst = queryAst.addFunctionToGroupBy(functionName, spacing, argumentsArray, alias);
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
||||
private addToGroupBy = (columnName: string, preferablyRun: boolean): void => {
|
||||
const { autoRun, queryAst } = this.state;
|
||||
const { queryAst } = this.state;
|
||||
if (!queryAst) return;
|
||||
const groupedAst = queryAst.addToGroupBy(columnName);
|
||||
const queryString = groupedAst.toString();
|
||||
this.setState({
|
||||
queryString,
|
||||
queryAst: parser(queryString),
|
||||
});
|
||||
if (autoRun && preferablyRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
const modifiedAst = queryAst.addToGroupBy(columnName);
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
||||
private addAggregateColumn = (
|
||||
|
@ -550,7 +560,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
distinct?: boolean,
|
||||
filter?: FilterClause,
|
||||
): void => {
|
||||
const { autoRun, queryAst } = this.state;
|
||||
const { queryAst } = this.state;
|
||||
if (!queryAst) return;
|
||||
const modifiedAst = queryAst.addAggregateColumn(
|
||||
columnName,
|
||||
|
@ -559,14 +569,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
distinct,
|
||||
filter,
|
||||
);
|
||||
const queryString = modifiedAst.toString();
|
||||
this.setState({
|
||||
queryString,
|
||||
queryAst: parser(queryString),
|
||||
});
|
||||
if (autoRun && preferablyRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
||||
private sqlOrderBy = (
|
||||
|
@ -574,35 +577,21 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
direction: 'ASC' | 'DESC',
|
||||
preferablyRun: boolean,
|
||||
): void => {
|
||||
const { autoRun, queryAst } = this.state;
|
||||
const { queryAst } = this.state;
|
||||
if (!queryAst) return;
|
||||
const modifiedAst = queryAst.orderBy(header, direction);
|
||||
const queryString = modifiedAst.toString();
|
||||
this.setState({
|
||||
queryString,
|
||||
queryAst: parser(queryString),
|
||||
});
|
||||
if (autoRun && preferablyRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
||||
private sqlExcludeColumn = (header: string, preferablyRun: boolean): void => {
|
||||
const { autoRun, queryAst } = this.state;
|
||||
const { queryAst } = this.state;
|
||||
if (!queryAst) return;
|
||||
const modifiedAst = queryAst.excludeColumn(header);
|
||||
const queryString = modifiedAst.toString();
|
||||
this.setState({
|
||||
queryString,
|
||||
queryAst: parser(queryString),
|
||||
});
|
||||
if (autoRun && preferablyRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
||||
private sqlFilterRow = (filters: RowFilter[], preferablyRun: boolean): void => {
|
||||
const { autoRun, queryAst } = this.state;
|
||||
const { queryAst } = this.state;
|
||||
if (!queryAst) return;
|
||||
|
||||
let modifiedAst: SqlQuery = queryAst;
|
||||
|
@ -611,14 +600,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
modifiedAst = modifiedAst.filterRow(filter.header, filter.row, filter.operator);
|
||||
}
|
||||
}
|
||||
const queryString = modifiedAst.toString();
|
||||
this.setState({
|
||||
queryString,
|
||||
queryAst: parser(queryString),
|
||||
});
|
||||
if (autoRun && preferablyRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
|
||||
};
|
||||
|
||||
private sqlClearWhere = (): void => {
|
||||
|
@ -630,8 +612,11 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
}
|
||||
};
|
||||
|
||||
private handleQueryStringChange = (queryString: string): void => {
|
||||
this.setState({ queryString, queryAst: parser(queryString) });
|
||||
private handleQueryStringChange = (queryString: string, preferablyRun?: boolean): void => {
|
||||
this.setState({ queryString, queryAst: parser(queryString) }, () => {
|
||||
const { autoRun } = this.state;
|
||||
if (preferablyRun && autoRun) this.handleRun();
|
||||
});
|
||||
};
|
||||
|
||||
private handleQueryContextChange = (queryContext: QueryContext) => {
|
||||
|
@ -643,18 +628,19 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
localStorageSet(LocalStorageKeys.AUTO_RUN, String(autoRun));
|
||||
};
|
||||
|
||||
private handleRun = (wrapQuery: boolean, customQueryString?: string) => {
|
||||
const { queryString, queryContext, queryHistory } = this.state;
|
||||
if (!customQueryString) {
|
||||
customQueryString = queryString;
|
||||
}
|
||||
private setWrapQuery = (wrapQuery: boolean) => {
|
||||
this.setState({ wrapQuery });
|
||||
};
|
||||
|
||||
private handleRun = () => {
|
||||
const { queryString, queryContext, wrapQuery, queryHistory } = this.state;
|
||||
|
||||
while (queryHistory.length > 9) {
|
||||
queryHistory.pop();
|
||||
}
|
||||
queryHistory.unshift({
|
||||
version: `${new Date().toISOString()}`,
|
||||
queryString: customQueryString,
|
||||
queryString,
|
||||
});
|
||||
let queryHistoryString;
|
||||
try {
|
||||
|
@ -664,16 +650,17 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
localStorageSet(LocalStorageKeys.QUERY_HISTORY, queryHistoryString);
|
||||
}
|
||||
|
||||
if (QueryView.isJsonLike(customQueryString) && !QueryView.validRune(customQueryString)) return;
|
||||
if (QueryView.isJsonLike(queryString) && !QueryView.validRune(queryString)) return;
|
||||
|
||||
localStorageSet(LocalStorageKeys.QUERY_KEY, customQueryString);
|
||||
this.sqlQueryManager.runQuery({ queryString: customQueryString, queryContext, wrapQuery });
|
||||
localStorageSet(LocalStorageKeys.QUERY_KEY, queryString);
|
||||
this.sqlQueryManager.runQuery({ queryString, queryContext, wrapQuery });
|
||||
};
|
||||
|
||||
private handleExplain = () => {
|
||||
const { queryString, queryContext } = this.state;
|
||||
const { queryString, queryContext, wrapQuery } = this.state;
|
||||
|
||||
this.setState({ explainDialogOpen: true });
|
||||
this.explainQueryManager.runQuery({ queryString, queryContext });
|
||||
this.explainQueryManager.runQuery({ queryString, queryContext, wrapQuery });
|
||||
};
|
||||
|
||||
private handleSecondaryPaneSizeChange = (secondaryPaneSize: number) => {
|
||||
|
@ -702,24 +689,13 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
return queryAst;
|
||||
};
|
||||
|
||||
private onQueryStringChange = (queryString: string) => {
|
||||
const { autoRun } = this.state;
|
||||
|
||||
this.handleQueryStringChange(queryString);
|
||||
if (autoRun) {
|
||||
this.handleRun(true, queryString);
|
||||
}
|
||||
};
|
||||
|
||||
render(): JSX.Element {
|
||||
const { columnMetadata, columnMetadataLoading, columnMetadataError, queryAst } = this.state;
|
||||
|
||||
let defaultSchema;
|
||||
if (queryAst && queryAst instanceof SqlQuery) {
|
||||
defaultSchema = queryAst.getSchema();
|
||||
}
|
||||
let defaultTable;
|
||||
if (queryAst && queryAst instanceof SqlQuery) {
|
||||
if (queryAst instanceof SqlQuery) {
|
||||
defaultSchema = queryAst.getSchema();
|
||||
defaultTable = queryAst.getTableName();
|
||||
}
|
||||
|
||||
|
@ -738,7 +714,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
|
|||
queryAst={this.getQueryAst}
|
||||
columnMetadataLoading={columnMetadataLoading}
|
||||
columnMetadata={columnMetadata}
|
||||
onQueryStringChange={this.onQueryStringChange}
|
||||
onQueryStringChange={this.handleQueryStringChange}
|
||||
defaultSchema={defaultSchema ? defaultSchema : 'druid'}
|
||||
defaultTable={defaultTable}
|
||||
/>
|
||||
|
|
|
@ -26,7 +26,9 @@ describe('run button', () => {
|
|||
const runButton = (
|
||||
<RunButton
|
||||
autoRun
|
||||
setAutoRun={() => null}
|
||||
setAutoRun={() => {}}
|
||||
wrapQuery
|
||||
setWrapQuery={() => {}}
|
||||
onHistory={() => null}
|
||||
onEditContext={() => null}
|
||||
runeMode={false}
|
||||
|
|
|
@ -46,21 +46,19 @@ import { DRUID_DOCS_RUNE, DRUID_DOCS_SQL } from '../../../variables';
|
|||
export interface RunButtonProps {
|
||||
runeMode: boolean;
|
||||
autoRun: boolean;
|
||||
setAutoRun: (autoRun: boolean) => void;
|
||||
wrapQuery: boolean;
|
||||
setWrapQuery: (wrapQuery: boolean) => void;
|
||||
queryContext: QueryContext;
|
||||
onQueryContextChange: (newQueryContext: QueryContext) => void;
|
||||
onRun: (wrapQuery: boolean) => void;
|
||||
onRun: () => void;
|
||||
onExplain: () => void;
|
||||
onEditContext: () => void;
|
||||
onHistory: () => void;
|
||||
setAutoRun: (autoRun: boolean) => void;
|
||||
}
|
||||
|
||||
interface RunButtonState {
|
||||
wrapQuery: boolean;
|
||||
}
|
||||
|
||||
@HotkeysTarget
|
||||
export class RunButton extends React.PureComponent<RunButtonProps, RunButtonState> {
|
||||
export class RunButton extends React.PureComponent<RunButtonProps> {
|
||||
constructor(props: RunButtonProps, context: any) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
|
@ -85,7 +83,7 @@ export class RunButton extends React.PureComponent<RunButtonProps, RunButtonStat
|
|||
private handleRun = () => {
|
||||
const { onRun } = this.props;
|
||||
if (!onRun) return;
|
||||
onRun(this.state.wrapQuery);
|
||||
onRun();
|
||||
};
|
||||
|
||||
renderExtraMenu() {
|
||||
|
@ -96,10 +94,11 @@ export class RunButton extends React.PureComponent<RunButtonProps, RunButtonStat
|
|||
onQueryContextChange,
|
||||
onEditContext,
|
||||
onHistory,
|
||||
setAutoRun,
|
||||
autoRun,
|
||||
setAutoRun,
|
||||
wrapQuery,
|
||||
setWrapQuery,
|
||||
} = this.props;
|
||||
const { wrapQuery } = this.state;
|
||||
|
||||
const useCache = getUseCache(queryContext);
|
||||
const useApproximateCountDistinct = getUseApproximateCountDistinct(queryContext);
|
||||
|
@ -120,7 +119,7 @@ export class RunButton extends React.PureComponent<RunButtonProps, RunButtonStat
|
|||
<MenuCheckbox
|
||||
checked={wrapQuery}
|
||||
label="Wrap query with limit"
|
||||
onChange={() => this.setState({ wrapQuery: !wrapQuery })}
|
||||
onChange={() => setWrapQuery(!wrapQuery)}
|
||||
/>
|
||||
<MenuCheckbox
|
||||
checked={autoRun}
|
||||
|
@ -160,8 +159,7 @@ export class RunButton extends React.PureComponent<RunButtonProps, RunButtonStat
|
|||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
const { runeMode, onRun } = this.props;
|
||||
const { wrapQuery } = this.state;
|
||||
const { runeMode, onRun, wrapQuery } = this.props;
|
||||
|
||||
return (
|
||||
<ButtonGroup className="run-button">
|
||||
|
|
Loading…
Reference in New Issue