From 63baa29ad157f53639d3461f43875783038bb92b Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Thu, 21 May 2020 12:57:07 -0700 Subject: [PATCH] Fix web console query view crashing on simple query (#9897) * only parse full queries * upgraded sql parser --- licenses.yaml | 2 +- web-console/package-lock.json | 6 +- web-console/package.json | 2 +- .../__snapshots__/query-view.spec.tsx.snap | 82 +++++++++++++++++++ .../number-menu-items.spec.tsx | 8 +- .../string-menu-items.spec.tsx | 8 +- .../time-menu-items/time-menu-items.spec.tsx | 8 +- .../column-tree/column-tree.spec.tsx | 6 +- .../query-output/query-output.spec.tsx | 8 +- .../src/views/query-view/query-view.spec.tsx | 5 ++ .../src/views/query-view/query-view.tsx | 29 +++---- 11 files changed, 120 insertions(+), 44 deletions(-) diff --git a/licenses.yaml b/licenses.yaml index 6d693afa85f..6680ade8149 100644 --- a/licenses.yaml +++ b/licenses.yaml @@ -4707,7 +4707,7 @@ license_category: binary module: web-console license_name: Apache License version 2.0 copyright: Imply Data -version: 0.5.1 +version: 0.6.1 --- diff --git a/web-console/package-lock.json b/web-console/package-lock.json index 94954ef87be..422be0c2472 100644 --- a/web-console/package-lock.json +++ b/web-console/package-lock.json @@ -4243,9 +4243,9 @@ } }, "druid-query-toolkit": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.5.1.tgz", - "integrity": "sha512-oI1YddnzIbkcelI93qaRtonu3PLGw65fDqLLK6e35gD4Ef/Yf8bOZvFK9wDYNAXcA6SDy7UDarfWsgD2dDWsjg==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.6.1.tgz", + "integrity": "sha512-ykrWD9AbDQEvE55x8ST1kyiiGHSN8zhp/Lqe7z43/l7XG9QD7AQwfBzOn+HATXFynrOQN/3z3Cis70EzdDjc1g==", "requires": { "tslib": "^1.10.0" } diff --git a/web-console/package.json b/web-console/package.json index 4bf2d91ed96..293764aba7e 100644 --- a/web-console/package.json +++ b/web-console/package.json @@ -68,7 +68,7 @@ "d3-axis": "^1.0.12", "d3-scale": "^3.2.0", "d3-selection": "^1.4.0", - "druid-query-toolkit": "^0.5.1", + "druid-query-toolkit": "^0.6.1", "file-saver": "^2.0.2", "has-own-prop": "^2.0.0", "hjson": "^3.2.1", diff --git a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap index 4b26917d411..4348898355c 100644 --- a/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap +++ b/web-console/src/views/query-view/__snapshots__/query-view.spec.tsx.snap @@ -81,3 +81,85 @@ exports[`sql view matches snapshot 1`] = ` `; + +exports[`sql view matches snapshot with query 1`] = ` +
+ + +
+ +
+ + + + + + + +
+
+ +
+
+`; diff --git a/web-console/src/views/query-view/column-tree/column-tree-menu/number-menu-items/number-menu-items.spec.tsx b/web-console/src/views/query-view/column-tree/column-tree-menu/number-menu-items/number-menu-items.spec.tsx index 491ecddd29c..53b2bd5d500 100644 --- a/web-console/src/views/query-view/column-tree/column-tree-menu/number-menu-items/number-menu-items.spec.tsx +++ b/web-console/src/views/query-view/column-tree/column-tree-menu/number-menu-items/number-menu-items.spec.tsx @@ -17,21 +17,19 @@ */ import { render } from '@testing-library/react'; -import { sqlParserFactory } from 'druid-query-toolkit'; +import { parseSqlQuery } from 'druid-query-toolkit'; import React from 'react'; import { NumberMenuItems } from './number-menu-items'; describe('number menu', () => { - const parser = sqlParserFactory(['COUNT']); - it('matches snapshot when menu is opened for column not inside group by', () => { const numberMenu = ( {}} /> ); @@ -46,7 +44,7 @@ describe('number menu', () => { schema="schema" table="table" columnName={'added'} - parsedQuery={parser(`SELECT added, count(*) as cnt FROM wikipedia GROUP BY 1`)} + parsedQuery={parseSqlQuery(`SELECT added, count(*) as cnt FROM wikipedia GROUP BY 1`)} onQueryChange={() => {}} /> ); diff --git a/web-console/src/views/query-view/column-tree/column-tree-menu/string-menu-items/string-menu-items.spec.tsx b/web-console/src/views/query-view/column-tree/column-tree-menu/string-menu-items/string-menu-items.spec.tsx index 3f3c54fc318..bbaae6164ad 100644 --- a/web-console/src/views/query-view/column-tree/column-tree-menu/string-menu-items/string-menu-items.spec.tsx +++ b/web-console/src/views/query-view/column-tree/column-tree-menu/string-menu-items/string-menu-items.spec.tsx @@ -17,21 +17,19 @@ */ import { render } from '@testing-library/react'; -import { sqlParserFactory } from 'druid-query-toolkit'; +import { parseSqlQuery } from 'druid-query-toolkit'; import React from 'react'; import { StringMenuItems } from './string-menu-items'; describe('string menu', () => { - const parser = sqlParserFactory(['COUNT']); - it('matches snapshot when menu is opened for column not inside group by', () => { const stringMenu = ( {}} /> ); @@ -46,7 +44,7 @@ describe('string menu', () => { table={'table'} schema={'schema'} columnName={'channel'} - parsedQuery={parser(`SELECT channel, count(*) as cnt FROM wikipedia GROUP BY 1`)} + parsedQuery={parseSqlQuery(`SELECT channel, count(*) as cnt FROM wikipedia GROUP BY 1`)} onQueryChange={() => {}} /> ); diff --git a/web-console/src/views/query-view/column-tree/column-tree-menu/time-menu-items/time-menu-items.spec.tsx b/web-console/src/views/query-view/column-tree/column-tree-menu/time-menu-items/time-menu-items.spec.tsx index a8d5ee77ed0..58586478eb6 100644 --- a/web-console/src/views/query-view/column-tree/column-tree-menu/time-menu-items/time-menu-items.spec.tsx +++ b/web-console/src/views/query-view/column-tree/column-tree-menu/time-menu-items/time-menu-items.spec.tsx @@ -17,21 +17,19 @@ */ import { render } from '@testing-library/react'; -import { sqlParserFactory } from 'druid-query-toolkit'; +import { parseSqlQuery } from 'druid-query-toolkit'; import React from 'react'; import { TimeMenuItems } from './time-menu-items'; describe('time menu', () => { - const parser = sqlParserFactory(['COUNT']); - it('matches snapshot when menu is opened for column not inside group by', () => { const timeMenu = ( {}} /> ); @@ -46,7 +44,7 @@ describe('time menu', () => { table={'table'} schema={'schema'} columnName={'__time'} - parsedQuery={parser(`SELECT __time, count(*) as cnt FROM wikipedia GROUP BY 1`)} + parsedQuery={parseSqlQuery(`SELECT __time, count(*) as cnt FROM wikipedia GROUP BY 1`)} onQueryChange={() => {}} /> ); diff --git a/web-console/src/views/query-view/column-tree/column-tree.spec.tsx b/web-console/src/views/query-view/column-tree/column-tree.spec.tsx index e925eabcf7d..5636c74bca1 100644 --- a/web-console/src/views/query-view/column-tree/column-tree.spec.tsx +++ b/web-console/src/views/query-view/column-tree/column-tree.spec.tsx @@ -17,7 +17,7 @@ */ import { render } from '@testing-library/react'; -import { sqlParserFactory } from 'druid-query-toolkit'; +import { parseSqlQuery } from 'druid-query-toolkit'; import React from 'react'; import { ColumnMetadata } from '../../../utils/column-metadata'; @@ -25,13 +25,11 @@ import { ColumnMetadata } from '../../../utils/column-metadata'; import { ColumnTree } from './column-tree'; describe('column tree', () => { - const parser = sqlParserFactory(['COUNT']); - it('matches snapshot', () => { const columnTree = ( { - return parser(`SELECT channel, count(*) as cnt FROM wikipedia GROUP BY 1`); + return parseSqlQuery(`SELECT channel, count(*) as cnt FROM wikipedia GROUP BY 1`); }} defaultSchema="druid" defaultTable="wikipedia" diff --git a/web-console/src/views/query-view/query-output/query-output.spec.tsx b/web-console/src/views/query-view/query-output/query-output.spec.tsx index 3da323bc81a..6417b912a26 100644 --- a/web-console/src/views/query-view/query-output/query-output.spec.tsx +++ b/web-console/src/views/query-view/query-output/query-output.spec.tsx @@ -17,18 +17,14 @@ */ import { render } from '@testing-library/react'; -import { sqlParserFactory } from 'druid-query-toolkit'; +import { parseSqlQuery } from 'druid-query-toolkit'; import React from 'react'; -import { SQL_FUNCTIONS } from '../../../../lib/sql-docs'; - import { QueryOutput } from './query-output'; describe('query output', () => { it('matches snapshot', () => { - const parser = sqlParserFactory(SQL_FUNCTIONS.map(sqlFunction => sqlFunction.name)); - - const parsedQuery = parser(`SELECT + const parsedQuery = parseSqlQuery(`SELECT "language", COUNT(*) AS "Count", COUNT(DISTINCT "language") AS "dist_language", COUNT(*) FILTER (WHERE "language"= 'xxx') AS "language_filtered_count" FROM "github" diff --git a/web-console/src/views/query-view/query-view.spec.tsx b/web-console/src/views/query-view/query-view.spec.tsx index d8db9578930..b3397a01c3b 100644 --- a/web-console/src/views/query-view/query-view.spec.tsx +++ b/web-console/src/views/query-view/query-view.spec.tsx @@ -27,6 +27,11 @@ describe('sql view', () => { expect(sqlView).toMatchSnapshot(); }); + it('matches snapshot with query', () => { + const sqlView = shallow(); + expect(sqlView).toMatchSnapshot(); + }); + it('trimSemicolon', () => { expect(QueryView.trimSemicolon('SELECT * FROM tbl;')).toEqual('SELECT * FROM tbl'); expect(QueryView.trimSemicolon('SELECT * FROM tbl; ')).toEqual('SELECT * FROM tbl '); diff --git a/web-console/src/views/query-view/query-view.tsx b/web-console/src/views/query-view/query-view.tsx index de844bf8551..4e9a18cc6c5 100644 --- a/web-console/src/views/query-view/query-view.tsx +++ b/web-console/src/views/query-view/query-view.tsx @@ -23,8 +23,8 @@ import { HeaderRows, isFirstRowHeader, normalizeQueryResult, + parseSqlQuery, shouldIncludeTimestamp, - sqlParserFactory, SqlQuery, } from 'druid-query-toolkit'; import Hjson from 'hjson'; @@ -32,7 +32,6 @@ import memoizeOne from 'memoize-one'; import React from 'react'; import SplitterLayout from 'react-splitter-layout'; -import { SQL_FUNCTIONS } from '../../../lib/sql-docs'; import { QueryPlanDialog } from '../../dialogs'; import { EditContextDialog } from '../../dialogs/edit-context-dialog/edit-context-dialog'; import { QueryHistoryDialog } from '../../dialogs/query-history-dialog/query-history-dialog'; @@ -63,11 +62,9 @@ import { RunButton } from './run-button/run-button'; import './query-view.scss'; -const parserRaw = sqlParserFactory(SQL_FUNCTIONS.map(sqlFunction => sqlFunction.name)); - -const parser = memoizeOne((sql: string) => { +const parser = memoizeOne((sql: string): SqlQuery | undefined => { try { - return parserRaw(sql); + return parseSqlQuery(sql); } catch { return; } @@ -87,7 +84,7 @@ export interface QueryViewProps { export interface QueryViewState { queryString: string; - parsedQuery: SqlQuery; + parsedQuery?: SqlQuery; queryContext: QueryContext; wrapQueryLimit: number | undefined; autoRun: boolean; @@ -479,18 +476,22 @@ export class QueryView extends React.PureComponent