Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ export const ControlPane = function ControlPane(props: ControlPaneProps) {
: filterMap(effectiveValue as ExpressionMeta[], ({ expression }) =>
expression instanceof SqlColumn ? expression.getName() : undefined,
);

return {
element: (
<NamedExpressionsInput<ExpressionMeta>
Expand Down Expand Up @@ -295,6 +296,10 @@ export const ControlPane = function ControlPane(props: ControlPaneProps) {
}

case 'measures': {
const disabledMeasureNames = parameter.allowDuplicates
? []
: filterMap(effectiveValue as Measure[], measure => measure.getAggregateMeasureName());

return {
element: (
<NamedExpressionsInput<Measure>
Expand All @@ -307,6 +312,7 @@ export const ControlPane = function ControlPane(props: ControlPaneProps) {
columns={columns}
measures={measures}
initMeasure={initMeasure}
disabledMeasureNames={disabledMeasureNames}
onSelectMeasure={m => onValueChange(changeOrAdd(effectiveValue, initMeasure, m))}
onClose={onClose}
onAddToSourceQueryAsMeasure={onAddToSourceQueryAsMeasure}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,25 @@ export interface MeasureMenuProps {
columns: readonly Column[];
measures: readonly Measure[];
initMeasure: Measure | undefined;
disabledMeasureNames?: string[];
onSelectMeasure(measure: Measure): void;
onClose(): void;
onAddToSourceQueryAsMeasure?(measure: Measure): void;
}

export const MeasureMenu = function MeasureMenu(props: MeasureMenuProps) {
const { columns, measures, initMeasure, onSelectMeasure, onClose, onAddToSourceQueryAsMeasure } =
props;
const {
columns,
measures,
initMeasure,
disabledMeasureNames = [],
onSelectMeasure,
onClose,
onAddToSourceQueryAsMeasure,
} = props;

const [tab, setTab] = useState<MeasureMenuTab>(() => {
if (!initMeasure) return 'compose';
if (!initMeasure) return measures.length > 1 ? 'saved' : 'compose';
if (measures.some(measure => measure.equivalent(initMeasure))) return 'saved';
return MeasurePattern.fit(initMeasure.expression) ? 'compose' : 'sql';
});
Expand Down Expand Up @@ -165,8 +173,9 @@ export const MeasureMenu = function MeasureMenu(props: MeasureMenuProps) {
return (
<MenuItem
key={i}
icon={IconNames.NUMERICAL}
icon={IconNames.PULSE}
text={aggregateMeasure.name}
disabled={disabledMeasureNames.includes(measure.name)}
labelElement={
aggregateMeasure.equals(initMeasure) ? <Icon icon={IconNames.TICK} /> : undefined
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

import { FormGroup, InputGroup, Menu, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import type { ContainsFilterPattern, QueryResult } from '@druid-toolkit/query';
import { C, F, filterPatternToExpression, SqlExpression, SqlQuery } from '@druid-toolkit/query';
import type { ContainsFilterPattern, QueryResult, SqlQuery } from '@druid-toolkit/query';
import { C, F, filterPatternToExpression, SqlExpression } from '@druid-toolkit/query';
import React, { useMemo } from 'react';

import { useQueryManager } from '../../../../../../hooks';
Expand All @@ -43,14 +43,14 @@ export const ContainsFilterControl = React.memo(function ContainsFilterControl(

const previewQuery = useMemo(
() =>
SqlQuery.from(querySource.query)
.addSelect(F.cast(C(column), 'VARCHAR').as('c'), { addToGroupBy: 'end' })
.changeWhereExpression(
querySource
.getInitQuery(
SqlExpression.and(
filter,
contains ? filterPatternToExpression(filterPattern) : undefined,
),
)
.addSelect(F.cast(C(column), 'VARCHAR').as('c'), { addToGroupBy: 'end' })
.changeOrderByExpression(F.count().toOrderByExpression('DESC'))
.changeLimitValue(101)
.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

import { FormGroup, InputGroup, Menu, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import type { QueryResult, RegexpFilterPattern } from '@druid-toolkit/query';
import { C, F, filterPatternToExpression, SqlExpression, SqlQuery } from '@druid-toolkit/query';
import type { QueryResult, RegexpFilterPattern, SqlQuery } from '@druid-toolkit/query';
import { C, F, filterPatternToExpression, SqlExpression } from '@druid-toolkit/query';
import React, { useMemo } from 'react';

import { useQueryManager } from '../../../../../../hooks';
Expand Down Expand Up @@ -52,11 +52,11 @@ export const RegexpFilterControl = React.memo(function RegexpFilterControl(

const previewQuery = useMemo(
() =>
SqlQuery.from(querySource.query)
.addSelect(F.cast(C(column), 'VARCHAR').as('c'), { addToGroupBy: 'end' })
.changeWhereExpression(
querySource
.getInitQuery(
SqlExpression.and(filter, regexp ? filterPatternToExpression(filterPattern) : undefined),
)
.addSelect(F.cast(C(column), 'VARCHAR').as('c'), { addToGroupBy: 'end' })
.changeOrderByExpression(F.count().toOrderByExpression('DESC'))
.changeLimitValue(101)
.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

import { FormGroup, Menu, MenuItem } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import type { QueryResult, ValuesFilterPattern } from '@druid-toolkit/query';
import { C, F, SqlExpression, SqlQuery } from '@druid-toolkit/query';
import type { QueryResult, SqlQuery, ValuesFilterPattern } from '@druid-toolkit/query';
import { C, F, SqlExpression } from '@druid-toolkit/query';
import React, { useMemo, useState } from 'react';

import { ClearableInput } from '../../../../../../components';
Expand Down Expand Up @@ -49,14 +49,14 @@ export const ValuesFilterControl = React.memo(function ValuesFilterControl(

const valuesQuery = useMemo(
() =>
SqlQuery.from(querySource.query)
.addSelect(C(column).as('c'), { addToGroupBy: 'end' })
.changeWhereExpression(
querySource
.getInitQuery(
SqlExpression.and(
filter,
searchString ? F('ICONTAINS_STRING', C(column), searchString) : undefined,
),
)
.addSelect(C(column).as('c'), { addToGroupBy: 'end' })
.changeOrderByExpression(F.count().toOrderByExpression('DESC'))
.changeLimitValue(101)
.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
text-overflow: ellipsis;
padding: 1px 0;
opacity: 0.8;

&.special {
font-style: italic;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
import { Callout } from '@blueprintjs/core';
import type { SqlQuery } from '@druid-toolkit/query';
import { type QueryResult } from '@druid-toolkit/query';
import classNames from 'classnames';
import React from 'react';

import { useQueryManager } from '../../../../hooks';
import { formatEmpty } from '../../../../utils';

import './preview-pane.scss';

Expand Down Expand Up @@ -58,8 +60,11 @@ export const PreviewPane = React.memo(function PreviewPane(props: PreviewPanePro
<div className="preview-values-wrapper">
<div className="preview-values">
{previewValues.map((v, i) => (
<div className="preview-value" key={i}>
{String(v)}
<div
className={classNames('preview-value', { special: v == null || v === '' })}
key={i}
>
{formatEmpty(v)}
</div>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
*/

import { Button, Classes, Dialog, FormGroup, InputGroup, Intent, Tag } from '@blueprintjs/core';
import { type QueryResult, F, sql, SqlExpression, SqlQuery } from '@druid-toolkit/query';
import type { SqlQuery } from '@druid-toolkit/query';
import { type QueryResult, F, sql, SqlExpression } from '@druid-toolkit/query';
import React, { useMemo, useState } from 'react';

import { AppToaster } from '../../../../../singletons';
import { ExpressionMeta, QuerySource } from '../../../models';
import type { QuerySource } from '../../../models';
import { ExpressionMeta } from '../../../models';
import type { Rename } from '../../../utils';
import { PreviewPane } from '../../preview-pane/preview-pane';
import { SqlInput } from '../../sql-input/sql-input';
Expand All @@ -46,7 +48,8 @@ export const ColumnDialog = React.memo(function ColumnDialog(props: ColumnDialog
const previewQuery = useMemo(() => {
const expression = SqlExpression.maybeParse(formula);
if (!expression) return;
return SqlQuery.from(QuerySource.stripToBaseSource(querySource.query))
return querySource
.getInitBaseQuery()
.addSelect(F.cast(expression, 'VARCHAR').as('v'), { addToGroupBy: 'end' })
.applyIf(querySource.hasBaseTimeColumn(), q =>
q.addWhere(sql`MAX_DATA_TIME() - INTERVAL '14' DAY <= __time`),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ import {
Menu,
Tag,
} from '@blueprintjs/core';
import type { SqlExpression } from '@druid-toolkit/query';
import { type QueryResult, F, sql, SqlFunction, SqlQuery } from '@druid-toolkit/query';
import type { SqlExpression, SqlQuery } from '@druid-toolkit/query';
import { type QueryResult, F, sql, SqlFunction } from '@druid-toolkit/query';
import React, { useState } from 'react';

import { ClearableInput, Loader, MenuCheckbox } from '../../../../../components';
import { useQueryManager } from '../../../../../hooks';
import { caseInsensitiveContains, filterMap, pluralIfNeeded } from '../../../../../utils';
import { ExpressionMeta, QuerySource } from '../../../models';
import type { QuerySource } from '../../../models';
import { ExpressionMeta } from '../../../models';
import { toggle } from '../../../utils';

import './nested-column-dialog.scss';
Expand All @@ -60,7 +61,8 @@ export const NestedColumnDialog = React.memo(function NestedColumnDialog(
const [pathsState] = useQueryManager({
query: nestedColumn,
processQuery: async nestedColumn => {
const query = SqlQuery.from(QuerySource.stripToBaseSource(querySource.query))
const query = querySource
.getInitBaseQuery()
.addSelect(
SqlFunction.decorated('ARRAY_CONCAT_AGG', 'DISTINCT', [
F('JSON_PATHS', nestedColumn),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ function formatQuerySource(source: SqlQuery | undefined): string | JSX.Element {
if (!(source instanceof SqlQuery)) return 'No source selected';
const fromExpressions = source.getFromExpressions();
if (fromExpressions.length !== 1) return 'Multiple FROM expressions';
const fromExpression = fromExpressions[0];
if (!(fromExpression instanceof SqlTable)) return 'Complex FROM expression';
return fromExpression.getName();
const fromExpression = fromExpressions[0].getUnderlyingExpression();
if (fromExpression instanceof SqlTable) {
return fromExpression.getName();
} else if (fromExpression instanceof SqlQuery) {
return formatQuerySource(fromExpression);
} else {
return 'Complex FROM expression';
}
}

export interface SourcePaneProps {
Expand Down
5 changes: 4 additions & 1 deletion web-console/src/views/explore-view/explore-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ export class ExploreState {
if (!QuerySource.isSingleStarQuery(this.parsedSource)) return this; // Only trigger for `SELECT * FROM ...` queries
if (!this.where.equal(SqlLiteral.TRUE)) return this;

const timeColumn = columns.find(c => c.isTimeColumn());
// Either find the `__time::TIMESTAMP` column or use the first column if it is a TIMESTAMP
const timeColumn =
columns.find(c => c.isTimeColumn()) ||
(columns[0].sqlType === 'TIMESTAMP' ? columns[0] : undefined);
if (!timeColumn) return this;

return this.change({
Expand Down
2 changes: 1 addition & 1 deletion web-console/src/views/explore-view/explore-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export const ExploreView = React.memo(function ExploreView() {
});

// -------------------------------------------------------
// If we have a __time::TIMESTAMP column and no filter add a filter
// If we have a TIMESTAMP column and no filter add a filter

useEffect(() => {
const columns = querySourceState.data?.columns;
Expand Down
4 changes: 4 additions & 0 deletions web-console/src/views/explore-view/models/measure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ export class Measure extends ExpressionMeta {
return this.changeExpression(F(Measure.AGGREGATE, L(this.name)));
}

public getAggregateMeasureName(): string | undefined {
return Measure.getAggregateMeasureName(this.expression);
}

public getUsedAggregates(): string[] {
return uniq(
filterMap(
Expand Down
8 changes: 8 additions & 0 deletions web-console/src/views/explore-view/models/query-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ export class QuerySource {
};
}

public getInitQuery(where?: SqlExpression): SqlQuery {
return SqlQuery.from(this.query.as('t')).changeWhereExpression(where);
}

public getInitBaseQuery(): SqlQuery {
return SqlQuery.from(QuerySource.stripToBaseSource(this.query).as('t'));
}

private materializeStarIfNeeded(): SqlQuery {
const { query, columns, measures } = this;
let columnsToExpand = columns.map(c => c.name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* limitations under the License.
*/

import { L, SqlQuery } from '@druid-toolkit/query';
import { L } from '@druid-toolkit/query';
import type { ECharts } from 'echarts';
import * as echarts from 'echarts';
import React, { useEffect, useMemo, useRef } from 'react';
Expand Down Expand Up @@ -75,11 +75,10 @@ ModuleRepository.registerModule<BarChartParameterValues>({
const { splitColumn, measure, measureToSort, limit } = parameterValues;

const dataQuery = useMemo(() => {
const source = querySource.query;
const splitExpression = splitColumn ? splitColumn.expression : L(OVERALL_LABEL);

return SqlQuery.from(source)
.addWhere(where)
return querySource
.getInitQuery(where)
.addSelect(splitExpression.as('dim'), { addToGroupBy: 'end' })
.addSelect(measure.expression.as('met'), {
addToOrderBy: measureToSort ? undefined : 'end',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*/

import { Button } from '@blueprintjs/core';
import type { SqlExpression, SqlOrderByDirection } from '@druid-toolkit/query';
import { C, F, SqlQuery } from '@druid-toolkit/query';
import type { SqlExpression, SqlOrderByDirection, SqlQuery } from '@druid-toolkit/query';
import { C, F } from '@druid-toolkit/query';
import React, { useMemo } from 'react';

import { Loader } from '../../../components';
Expand Down Expand Up @@ -213,13 +213,14 @@ ModuleRepository.registerModule<GroupingTableParameterValues>({
const maxPivotValues = parameterValues.maxPivotValues || 10;
if (!pivotColumn) return;

return SqlQuery.from(querySource.query)
return querySource
.getInitQuery(where)
.addSelect(pivotColumn.expression.as('v'), { addToGroupBy: 'end' })
.changeOrderByExpression(
(measures.length ? measures[0].expression : F.count()).toOrderByExpression('DESC'),
)
.changeLimitValue(maxPivotValues);
}, [querySource.query, parameterValues]);
}, [querySource, where, parameterValues]);

const [pivotValueState, queryManager] = useQueryManager({
query: pivotValueQuery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
* limitations under the License.
*/

import { C, F, L, SqlQuery } from '@druid-toolkit/query';
import type { SqlQuery } from '@druid-toolkit/query';
import { C, F, L } from '@druid-toolkit/query';
import type { ECharts } from 'echarts';
import * as echarts from 'echarts';
import React, { useEffect, useMemo, useRef } from 'react';
Expand Down Expand Up @@ -82,10 +83,8 @@ ModuleRepository.registerModule<MultiAxisChartParameterValues>({
const { measures } = parameterValues;

const dataQuery = useMemo(() => {
const source = querySource.query;

return SqlQuery.from(source)
.addWhere(where)
return querySource
.getInitQuery(where)
.addSelect(F.timeFloor(C(timeColumnName || '__time'), L(timeGranularity)).as('time'), {
addToGroupBy: 'end',
addToOrderBy: 'end',
Expand Down
Loading