Web-Console: Replace from clause (#8371)

* add replace from

* add failture state

* fix uninential downgrade

* use uppercase for SQL keywords
This commit is contained in:
mcbrewster 2019-08-22 10:09:37 -06:00 committed by Fangjin Yang
parent b95607d31c
commit 5274c5ab73
7 changed files with 48 additions and 8 deletions

View File

@ -42,7 +42,7 @@ As part of this repo:
- `public/` - The compiled destination of the file powering this console - `public/` - The compiled destination of the file powering this console
- `assets/` - The images (and other assets) used within the console - `assets/` - The images (and other assets) used within the console
- `script/` - Some helper bash scripts for running this console - `script/` - Some helper bash scripts for running this console
- `src/` - This directory (together with `lib`) constitutes all the source code for this console - `src/` - This directory (together with `lib`) constitutes all the source code for this console
Generated/copied dynamically Generated/copied dynamically

View File

@ -4428,9 +4428,9 @@
"integrity": "sha512-0sYnfUHHMoajaud/i5BHKA12bUxiWEHJ9rxGqVEppFxsEcxef0TZQ5J59lU+UniEBcz/sG5fTESRyS7cOm3tSQ==" "integrity": "sha512-0sYnfUHHMoajaud/i5BHKA12bUxiWEHJ9rxGqVEppFxsEcxef0TZQ5J59lU+UniEBcz/sG5fTESRyS7cOm3tSQ=="
}, },
"druid-query-toolkit": { "druid-query-toolkit": {
"version": "0.3.21", "version": "0.3.23",
"resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.21.tgz", "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.23.tgz",
"integrity": "sha512-CdMLIqXy3pzjZb8iq2n6B8R7jTKVyAuAUdnH6kF0EbP1Fb2XSh8Kg8O88Ew+3ye4R9PY86a4LlXMPW4NSyKX+A==", "integrity": "sha512-6wVAGFw1sjLT9U5f7QNaIKCS0VgUfWLn/X8YWf3YQN3awSCxClzFUQnLKnHeIEb7ot0ca4H6axlb7NpzGqmtzA==",
"requires": { "requires": {
"tslib": "^1.10.0" "tslib": "^1.10.0"
} }

View File

@ -61,7 +61,7 @@
"d3": "^5.10.1", "d3": "^5.10.1",
"d3-array": "^2.3.1", "d3-array": "^2.3.1",
"druid-console": "0.0.2", "druid-console": "0.0.2",
"druid-query-toolkit": "^0.3.21", "druid-query-toolkit": "^0.3.23",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"has-own-prop": "^2.0.0", "has-own-prop": "^2.0.0",
"hjson": "^3.1.2", "hjson": "^3.1.2",

View File

@ -16,6 +16,7 @@ exports[`sql view matches snapshot 1`] = `
hasGroupBy={[Function]} hasGroupBy={[Function]}
onQueryStringChange={[Function]} onQueryStringChange={[Function]}
queryAst={[Function]} queryAst={[Function]}
replaceFrom={[Function]}
/> />
<t <t
customClassName="" customClassName=""

View File

@ -59,6 +59,7 @@ describe('column tree', () => {
] as ColumnMetadata[] ] as ColumnMetadata[]
} }
onQueryStringChange={() => {}} onQueryStringChange={() => {}}
replaceFrom={() => null}
/> />
); );

View File

@ -27,7 +27,15 @@ import {
Tree, Tree,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons'; import { IconNames } from '@blueprintjs/icons';
import { Alias, FilterClause, RefExpression, SqlQuery, StringType } from 'druid-query-toolkit'; import {
Alias,
FilterClause,
RefExpression,
refExpressionFactory,
SqlQuery,
stringFactory,
StringType,
} from 'druid-query-toolkit';
import React, { ChangeEvent } from 'react'; import React, { ChangeEvent } from 'react';
import { Loader } from '../../../components'; import { Loader } from '../../../components';
@ -136,6 +144,7 @@ export interface ColumnTreeProps {
filter?: FilterClause, filter?: FilterClause,
) => void; ) => void;
filterByRow: (filters: RowFilter[], preferablyRun: boolean) => void; filterByRow: (filters: RowFilter[], preferablyRun: boolean) => void;
replaceFrom: (table: RefExpression, preferablyRun: boolean) => void;
hasGroupBy: () => boolean; hasGroupBy: () => boolean;
queryAst: () => SqlQuery | undefined; queryAst: () => SqlQuery | undefined;
clear: (column: string, preferablyRun: boolean) => void; clear: (column: string, preferablyRun: boolean) => void;
@ -173,7 +182,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
<Menu> <Menu>
<MenuItem <MenuItem
icon={IconNames.FULLSCREEN} icon={IconNames.FULLSCREEN}
text={`Select ... from ${table}`} text={`SELECT ... FROM ${table}`}
onClick={() => { onClick={() => {
handleTableClick( handleTableClick(
schema, schema,
@ -198,6 +207,24 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
copyAndAlert(table, `${table} query copied to clipboard`); copyAndAlert(table, `${table} query copied to clipboard`);
}} }}
/> />
<Deferred
content={() => (
<>
{props.queryAst() && (
<MenuItem
icon={IconNames.EXCHANGE}
text={`Replace FROM with: ${table}`}
onClick={() => {
props.replaceFrom(
refExpressionFactory(stringFactory(table, `"`)),
true,
);
}}
/>
)}
</>
)}
/>
</Menu> </Menu>
} }
> >

View File

@ -574,6 +574,13 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun); this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
}; };
private replaceFrom = (table: RefExpression, preferablyRun: boolean): void => {
const { queryAst } = this.state;
if (!queryAst) return;
const modifiedAst = queryAst.replaceFrom(table);
this.handleQueryStringChange(modifiedAst.toString(), preferablyRun);
};
private addAggregateColumn = ( private addAggregateColumn = (
columnName: string | RefExpression, columnName: string | RefExpression,
functionName: string, functionName: string,
@ -698,7 +705,10 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
private getCurrentFilters = () => { private getCurrentFilters = () => {
const { queryAst } = this.state; const { queryAst } = this.state;
return queryAst.getCurrentFilters(); if (queryAst) {
return queryAst.getCurrentFilters();
}
return [];
}; };
render(): JSX.Element { render(): JSX.Element {
@ -730,6 +740,7 @@ export class QueryView extends React.PureComponent<QueryViewProps, QueryViewStat
defaultSchema={defaultSchema ? defaultSchema : 'druid'} defaultSchema={defaultSchema ? defaultSchema : 'druid'}
defaultTable={defaultTable} defaultTable={defaultTable}
currentFilters={this.getCurrentFilters} currentFilters={this.getCurrentFilters}
replaceFrom={this.replaceFrom}
/> />
)} )}
{this.renderMainArea()} {this.renderMainArea()}