mirror of https://github.com/apache/druid.git
Add time taken by last query in SQL view (#7421)
* Add time taken by query * Fix time to 2 dp; set state in on state change; hide time taken at first * Refactored code: defined query result interface; more concise shorthand expression * Use single quote
This commit is contained in:
parent
bbb620125d
commit
4ea37e2614
|
@ -28,11 +28,16 @@
|
|||
}
|
||||
|
||||
.buttons {
|
||||
position: relative;
|
||||
|
||||
button{
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.query-elapsed {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ export interface SqlControlProps extends React.Props<any> {
|
|||
initSql: string | null;
|
||||
onRun: (query: string) => void;
|
||||
onExplain: (query: string) => void;
|
||||
queryElapsed: number | null;
|
||||
}
|
||||
|
||||
export interface SqlControlState {
|
||||
|
@ -166,7 +167,7 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
}
|
||||
|
||||
render() {
|
||||
const { onRun, onExplain } = this.props;
|
||||
const { onRun, onExplain, queryElapsed } = this.props;
|
||||
const { query, autoCompleteOn } = this.state;
|
||||
|
||||
const isRune = query.trim().startsWith('{');
|
||||
|
@ -217,7 +218,11 @@ export class SqlControl extends React.Component<SqlControlProps, SqlControlState
|
|||
<Button rightIcon={IconNames.CARET_RIGHT} onClick={() => onRun(query)}>
|
||||
{isRune ? 'Rune' : 'Run'}
|
||||
</Button>
|
||||
{!isRune ? SqlControlPopover : null}
|
||||
{!isRune && SqlControlPopover}
|
||||
{
|
||||
queryElapsed &&
|
||||
<span className={'query-elapsed'}> Last query took {(queryElapsed / 1000).toFixed(2)} seconds</span>
|
||||
}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@ import {
|
|||
localStorageGet, LocalStorageKeys,
|
||||
localStorageSet, parseQueryPlan,
|
||||
queryDruidRune,
|
||||
queryDruidSql, QueryManager, SemiJoinQueryExplanation
|
||||
queryDruidSql, QueryManager,
|
||||
SemiJoinQueryExplanation
|
||||
} from '../utils';
|
||||
|
||||
import './sql-view.scss';
|
||||
|
@ -46,11 +47,17 @@ export interface SqlViewState {
|
|||
explainResult: BasicQueryExplanation | SemiJoinQueryExplanation | string | null;
|
||||
loadingExplain: boolean;
|
||||
explainError: Error | null;
|
||||
queryElapsed: number | null;
|
||||
}
|
||||
|
||||
interface SqlQueryResult {
|
||||
queryResult: HeaderRows;
|
||||
queryElapsed: number;
|
||||
}
|
||||
|
||||
export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
|
||||
|
||||
private sqlQueryManager: QueryManager<string, HeaderRows>;
|
||||
private sqlQueryManager: QueryManager<string, SqlQueryResult>;
|
||||
private explainQueryManager: QueryManager<string, any>;
|
||||
|
||||
constructor(props: SqlViewProps, context: any) {
|
||||
|
@ -62,34 +69,42 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
|
|||
explainDialogOpen: false,
|
||||
loadingExplain: false,
|
||||
explainResult: null,
|
||||
explainError: null
|
||||
explainError: null,
|
||||
queryElapsed: null
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.sqlQueryManager = new QueryManager({
|
||||
processQuery: async (query: string) => {
|
||||
const startTime = new Date();
|
||||
if (query.trim().startsWith('{')) {
|
||||
// Secret way to issue a native JSON "rune" query
|
||||
const runeQuery = Hjson.parse(query);
|
||||
return decodeRune(runeQuery, await queryDruidRune(runeQuery));
|
||||
|
||||
const result = await queryDruidRune(runeQuery);
|
||||
return {
|
||||
queryResult: decodeRune(runeQuery, result),
|
||||
queryElapsed: new Date().valueOf() - startTime.valueOf()
|
||||
};
|
||||
} else {
|
||||
const result = await queryDruidSql({
|
||||
query,
|
||||
resultFormat: 'array',
|
||||
header: true
|
||||
});
|
||||
|
||||
return {
|
||||
header: (result && result.length) ? result[0] : [],
|
||||
rows: (result && result.length) ? result.slice(1) : []
|
||||
queryResult: {
|
||||
header: (result && result.length) ? result[0] : [],
|
||||
rows: (result && result.length) ? result.slice(1) : []
|
||||
},
|
||||
queryElapsed: new Date().valueOf() - startTime.valueOf()
|
||||
};
|
||||
}
|
||||
},
|
||||
onStateChange: ({ result, loading, error }) => {
|
||||
this.setState({
|
||||
result,
|
||||
result: result ? result.queryResult : null,
|
||||
queryElapsed: result ? result.queryElapsed : null,
|
||||
loading,
|
||||
error
|
||||
});
|
||||
|
@ -158,6 +173,7 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
|
|||
|
||||
render() {
|
||||
const { initSql } = this.props;
|
||||
const { queryElapsed } = this.state;
|
||||
|
||||
return <div className="sql-view app-view">
|
||||
<SqlControl
|
||||
|
@ -167,6 +183,7 @@ export class SqlView extends React.Component<SqlViewProps, SqlViewState> {
|
|||
this.sqlQueryManager.runQuery(q);
|
||||
}}
|
||||
onExplain={(q: string) => this.getExplain(q)}
|
||||
queryElapsed={queryElapsed}
|
||||
/>
|
||||
{this.renderResultTable()}
|
||||
{this.renderExplainDialog()}
|
||||
|
|
Loading…
Reference in New Issue