Web console: update druid-query-toolkit to version 0.4.x (#9500)

* add support for new version of DQT

* update druid-query-toolkit

* fix direction css

* fix remove

* update package

* remove useless conditional

* bump package

* jest -u

Co-authored-by: Maggie Brewster <maggiebrewster@implydata20sMBP.attlocal.net>
This commit is contained in:
mcbrewster 2020-03-13 18:09:47 -07:00 committed by GitHub
parent 6afd55c8f4
commit bcb9a632c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 247 additions and 178 deletions

View File

@ -4237,9 +4237,9 @@
}
},
"druid-query-toolkit": {
"version": "0.3.29",
"resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.3.29.tgz",
"integrity": "sha512-WKpsmmqgZd5vgOGCyWZ+2h0aNpTbd82h0svC5GBbhqmXB++vkJchYPGjPmmHkNMV2JI2f40ztxel3hpZv5zSQg==",
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/druid-query-toolkit/-/druid-query-toolkit-0.4.3.tgz",
"integrity": "sha512-g2xHaD9lhpTZjM9UEiOQBpgBvO1hm0/cVgqymbUIUf6cgBCm7C1o20fHQzCEK4FBhVmWQSt63pjhRaQ+OM4FGQ==",
"requires": {
"tslib": "^1.10.0"
}

View File

@ -65,7 +65,7 @@
"d3-axis": "^1.0.12",
"d3-scale": "^3.2.0",
"d3-selection": "^1.4.0",
"druid-query-toolkit": "^0.3.29",
"druid-query-toolkit": "^0.4.3",
"file-saver": "^2.0.2",
"has-own-prop": "^2.0.0",
"hjson": "^3.2.1",

View File

@ -18,8 +18,7 @@
import { MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { SqlQuery, StringType } from 'druid-query-toolkit';
import { aliasFactory } from 'druid-query-toolkit/build/ast/sql-query/helpers';
import { SqlAliasRef, SqlFunction, SqlLiteral, SqlQuery, SqlRef } from 'druid-query-toolkit';
import React from 'react';
export interface NumberMenuItemsProps {
@ -37,13 +36,25 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
<MenuItem
text={`"${columnName}" > 100`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(columnName, 100, '>'));
onQueryChange(
parsedQuery.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'>',
SqlLiteral.fromInput(100),
),
);
}}
/>
<MenuItem
text={`"${columnName}" <= 100`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(columnName, 100, '<='));
onQueryChange(
parsedQuery.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'<=',
SqlLiteral.fromInput(100),
),
);
}}
/>
</MenuItem>
@ -52,7 +63,7 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
function renderRemoveFilter(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasFilterForColumn(columnName)) return;
if (!parsedQuery.getCurrentFilters().includes(columnName)) return;
return (
<MenuItem
@ -67,13 +78,13 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
function renderRemoveGroupBy(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupByForColumn(columnName)) return;
if (!parsedQuery.hasGroupByColumn(columnName)) return;
return (
<MenuItem
icon={IconNames.UNGROUP_OBJECTS}
text={'Remove group by'}
onClick={() => {
onQueryChange(parsedQuery.removeGroupBy(columnName), true);
onQueryChange(parsedQuery.removeFromGroupBy(columnName), true);
}}
/>
);
@ -81,32 +92,31 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
function renderGroupByMenu(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.groupByClause) return;
if (!parsedQuery.groupByExpression) return;
return (
<MenuItem icon={IconNames.GROUP_OBJECTS} text={`Group by`}>
<MenuItem
text={`"${columnName}"`}
onClick={() => {
onQueryChange(parsedQuery.addToGroupBy(columnName), true);
onQueryChange(
parsedQuery.addToGroupBy(SqlRef.fromNameWithDoubleQuotes(columnName)),
true,
);
}}
/>
<MenuItem
text={`TRUNC("${columnName}", -1) AS "${columnName}_trunc"`}
onClick={() => {
onQueryChange(
parsedQuery.addFunctionToGroupBy(
'TRUNC',
[' '],
[
new StringType({
spacing: [],
chars: columnName,
quote: '"',
}),
-1,
],
aliasFactory(`${columnName}_truncated`),
parsedQuery.addToGroupBy(
SqlAliasRef.sqlAliasFactory(
SqlFunction.sqlFunctionFactory('TRUNC', [
SqlRef.fromNameWithDoubleQuotes(columnName),
SqlLiteral.fromInput(-1),
]),
`${columnName}_truncated`,
),
),
true,
);
@ -118,7 +128,7 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
function renderAggregateMenu(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.groupByClause) return;
if (!parsedQuery.groupByExpression) return;
return (
<MenuItem icon={IconNames.FUNCTION} text={`Aggregate`}>
@ -126,7 +136,11 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
text={`SUM(${columnName}) AS "sum_${columnName}"`}
onClick={() => {
onQueryChange(
parsedQuery.addAggregateColumn(columnName, 'SUM', aliasFactory(`sum_${columnName}`)),
parsedQuery.addAggregateColumn(
[SqlRef.fromName(columnName)],
'SUM',
`sum_${columnName}`,
),
true,
);
}}
@ -135,7 +149,11 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
text={`MAX(${columnName}) AS "max_${columnName}"`}
onClick={() => {
onQueryChange(
parsedQuery.addAggregateColumn(columnName, 'MAX', aliasFactory(`max_${columnName}`)),
parsedQuery.addAggregateColumn(
[SqlRef.fromName(columnName)],
'MAX',
`max_${columnName}`,
),
true,
);
}}
@ -144,7 +162,11 @@ export const NumberMenuItems = React.memo(function NumberMenuItems(props: Number
text={`MIN(${columnName}) AS "min_${columnName}"`}
onClick={() => {
onQueryChange(
parsedQuery.addAggregateColumn(columnName, 'MIN', aliasFactory(`min_${columnName}`)),
parsedQuery.addAggregateColumn(
[SqlRef.fromName(columnName)],
'MIN',
`min_${columnName}`,
),
true,
);
}}

View File

@ -19,14 +19,13 @@
import { MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import {
ComparisonExpression,
ComparisonExpressionRhs,
FilterClause,
refExpressionFactory,
SqlAliasRef,
SqlFunction,
SqlLiteral,
SqlMulti,
SqlQuery,
WhereClause,
SqlRef,
} from 'druid-query-toolkit';
import { aliasFactory, stringFactory } from 'druid-query-toolkit/build/ast/sql-query/helpers';
import React from 'react';
export interface StringMenuItemsProps {
@ -44,13 +43,13 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
<MenuItem
text={`"${columnName}" = 'xxx'`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(columnName, 'xxx', '='), false);
onQueryChange(parsedQuery.addWhereFilter(columnName, '=', 'xxx'), false);
}}
/>
<MenuItem
text={`"${columnName}" LIKE '%xxx%'`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(columnName, '%xxx%', 'LIKE'), false);
onQueryChange(parsedQuery.addWhereFilter(columnName, 'LIKE', '%xxx%'), false);
}}
/>
</MenuItem>
@ -59,7 +58,7 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
function renderRemoveFilter(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasFilterForColumn(columnName)) return;
if (!parsedQuery.getCurrentFilters().includes(columnName)) return;
return (
<MenuItem
@ -74,13 +73,13 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
function renderRemoveGroupBy(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupByForColumn(columnName)) return;
if (!parsedQuery.hasGroupByColumn(columnName)) return;
return (
<MenuItem
icon={IconNames.UNGROUP_OBJECTS}
text={'Remove group by'}
onClick={() => {
onQueryChange(parsedQuery.removeGroupBy(columnName), true);
onQueryChange(parsedQuery.removeFromGroupBy(columnName), true);
}}
/>
);
@ -88,26 +87,32 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
function renderGroupByMenu(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupBy()) return;
if (!parsedQuery.groupByExpression) return;
return (
<MenuItem icon={IconNames.GROUP_OBJECTS} text={`Group by`}>
<MenuItem
text={`"${columnName}"`}
onClick={() => {
onQueryChange(parsedQuery.addToGroupBy(columnName), true);
onQueryChange(
parsedQuery.addToGroupBy(SqlRef.fromNameWithDoubleQuotes(columnName)),
true,
);
}}
/>
<MenuItem
text={`SUBSTRING("${columnName}", 1, 2) AS "${columnName}_substring"`}
onClick={() => {
onQueryChange(
parsedQuery.addFunctionToGroupBy(
'SUBSTRING',
[' ', ' '],
[stringFactory(columnName, `"`), 1, 2],
aliasFactory(`${columnName}_substring`),
parsedQuery.addToGroupBy(
SqlAliasRef.sqlAliasFactory(
SqlFunction.sqlFunctionFactory('SUBSTRING', [
SqlRef.fromNameWithDoubleQuotes(columnName),
SqlLiteral.fromInput(1),
SqlLiteral.fromInput(2),
]),
`${columnName}_substring`,
),
),
true,
);
@ -119,7 +124,7 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
function renderAggregateMenu(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupBy()) return;
if (!parsedQuery.groupByExpression) return;
return (
<MenuItem icon={IconNames.FUNCTION} text={`Aggregate`}>
@ -128,9 +133,11 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
onClick={() =>
onQueryChange(
parsedQuery.addAggregateColumn(
columnName,
[SqlRef.fromNameWithDoubleQuotes(columnName)],
'COUNT',
aliasFactory(`dist_${columnName}`),
`dist_${columnName}`,
undefined,
'DISTINCT',
),
true,
)
@ -141,28 +148,13 @@ export const StringMenuItems = React.memo(function StringMenuItems(props: String
onClick={() => {
onQueryChange(
parsedQuery.addAggregateColumn(
refExpressionFactory('*'),
[SqlRef.fromName('*')],
'COUNT',
aliasFactory(`${columnName}_filtered_count`),
false,
new FilterClause({
keyword: 'FILTER',
spacing: [' '],
ex: new WhereClause({
keyword: 'WHERE',
spacing: [' '],
filter: new ComparisonExpression({
parens: [],
ex: stringFactory(columnName, '"'),
rhs: new ComparisonExpressionRhs({
parens: [],
op: '=',
rhs: stringFactory('xxx', `'`),
spacing: [' ', ' '],
}),
}),
}),
}),
`${columnName}_filtered_count`,
SqlMulti.sqlMultiFactory('=', [
SqlRef.fromNameWithDoubleQuotes(columnName),
SqlLiteral.fromInput('xxx'),
]),
),
);
}}

View File

@ -18,17 +18,20 @@
import { MenuDivider, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { AdditiveExpression, SqlQuery, Timestamp, timestampFactory } from 'druid-query-toolkit';
import {
aliasFactory,
intervalFactory,
refExpressionFactory,
stringFactory,
} from 'druid-query-toolkit/build/ast/sql-query/helpers';
SqlAliasRef,
SqlFunction,
SqlInterval,
SqlLiteral,
SqlMulti,
SqlQuery,
SqlRef,
SqlTimestamp,
} from 'druid-query-toolkit';
import React from 'react';
function dateToTimestamp(date: Date): Timestamp {
return timestampFactory(
function dateToTimestamp(date: Date): SqlTimestamp {
return SqlTimestamp.sqlTimestampFactory(
date
.toISOString()
.split('.')[0]
@ -103,14 +106,17 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
<MenuItem
text={`Latest hour`}
onClick={() => {
const additiveExpression = new AdditiveExpression({
parens: [],
op: ['-'],
ex: [refExpressionFactory('CURRENT_TIMESTAMP'), intervalFactory('HOUR', '1')],
spacing: [' ', ' '],
});
onQueryChange(
parsedQuery.removeFilter(columnName).filterRow(columnName, additiveExpression, '>='),
parsedQuery
.removeFilter(columnName)
.addWhereFilter(
columnName,
'>=',
SqlMulti.sqlMultiFactory('-', [
SqlRef.fromName('CURRENT_TIMESTAMP'),
SqlInterval.sqlIntervalFactory('HOUR', 1),
]),
),
true,
);
}}
@ -118,14 +124,17 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
<MenuItem
text={`Latest day`}
onClick={() => {
const additiveExpression = new AdditiveExpression({
parens: [],
op: ['-'],
ex: [refExpressionFactory('CURRENT_TIMESTAMP'), intervalFactory('DAY', '1')],
spacing: [' ', ' '],
});
onQueryChange(
parsedQuery.removeFilter(columnName).filterRow(columnName, additiveExpression, '>='),
parsedQuery
.removeFilter(columnName)
.addWhereFilter(
columnName,
'>=',
SqlMulti.sqlMultiFactory('-', [
SqlRef.fromName('CURRENT_TIMESTAMP'),
SqlInterval.sqlIntervalFactory('Day', 1),
]),
),
true,
);
}}
@ -133,14 +142,17 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
<MenuItem
text={`Latest week`}
onClick={() => {
const additiveExpression = new AdditiveExpression({
parens: [],
op: ['-'],
ex: [refExpressionFactory('CURRENT_TIMESTAMP'), intervalFactory('DAY', '7')],
spacing: [' ', ' '],
});
onQueryChange(
parsedQuery.removeFilter(columnName).filterRow(columnName, additiveExpression, '>='),
parsedQuery
.removeFilter(columnName)
.addWhereFilter(
columnName,
'>=',
SqlMulti.sqlMultiFactory('-', [
SqlRef.fromName('CURRENT_TIMESTAMP'),
SqlInterval.sqlIntervalFactory('Day', 7),
]),
),
true,
);
}}
@ -148,14 +160,17 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
<MenuItem
text={`Latest month`}
onClick={() => {
const additiveExpression = new AdditiveExpression({
parens: [],
op: ['-'],
ex: [refExpressionFactory('CURRENT_TIMESTAMP'), intervalFactory('MONTH', '1')],
spacing: [' ', ' '],
});
onQueryChange(
parsedQuery.removeFilter(columnName).filterRow(columnName, additiveExpression, '>='),
parsedQuery
.removeFilter(columnName)
.addWhereFilter(
columnName,
'>=',
SqlMulti.sqlMultiFactory('-', [
SqlRef.fromName('CURRENT_TIMESTAMP'),
SqlInterval.sqlIntervalFactory('MONTH', 1),
]),
),
true,
);
}}
@ -163,14 +178,17 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
<MenuItem
text={`Latest year`}
onClick={() => {
const additiveExpression = new AdditiveExpression({
parens: [],
op: ['-'],
ex: [refExpressionFactory('CURRENT_TIMESTAMP'), intervalFactory('YEAR', '1')],
spacing: [' ', ' '],
});
onQueryChange(
parsedQuery.removeFilter(columnName).filterRow(columnName, additiveExpression, '>='),
parsedQuery
.removeFilter(columnName)
.addWhereFilter(
columnName,
'>=',
SqlMulti.sqlMultiFactory('-', [
SqlRef.fromName('CURRENT_TIMESTAMP'),
SqlInterval.sqlIntervalFactory('YEAR', 1),
]),
),
true,
);
}}
@ -183,8 +201,16 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
onQueryChange(
parsedQuery
.removeFilter(columnName)
.filterRow(dateToTimestamp(hourStart), stringFactory(columnName, `"`), '<=')
.filterRow(columnName, dateToTimestamp(nextHour(hourStart)), '<'),
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'>=',
dateToTimestamp(hourStart),
)
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'<',
dateToTimestamp(nextHour(hourStart)),
),
true,
);
}}
@ -196,8 +222,16 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
onQueryChange(
parsedQuery
.removeFilter(columnName)
.filterRow(dateToTimestamp(dayStart), stringFactory(columnName, `"`), '<=')
.filterRow(columnName, dateToTimestamp(nextDay(dayStart)), '<'),
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'>=',
dateToTimestamp(dayStart),
)
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'<',
dateToTimestamp(nextDay(dayStart)),
),
true,
);
}}
@ -209,8 +243,16 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
onQueryChange(
parsedQuery
.removeFilter(columnName)
.filterRow(dateToTimestamp(monthStart), stringFactory(columnName, `"`), '<=')
.filterRow(columnName, dateToTimestamp(nextMonth(monthStart)), '<'),
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'>=',
dateToTimestamp(monthStart),
)
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'<',
dateToTimestamp(nextMonth(monthStart)),
),
true,
);
}}
@ -222,8 +264,16 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
onQueryChange(
parsedQuery
.removeFilter(columnName)
.filterRow(dateToTimestamp(yearStart), stringFactory(columnName, `"`), '<=')
.filterRow(columnName, dateToTimestamp(nextYear(yearStart)), '<'),
.addWhereFilter(
SqlRef.fromNameWithDoubleQuotes(columnName),
'<=',
dateToTimestamp(yearStart),
)
.addWhereFilter(
dateToTimestamp(yearStart),
'<',
dateToTimestamp(nextYear(yearStart)),
),
true,
);
}}
@ -234,7 +284,7 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
function renderRemoveFilter(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasFilterForColumn(columnName)) return;
if (!parsedQuery.getCurrentFilters().includes(columnName)) return;
return (
<MenuItem
@ -249,13 +299,13 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
function renderRemoveGroupBy(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupByForColumn(columnName)) return;
if (!parsedQuery.hasGroupByColumn(columnName)) return;
return (
<MenuItem
icon={IconNames.UNGROUP_OBJECTS}
text={'Remove group by'}
onClick={() => {
onQueryChange(parsedQuery.removeGroupBy(columnName), true);
onQueryChange(parsedQuery.removeFromGroupBy(columnName), true);
}}
/>
);
@ -263,7 +313,7 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
function renderGroupByMenu(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupBy()) return;
if (!parsedQuery.groupByExpression) return;
return (
<MenuItem icon={IconNames.GROUP_OBJECTS} text={`Group by`}>
@ -271,11 +321,14 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
text={`TIME_FLOOR("${columnName}", 'PT1H') AS "${columnName}_time_floor"`}
onClick={() => {
onQueryChange(
parsedQuery.addFunctionToGroupBy(
'TIME_FLOOR',
[' '],
[stringFactory(columnName, `"`), stringFactory('PT1H', `'`)],
aliasFactory(`${columnName}_time_floor`),
parsedQuery.addToGroupBy(
SqlAliasRef.sqlAliasFactory(
SqlFunction.sqlFunctionFactory('TIME_FLOOR', [
SqlRef.fromName(columnName),
SqlLiteral.fromInput('PT1h'),
]),
`${columnName}_time_floor`,
),
),
true,
);
@ -285,11 +338,14 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
text={`TIME_FLOOR("${columnName}", 'P1D') AS "${columnName}_time_floor"`}
onClick={() => {
onQueryChange(
parsedQuery.addFunctionToGroupBy(
'TIME_FLOOR',
[' '],
[stringFactory(columnName, `"`), stringFactory('P1D', `'`)],
aliasFactory(`${columnName}_time_floor`),
parsedQuery.addToGroupBy(
SqlAliasRef.sqlAliasFactory(
SqlFunction.sqlFunctionFactory('TIME_FLOOR', [
SqlRef.fromName(columnName),
SqlLiteral.fromInput('P1D'),
]),
`${columnName}_time_floor`,
),
),
true,
);
@ -299,11 +355,14 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
text={`TIME_FLOOR("${columnName}", 'P7D') AS "${columnName}_time_floor"`}
onClick={() => {
onQueryChange(
parsedQuery.addFunctionToGroupBy(
'TIME_FLOOR',
[' '],
[stringFactory(columnName, `"`), stringFactory('P7D', `'`)],
aliasFactory(`${columnName}_time_floor`),
parsedQuery.addToGroupBy(
SqlAliasRef.sqlAliasFactory(
SqlFunction.sqlFunctionFactory('TIME_FLOOR', [
SqlRef.fromName(columnName),
SqlLiteral.fromInput('P7D'),
]),
`${columnName}_time_floor`,
),
),
true,
);
@ -315,7 +374,7 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
function renderAggregateMenu(): JSX.Element | undefined {
const { columnName, parsedQuery, onQueryChange } = props;
if (!parsedQuery.hasGroupBy()) return;
if (!parsedQuery.groupByExpression) return;
return (
<MenuItem icon={IconNames.FUNCTION} text={`Aggregate`}>
@ -323,7 +382,11 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
text={`MAX("${columnName}") AS "max_${columnName}"`}
onClick={() => {
onQueryChange(
parsedQuery.addAggregateColumn(columnName, 'MAX', aliasFactory(`max_${columnName}`)),
parsedQuery.addAggregateColumn(
[SqlRef.fromNameWithDoubleQuotes(columnName)],
'MAX',
`max_${columnName}`,
),
true,
);
}}
@ -332,7 +395,11 @@ export const TimeMenuItems = React.memo(function TimeMenuItems(props: TimeMenuIt
text={`MIN("${columnName}") AS "min_${columnName}"`}
onClick={() => {
onQueryChange(
parsedQuery.addAggregateColumn(columnName, 'MIN', aliasFactory(`min_${columnName}`)),
parsedQuery.addAggregateColumn(
[SqlRef.fromNameWithDoubleQuotes(columnName)],
'MIN',
`min_${columnName}`,
),
true,
);
}}

View File

@ -27,7 +27,7 @@ import {
Tree,
} from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { refExpressionFactory, SqlQuery, stringFactory } from 'druid-query-toolkit';
import { SqlQuery } from 'druid-query-toolkit';
import React, { ChangeEvent } from 'react';
import { Loader } from '../../../components';
@ -184,12 +184,7 @@ export class ColumnTree extends React.PureComponent<ColumnTreeProps, ColumnTreeS
icon={IconNames.EXCHANGE}
text={`Replace FROM with: ${table}`}
onClick={() => {
props.onQueryStringChange(
parsedQuery.replaceFrom(
refExpressionFactory(stringFactory(table, `"`)),
),
true,
);
props.onQueryStringChange(parsedQuery.replaceFrom(table), true);
}}
/>
)}

View File

@ -74,7 +74,7 @@ exports[`query output matches snapshot 1`] = `
/>
</div>
<div
class="rt-th aggregate-header rt-resizable-header"
class="rt-th aggregate-header rt-resizable-header"
role="columnheader"
style="flex: 100 0 auto; width: 100px;"
tabindex="-1"
@ -101,7 +101,7 @@ exports[`query output matches snapshot 1`] = `
/>
</div>
<div
class="rt-th aggregate-header rt-resizable-header"
class="rt-th aggregate-header rt-resizable-header"
role="columnheader"
style="flex: 100 0 auto; width: 100px;"
tabindex="-1"

View File

@ -19,10 +19,7 @@
import { Menu, MenuItem, Popover } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import { HeaderRows, SqlQuery } from 'druid-query-toolkit';
import {
basicIdentifierEscape,
basicLiteralEscape,
} from 'druid-query-toolkit/build/ast/sql-query/helpers';
import { basicIdentifierEscape, basicLiteralEscape } from 'druid-query-toolkit/build/sql/helpers';
import React, { useState } from 'react';
import ReactTable from 'react-table';
@ -94,7 +91,7 @@ export const QueryOutput = React.memo(function QueryOutput(props: QueryOutputPro
icon: IconNames.CROSS,
title: `Remove: ${trimValue(header)}`,
onAction: () => {
onQueryChange(parsedQuery.excludeColumn(header), true);
onQueryChange(parsedQuery.remove(header), true);
},
});
@ -161,14 +158,14 @@ export const QueryOutput = React.memo(function QueryOutput(props: QueryOutputPro
icon={IconNames.FILTER_KEEP}
text={`Filter by: ${trimValue(header)} = ${trimValue(value)}`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(header, value, '='), true);
onQueryChange(parsedQuery.addWhereFilter(header, '=', value), true);
}}
/>
<MenuItem
icon={IconNames.FILTER_REMOVE}
text={`Filter by: ${trimValue(header)} != ${trimValue(value)}`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(header, value, '!='), true);
onQueryChange(parsedQuery.addWhereFilter(header, '!=', value), true);
}}
/>
{!isNaN(Number(value)) && (
@ -177,14 +174,14 @@ export const QueryOutput = React.memo(function QueryOutput(props: QueryOutputPro
icon={IconNames.FILTER_KEEP}
text={`Filter by: ${trimValue(header)} >= ${trimValue(value)}`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(header, value, '>='), true);
onQueryChange(parsedQuery.addWhereFilter(header, '>=', value), true);
}}
/>
<MenuItem
icon={IconNames.FILTER_KEEP}
text={`Filter by: ${trimValue(header)} <= ${trimValue(value)}`}
onClick={() => {
onQueryChange(parsedQuery.filterRow(header, value, '<='), true);
onQueryChange(parsedQuery.addWhereFilter(header, '<=', value), true);
}}
/>
</>
@ -236,27 +233,23 @@ export const QueryOutput = React.memo(function QueryOutput(props: QueryOutputPro
function getHeaderClassName(header: string) {
const { parsedQuery } = props;
if (!parsedQuery) return;
const className = [];
if (parsedQuery) {
const sorted = parsedQuery.getSorted();
if (sorted) {
className.push(
sorted.map(sorted => {
if (sorted.id === header) {
return sorted.desc ? '-sort-desc' : '-sort-asc';
}
return '';
})[0],
);
}
const sorted = parsedQuery.getSorted();
const aggregateColumns = parsedQuery.getAggregateColumns();
const aggregateColumns = parsedQuery.getAggregateColumns();
if (aggregateColumns && aggregateColumns.includes(header)) {
className.push('aggregate-header');
if (sorted) {
const sortedColumnNames = sorted.map(column => column.id);
if (sortedColumnNames.includes(header)) {
className.push(sorted[sortedColumnNames.indexOf(header)].desc ? '-sort-desc' : '-sort-asc');
}
}
if (aggregateColumns && aggregateColumns.includes(header)) {
className.push('aggregate-header');
}
return className.join(' ');
}