mirror of
https://github.com/apache/superset.git
synced 2026-04-20 00:24:38 +00:00
fix(explore): Dashboard filters on adhoc cols not working in Explore (#23239)
This commit is contained in:
committed by
GitHub
parent
5a099e0762
commit
6076457b90
@@ -70,6 +70,7 @@ import Control from './Control';
|
||||
import { ExploreAlert } from './ExploreAlert';
|
||||
import { RunQueryButton } from './RunQueryButton';
|
||||
import { Operators } from '../constants';
|
||||
import { CLAUSES } from './controls/FilterControl/types';
|
||||
|
||||
const { confirm } = Modal;
|
||||
|
||||
@@ -317,7 +318,7 @@ export const ControlPanelsContainer = (props: ControlPanelsContainerProps) => {
|
||||
setControlValue('adhoc_filters', [
|
||||
...(adhoc_filters || []),
|
||||
{
|
||||
clause: 'WHERE',
|
||||
clause: CLAUSES.WHERE,
|
||||
subject: x_axis,
|
||||
operator: Operators.TEMPORAL_RANGE,
|
||||
comparator: defaultTimeFilter || NO_TIME_RANGE,
|
||||
|
||||
@@ -32,14 +32,13 @@ import { TimeseriesDefaultFormData } from '@superset-ui/plugin-chart-echarts';
|
||||
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import {
|
||||
DndFilterSelect,
|
||||
DndFilterSelectProps,
|
||||
} from 'src/explore/components/controls/DndColumnSelectControl/DndFilterSelect';
|
||||
import { PLACEHOLDER_DATASOURCE } from 'src/dashboard/constants';
|
||||
import { EXPRESSION_TYPES } from '../FilterControl/types';
|
||||
|
||||
const defaultProps: DndFilterSelectProps = {
|
||||
type: 'DndFilterSelect',
|
||||
|
||||
@@ -43,10 +43,7 @@ import { Datasource, OptionSortType } from 'src/explore/types';
|
||||
import { OptionValueType } from 'src/explore/components/controls/DndColumnSelectControl/types';
|
||||
import AdhocFilterPopoverTrigger from 'src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger';
|
||||
import DndSelectLabel from 'src/explore/components/controls/DndColumnSelectControl/DndSelectLabel';
|
||||
import AdhocFilter, {
|
||||
CLAUSES,
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
import {
|
||||
DatasourcePanelDndItem,
|
||||
@@ -58,6 +55,7 @@ import { ControlComponentProps } from 'src/explore/components/Control';
|
||||
import AdhocFilterControl from '../FilterControl/AdhocFilterControl';
|
||||
import DndAdhocFilterOption from './DndAdhocFilterOption';
|
||||
import { useDefaultTimeFilter } from '../DateFilterControl/utils';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../FilterControl/types';
|
||||
|
||||
const { warning } = Modal;
|
||||
|
||||
|
||||
@@ -16,11 +16,9 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import { Operators } from 'src/explore/constants';
|
||||
import { EXPRESSION_TYPES, CLAUSES } from '../types';
|
||||
|
||||
describe('AdhocFilter', () => {
|
||||
it('sets filterOptionName in constructor', () => {
|
||||
|
||||
@@ -21,60 +21,13 @@ import {
|
||||
Operators,
|
||||
OPERATOR_ENUM_TO_OPERATOR_TYPE,
|
||||
} from 'src/explore/constants';
|
||||
import { getSimpleSQLExpression } from 'src/explore/exploreUtils';
|
||||
|
||||
export const EXPRESSION_TYPES = {
|
||||
SIMPLE: 'SIMPLE',
|
||||
SQL: 'SQL',
|
||||
};
|
||||
|
||||
export const CLAUSES = {
|
||||
HAVING: 'HAVING',
|
||||
WHERE: 'WHERE',
|
||||
};
|
||||
|
||||
const OPERATORS_TO_SQL = {
|
||||
'==': '=',
|
||||
'!=': '<>',
|
||||
'>': '>',
|
||||
'<': '<',
|
||||
'>=': '>=',
|
||||
'<=': '<=',
|
||||
IN: 'IN',
|
||||
'NOT IN': 'NOT IN',
|
||||
LIKE: 'LIKE',
|
||||
ILIKE: 'ILIKE',
|
||||
REGEX: 'REGEX',
|
||||
'IS NOT NULL': 'IS NOT NULL',
|
||||
'IS NULL': 'IS NULL',
|
||||
'IS TRUE': 'IS TRUE',
|
||||
'IS FALSE': 'IS FALSE',
|
||||
'LATEST PARTITION': ({ datasource }) =>
|
||||
`= '{{ presto.latest_partition('${datasource.schema}.${datasource.datasource_name}') }}'`,
|
||||
};
|
||||
import { translateToSql } from '../utils/translateToSQL';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const CUSTOM_OPERATIONS = [...CUSTOM_OPERATORS].map(
|
||||
op => OPERATOR_ENUM_TO_OPERATOR_TYPE[op].operation,
|
||||
);
|
||||
|
||||
function translateToSql(adhocMetric, { useSimple } = {}) {
|
||||
if (adhocMetric.expressionType === EXPRESSION_TYPES.SIMPLE || useSimple) {
|
||||
const { subject, comparator } = adhocMetric;
|
||||
const operator =
|
||||
adhocMetric.operator &&
|
||||
// 'LATEST PARTITION' supported callback only
|
||||
adhocMetric.operator ===
|
||||
OPERATOR_ENUM_TO_OPERATOR_TYPE[Operators.LATEST_PARTITION].operation
|
||||
? OPERATORS_TO_SQL[adhocMetric.operator](adhocMetric)
|
||||
: OPERATORS_TO_SQL[adhocMetric.operator];
|
||||
return getSimpleSQLExpression(subject, operator, comparator);
|
||||
}
|
||||
if (adhocMetric.expressionType === EXPRESSION_TYPES.SQL) {
|
||||
return adhocMetric.sqlExpression;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export default class AdhocFilter {
|
||||
constructor(adhocFilter) {
|
||||
this.expressionType = adhocFilter.expressionType || EXPRESSION_TYPES.SIMPLE;
|
||||
|
||||
@@ -22,10 +22,7 @@ import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { supersetTheme } from '@superset-ui/core';
|
||||
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import { LabelsContainer } from 'src/explore/components/controls/OptionControls';
|
||||
import {
|
||||
AGGREGATES,
|
||||
@@ -34,6 +31,7 @@ import {
|
||||
} from 'src/explore/constants';
|
||||
import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
import AdhocFilterControl from '.';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const simpleAdhocFilter = new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
|
||||
@@ -45,12 +45,10 @@ import Icons from 'src/components/Icons';
|
||||
import Modal from 'src/components/Modal';
|
||||
import AdhocFilterPopoverTrigger from 'src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger';
|
||||
import AdhocFilterOption from 'src/explore/components/controls/FilterControl/AdhocFilterOption';
|
||||
import AdhocFilter, {
|
||||
CLAUSES,
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import adhocFilterType from 'src/explore/components/controls/FilterControl/adhocFilterType';
|
||||
import columnType from 'src/explore/components/controls/FilterControl/columnType';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const { warning } = Modal;
|
||||
|
||||
|
||||
@@ -24,15 +24,13 @@ import Button from 'src/components/Button';
|
||||
|
||||
import ErrorBoundary from 'src/components/ErrorBoundary';
|
||||
import Tabs from 'src/components/Tabs';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import { AGGREGATES } from 'src/explore/constants';
|
||||
import AdhocFilterEditPopoverSimpleTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent';
|
||||
import AdhocFilterEditPopoverSqlTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent';
|
||||
import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
|
||||
import AdhocFilterEditPopover from '.';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const simpleAdhocFilter = new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
|
||||
@@ -24,9 +24,7 @@ import { styled, t } from '@superset-ui/core';
|
||||
import ErrorBoundary from 'src/components/ErrorBoundary';
|
||||
import Tabs from 'src/components/Tabs';
|
||||
import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilterEditPopoverSimpleTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent';
|
||||
import AdhocFilterEditPopoverSqlTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent';
|
||||
import columnType from 'src/explore/components/controls/FilterControl/columnType';
|
||||
@@ -34,6 +32,7 @@ import {
|
||||
POPOVER_INITIAL_HEIGHT,
|
||||
POPOVER_INITIAL_WIDTH,
|
||||
} from 'src/explore/constants';
|
||||
import { EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const propTypes = {
|
||||
adhocFilter: PropTypes.instanceOf(AdhocFilter).isRequired,
|
||||
|
||||
@@ -25,10 +25,7 @@ import thunk from 'redux-thunk';
|
||||
import { Provider } from 'react-redux';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import {
|
||||
AGGREGATES,
|
||||
Operators,
|
||||
@@ -46,6 +43,7 @@ import AdhocFilterEditPopoverSimpleTabContent, {
|
||||
useSimpleTabFilterProps,
|
||||
Props,
|
||||
} from '.';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const simpleAdhocFilter = new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
|
||||
@@ -38,10 +38,7 @@ import {
|
||||
OPERATOR_ENUM_TO_OPERATOR_TYPE,
|
||||
} from 'src/explore/constants';
|
||||
import FilterDefinitionOption from 'src/explore/components/controls/MetricControl/FilterDefinitionOption';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { Input } from 'src/components/Input';
|
||||
import { optionLabel } from 'src/utils/common';
|
||||
@@ -54,6 +51,7 @@ import {
|
||||
import useAdvancedDataTypes from './useAdvancedDataTypes';
|
||||
import { useDatePickerInAdhocFilter } from '../utils';
|
||||
import { useDefaultTimeFilter } from '../../DateFilterControl/utils';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const StyledInput = styled(Input)`
|
||||
margin-bottom: ${({ theme }) => theme.gridUnit * 4}px;
|
||||
|
||||
@@ -21,11 +21,9 @@ import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilterEditPopoverSqlTabContent from '.';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const sqlAdhocFilter = new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
|
||||
@@ -25,10 +25,8 @@ import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
|
||||
|
||||
import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
|
||||
import columnType from 'src/explore/components/controls/FilterControl/columnType';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const propTypes = {
|
||||
adhocFilter: PropTypes.instanceOf(AdhocFilter).isRequired,
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
import React from 'react';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilterOption, { AdhocFilterOptionProps } from '.';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const simpleAdhocFilter = new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
|
||||
@@ -19,11 +19,9 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from 'spec/helpers/testing-library';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import AdhocFilter, {
|
||||
EXPRESSION_TYPES,
|
||||
CLAUSES,
|
||||
} from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter';
|
||||
import AdhocFilterPopoverTrigger from '.';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
const simpleAdhocFilter = new AdhocFilter({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import PropTypes from 'prop-types';
|
||||
import { EXPRESSION_TYPES, CLAUSES } from './AdhocFilter';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from './types';
|
||||
|
||||
export default PropTypes.oneOfType([
|
||||
PropTypes.shape({
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
export enum EXPRESSION_TYPES {
|
||||
SIMPLE = 'SIMPLE',
|
||||
SQL = 'SQL',
|
||||
}
|
||||
|
||||
export enum CLAUSES {
|
||||
HAVING = 'HAVING',
|
||||
WHERE = 'WHERE',
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
AdhocFilter,
|
||||
isFreeFormAdhocFilter,
|
||||
isSimpleAdhocFilter,
|
||||
SimpleAdhocFilter,
|
||||
} from '@superset-ui/core';
|
||||
import {
|
||||
OPERATOR_ENUM_TO_OPERATOR_TYPE,
|
||||
Operators,
|
||||
} from 'src/explore/constants';
|
||||
import { getSimpleSQLExpression } from 'src/explore/exploreUtils';
|
||||
|
||||
export const OPERATORS_TO_SQL = {
|
||||
'==': '=',
|
||||
'!=': '<>',
|
||||
'>': '>',
|
||||
'<': '<',
|
||||
'>=': '>=',
|
||||
'<=': '<=',
|
||||
IN: 'IN',
|
||||
'NOT IN': 'NOT IN',
|
||||
LIKE: 'LIKE',
|
||||
ILIKE: 'ILIKE',
|
||||
REGEX: 'REGEX',
|
||||
'IS NOT NULL': 'IS NOT NULL',
|
||||
'IS NULL': 'IS NULL',
|
||||
'IS TRUE': 'IS TRUE',
|
||||
'IS FALSE': 'IS FALSE',
|
||||
'LATEST PARTITION': ({
|
||||
datasource,
|
||||
}: {
|
||||
datasource: { schema: string; datasource_name: string };
|
||||
}) =>
|
||||
`= '{{ presto.latest_partition('${datasource.schema}.${datasource.datasource_name}') }}'`,
|
||||
};
|
||||
|
||||
export const translateToSql = (
|
||||
adhocFilter: AdhocFilter,
|
||||
{ useSimple }: { useSimple: boolean } = { useSimple: false },
|
||||
) => {
|
||||
if (isSimpleAdhocFilter(adhocFilter) || useSimple) {
|
||||
const { subject, operator } = adhocFilter as SimpleAdhocFilter;
|
||||
const comparator =
|
||||
'comparator' in adhocFilter ? adhocFilter.comparator : undefined;
|
||||
const op =
|
||||
operator &&
|
||||
// 'LATEST PARTITION' supported callback only
|
||||
operator ===
|
||||
OPERATOR_ENUM_TO_OPERATOR_TYPE[Operators.LATEST_PARTITION].operation
|
||||
? OPERATORS_TO_SQL[operator](adhocFilter)
|
||||
: OPERATORS_TO_SQL[operator];
|
||||
return getSimpleSQLExpression(subject, op, comparator);
|
||||
}
|
||||
if (isFreeFormAdhocFilter(adhocFilter)) {
|
||||
return adhocFilter.sqlExpression;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
@@ -21,7 +21,8 @@ import { NO_TIME_RANGE } from '@superset-ui/core';
|
||||
import { Operators } from 'src/explore/constants';
|
||||
import * as FetchTimeRangeModule from 'src/explore/components/controls/DateFilterControl';
|
||||
import { useGetTimeRangeLabel } from './useGetTimeRangeLabel';
|
||||
import AdhocFilter, { CLAUSES, EXPRESSION_TYPES } from '../AdhocFilter';
|
||||
import AdhocFilter from '../AdhocFilter';
|
||||
import { CLAUSES, EXPRESSION_TYPES } from '../types';
|
||||
|
||||
test('should return empty object if operator is not TEMPORAL_RANGE', () => {
|
||||
const adhocFilter = new AdhocFilter({
|
||||
|
||||
@@ -20,7 +20,8 @@ import { useEffect, useState } from 'react';
|
||||
import { NO_TIME_RANGE } from '@superset-ui/core';
|
||||
import { fetchTimeRange } from 'src/explore/components/controls/DateFilterControl';
|
||||
import { Operators } from 'src/explore/constants';
|
||||
import AdhocFilter, { EXPRESSION_TYPES } from '../AdhocFilter';
|
||||
import AdhocFilter from '../AdhocFilter';
|
||||
import { EXPRESSION_TYPES } from '../types';
|
||||
|
||||
interface Results {
|
||||
actualTimeRange?: string;
|
||||
|
||||
@@ -129,6 +129,15 @@ const getDashboardFormData = (overrides: JsonObject = {}) => ({
|
||||
op: '<=',
|
||||
val: 10000,
|
||||
},
|
||||
{
|
||||
col: {
|
||||
sqlExpression: 'totally viable sql expression',
|
||||
expressionType: 'SQL',
|
||||
label: 'My column',
|
||||
},
|
||||
op: 'IN',
|
||||
val: ['Value1', 'Value2'],
|
||||
},
|
||||
],
|
||||
granularity_sqla: 'ds',
|
||||
time_range: 'Last month',
|
||||
@@ -179,6 +188,7 @@ const getExpectedResultFormData = (overrides: JsonObject = {}) => ({
|
||||
clause: 'WHERE',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'IN',
|
||||
operatorId: 'IN',
|
||||
subject: 'name',
|
||||
comparator: ['Aaron'],
|
||||
isExtra: true,
|
||||
@@ -188,11 +198,19 @@ const getExpectedResultFormData = (overrides: JsonObject = {}) => ({
|
||||
clause: 'WHERE',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '<=',
|
||||
operatorId: 'LESS_THAN_OR_EQUAL',
|
||||
subject: 'num_boys',
|
||||
comparator: 10000,
|
||||
isExtra: true,
|
||||
filterOptionName: expect.any(String),
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
expressionType: 'SQL',
|
||||
sqlExpression: `(totally viable sql expression) IN ('Value1', 'Value2')`,
|
||||
filterOptionName: expect.any(String),
|
||||
isExtra: true,
|
||||
},
|
||||
],
|
||||
adhoc_filters_b: [
|
||||
{
|
||||
@@ -208,6 +226,7 @@ const getExpectedResultFormData = (overrides: JsonObject = {}) => ({
|
||||
clause: 'WHERE',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: 'IN',
|
||||
operatorId: 'IN',
|
||||
subject: 'name',
|
||||
comparator: ['Aaron'],
|
||||
isExtra: true,
|
||||
@@ -217,11 +236,19 @@ const getExpectedResultFormData = (overrides: JsonObject = {}) => ({
|
||||
clause: 'WHERE',
|
||||
expressionType: 'SIMPLE',
|
||||
operator: '<=',
|
||||
operatorId: 'LESS_THAN_OR_EQUAL',
|
||||
subject: 'num_boys',
|
||||
comparator: 10000,
|
||||
isExtra: true,
|
||||
filterOptionName: expect.any(String),
|
||||
},
|
||||
{
|
||||
clause: 'WHERE',
|
||||
expressionType: 'SQL',
|
||||
sqlExpression: `(totally viable sql expression) IN ('Value1', 'Value2')`,
|
||||
filterOptionName: expect.any(String),
|
||||
isExtra: true,
|
||||
},
|
||||
],
|
||||
applied_time_extras: {
|
||||
__time_grain: 'P1D',
|
||||
@@ -282,6 +309,15 @@ const getExpectedResultFormData = (overrides: JsonObject = {}) => ({
|
||||
op: '<=',
|
||||
val: 10000,
|
||||
},
|
||||
{
|
||||
col: {
|
||||
expressionType: 'SQL',
|
||||
label: 'My column',
|
||||
sqlExpression: 'totally viable sql expression',
|
||||
},
|
||||
op: 'IN',
|
||||
val: ['Value1', 'Value2'],
|
||||
},
|
||||
],
|
||||
granularity_sqla: 'ds',
|
||||
time_range: 'Last month',
|
||||
|
||||
@@ -18,31 +18,55 @@
|
||||
*/
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import {
|
||||
EXTRA_FORM_DATA_OVERRIDE_REGULAR_MAPPINGS,
|
||||
EXTRA_FORM_DATA_OVERRIDE_EXTRA_KEYS,
|
||||
isDefined,
|
||||
JsonObject,
|
||||
ensureIsArray,
|
||||
QueryObjectFilterClause,
|
||||
SimpleAdhocFilter,
|
||||
QueryFormData,
|
||||
AdhocFilter,
|
||||
ensureIsArray,
|
||||
EXTRA_FORM_DATA_OVERRIDE_EXTRA_KEYS,
|
||||
EXTRA_FORM_DATA_OVERRIDE_REGULAR_MAPPINGS,
|
||||
isAdhocColumn,
|
||||
isDefined,
|
||||
isFreeFormAdhocFilter,
|
||||
isSimpleAdhocFilter,
|
||||
JsonObject,
|
||||
NO_TIME_RANGE,
|
||||
QueryFormData,
|
||||
QueryObjectFilterClause,
|
||||
SimpleAdhocFilter,
|
||||
} from '@superset-ui/core';
|
||||
import { OPERATOR_ENUM_TO_OPERATOR_TYPE } from '../constants';
|
||||
import { translateToSql } from '../components/controls/FilterControl/utils/translateToSQL';
|
||||
import {
|
||||
CLAUSES,
|
||||
EXPRESSION_TYPES,
|
||||
} from '../components/controls/FilterControl/types';
|
||||
|
||||
const simpleFilterToAdhoc = (
|
||||
filterClause: QueryObjectFilterClause,
|
||||
clause = 'where',
|
||||
clause: CLAUSES = CLAUSES.WHERE,
|
||||
) => {
|
||||
const result = {
|
||||
clause: clause.toUpperCase(),
|
||||
expressionType: 'SIMPLE',
|
||||
operator: filterClause.op,
|
||||
subject: filterClause.col,
|
||||
comparator: 'val' in filterClause ? filterClause.val : undefined,
|
||||
} as SimpleAdhocFilter;
|
||||
let result: AdhocFilter;
|
||||
if (isAdhocColumn(filterClause.col)) {
|
||||
result = {
|
||||
expressionType: 'SQL',
|
||||
clause,
|
||||
sqlExpression: translateToSql({
|
||||
expressionType: EXPRESSION_TYPES.SIMPLE,
|
||||
subject: `(${filterClause.col.sqlExpression})`,
|
||||
operator: filterClause.op,
|
||||
comparator: 'val' in filterClause ? filterClause.val : undefined,
|
||||
} as SimpleAdhocFilter),
|
||||
};
|
||||
} else {
|
||||
result = {
|
||||
expressionType: 'SIMPLE',
|
||||
clause,
|
||||
operator: filterClause.op,
|
||||
operatorId: Object.entries(OPERATOR_ENUM_TO_OPERATOR_TYPE).find(
|
||||
operatorEntry => operatorEntry[1].operation === filterClause.op,
|
||||
)?.[0],
|
||||
subject: filterClause.col,
|
||||
comparator: 'val' in filterClause ? filterClause.val : undefined,
|
||||
} as SimpleAdhocFilter;
|
||||
}
|
||||
if (filterClause.isExtra) {
|
||||
Object.assign(result, {
|
||||
isExtra: true,
|
||||
|
||||
@@ -25,6 +25,10 @@ import {
|
||||
ExtraFormData,
|
||||
} from '@superset-ui/core';
|
||||
import { FALSE_STRING, NULL_STRING, TRUE_STRING } from 'src/utils/common';
|
||||
import {
|
||||
CLAUSES,
|
||||
EXPRESSION_TYPES,
|
||||
} from '../explore/components/controls/FilterControl/types';
|
||||
|
||||
export const getSelectExtraFormData = (
|
||||
col: string,
|
||||
@@ -36,8 +40,8 @@ export const getSelectExtraFormData = (
|
||||
if (emptyFilter) {
|
||||
extra.adhoc_filters = [
|
||||
{
|
||||
expressionType: 'SQL',
|
||||
clause: 'WHERE',
|
||||
expressionType: EXPRESSION_TYPES.SQL,
|
||||
clause: CLAUSES.WHERE,
|
||||
sqlExpression: '1 = 0',
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user