chore: removing Druid from front- and back- end (#20338)

* first pass at removing native Druid nosql

* removing having_druid

* addressing comments, linting

* fixed all tests

* addressing comments

* redirected to ui-core TimeGranularity type

* query form metric linting

* fixed broken chart type

* implementing feedback
This commit is contained in:
AAfghahi 2022-07-08 11:57:03 -04:00 committed by GitHub
parent 9856d88c03
commit 0ce0c6e1eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 65 additions and 454 deletions

View File

@ -31,7 +31,6 @@ export const TIME_FILTER_LABELS = {
time_range: t('Time Range'),
granularity_sqla: t('Time Column'),
time_grain_sqla: t('Time Grain'),
druid_time_origin: t('Origin'),
granularity: t('Time Granularity'),
};

View File

@ -32,7 +32,6 @@ export const legacyTimeseriesTime: ControlPanelSectionConfig = {
...baseTimeSection,
controlSetRows: [
['granularity'],
['druid_time_origin'],
['granularity_sqla'],
['time_grain_sqla'],
['time_range'],

View File

@ -241,21 +241,6 @@ const columnsControl: typeof groupByControl = {
description: t('One or many columns to pivot as columns'),
};
const druid_time_origin: SharedControlConfig<'SelectControl'> = {
type: 'SelectControl',
freeForm: true,
label: TIME_FILTER_LABELS.druid_time_origin,
choices: [
['', 'default'],
['now', 'now'],
],
default: null,
description: t(
'Defines the origin where time buckets start, ' +
'accepts natural dates as in `now`, `sunday` or `1970-01-01`',
),
};
const granularity: SharedControlConfig<'SelectControl'> = {
type: 'SelectControl',
freeForm: true,
@ -569,7 +554,6 @@ const sharedControls = {
secondary_metric: enableExploreDnd ? dnd_secondary_metric : secondary_metric,
groupby: enableExploreDnd ? dndGroupByControl : groupByControl,
columns: enableExploreDnd ? dndColumnsControl : columnsControl,
druid_time_origin,
granularity,
granularity_sqla: enableExploreDnd ? dnd_granularity_sqla : granularity_sqla,
time_grain_sqla,

View File

@ -20,14 +20,16 @@
/* eslint-disable camelcase */
import {
AdhocFilter,
QueryFieldAliases,
QueryFormColumn,
QueryFormData,
QueryObject,
QueryObjectFilterClause,
isPhysicalColumn,
isAdhocColumn,
} from './types';
import {
QueryFieldAliases,
QueryFormColumn,
QueryFormData,
} from './types/QueryFormData';
import processFilters from './processFilters';
import extractExtras from './extractExtras';
import extractQueryFields from './extractQueryFields';

View File

@ -27,7 +27,7 @@ import {
export const DTTM_ALIAS = '__timestamp';
export const EXTRA_FORM_DATA_OVERRIDE_EXTRA_KEYS: (keyof ExtraFormDataOverrideExtras)[] =
['druid_time_origin', 'relative_start', 'relative_end', 'time_grain_sqla'];
['relative_start', 'relative_end', 'time_grain_sqla'];
export const EXTRA_FORM_DATA_APPEND_KEYS: (keyof ExtraFormDataAppend)[] = [
'adhoc_filters',

View File

@ -18,10 +18,9 @@
*/
/* eslint-disable camelcase */
import { TimeGranularity, QueryFormData } from '@superset-ui/core';
import {
AppliedTimeExtras,
isDruidFormData,
QueryFormData,
QueryObjectExtras,
QueryObjectFilterClause,
TimeColumnConfigKey,
@ -30,8 +29,7 @@ import {
type ExtraFilterQueryField = {
time_range?: string;
granularity_sqla?: string;
time_grain_sqla?: string;
druid_time_origin?: string;
time_grain_sqla?: TimeGranularity;
granularity?: string;
};
@ -58,7 +56,6 @@ export default function extractExtras(formData: QueryFormData): ExtractedExtra {
__time_range: 'time_range',
__time_col: 'granularity_sqla',
__time_grain: 'time_grain_sqla',
__time_origin: 'druid_time_origin',
__granularity: 'granularity',
};
@ -66,28 +63,21 @@ export default function extractExtras(formData: QueryFormData): ExtractedExtra {
if (filter.col in reservedColumnsToQueryField) {
const key = filter.col as TimeColumnConfigKey;
const queryField = reservedColumnsToQueryField[key];
extract[queryField] = filter.val as string;
extract[queryField] = filter.val as TimeGranularity;
applied_time_extras[key] = filter.val as string;
} else {
filters.push(filter);
}
});
// map to undeprecated names and remove deprecated fields
if (isDruidFormData(formData) && !extract.druid_time_origin) {
extras.druid_time_origin = formData.druid_time_origin;
delete extract.druid_time_origin;
} else {
// SQL
extras.time_grain_sqla =
extract.time_grain_sqla || formData.time_grain_sqla;
extract.granularity =
extract.granularity_sqla ||
formData.granularity ||
formData.granularity_sqla;
delete extract.granularity_sqla;
delete extract.time_grain_sqla;
}
// SQL
extras.time_grain_sqla = extract.time_grain_sqla || formData.time_grain_sqla;
extract.granularity =
extract.granularity_sqla ||
formData.granularity ||
formData.granularity_sqla;
delete extract.granularity_sqla;
delete extract.time_grain_sqla;
return extract;
}

View File

@ -18,7 +18,7 @@
*/
/* eslint-disable no-underscore-dangle */
import { QueryFormData } from './types';
import { QueryFormData } from '@superset-ui/core';
import { TimeGranularity } from '../time-format';
export default function extractTimegrain(

View File

@ -17,7 +17,7 @@
* under the License.
*/
import { isAdhocMetricSimple, isSavedMetric, QueryFormMetric } from './types';
import { QueryFormMetric, isSavedMetric, isAdhocMetricSimple } from './types';
export default function getMetricLabel(metric: QueryFormMetric): string {
if (isSavedMetric(metric)) {

View File

@ -69,7 +69,6 @@ export default function processFilters(
// some filter-related fields need to go in `extras`
extras.having = freeformHaving.map(sanitizeClause).join(' AND ');
extras.having_druid = simpleHaving;
extras.where = freeformWhere.map(sanitizeClause).join(' AND ');
return {

View File

@ -82,7 +82,6 @@ export type Filter = {
adhoc_filters?: AdhocFilter[];
granularity_sqla?: string;
granularity?: string;
druid_time_origin?: string;
time_grain_sqla?: string;
time_range?: string;
requiredFirst?: boolean;

View File

@ -122,7 +122,7 @@ export type PostProcessingPivot = _PostProcessingPivot | DefaultPostProcessing;
interface _PostProcessingProphet {
operation: 'prophet';
options: {
time_grain: TimeGranularity;
time_grain: TimeGranularity | undefined;
periods: number;
confidence_interval: number;
yearly_seasonality?: boolean | number;

View File

@ -52,8 +52,6 @@ export type QueryObjectFilterClause = {
export type QueryObjectExtras = Partial<{
/** HAVING condition for Druid */
having_druid?: string;
druid_time_origin?: string;
/** HAVING condition for SQLAlchemy */
having?: string;
relative_start?: string;

View File

@ -122,14 +122,14 @@ export type ExtraFormDataAppend = {
* filter clauses can't be overridden */
export type ExtraFormDataOverrideExtras = Pick<
QueryObjectExtras,
'druid_time_origin' | 'relative_start' | 'relative_end' | 'time_grain_sqla'
'relative_start' | 'relative_end' | 'time_grain_sqla'
>;
/** These parameters override those already present in the form data/query object */
export type ExtraFormDataOverrideRegular = Partial<
Pick<SqlaFormData, 'granularity_sqla'>
> &
Partial<Pick<DruidFormData, 'granularity'>> &
Partial<Pick<SqlaFormData, 'granularity'>> &
Partial<Pick<BaseFormData, 'time_range'>> &
Partial<Pick<QueryObject, 'time_column' | 'time_grain'>>;
@ -194,30 +194,16 @@ export interface SqlaFormData extends BaseFormData {
/**
* Name of the Time Column. Time column is optional.
*/
granularity?: string;
granularity_sqla?: string;
time_grain_sqla?: TimeGranularity;
having?: string;
}
/**
* Form data for Druid datasources.
*/
export interface DruidFormData extends BaseFormData {
granularity?: string;
having_druid?: string;
druid_time_origin?: string;
}
export type QueryFormData = DruidFormData | SqlaFormData;
export type QueryFormData = SqlaFormData;
//---------------------------------------------------
// Type guards
//---------------------------------------------------
export function isDruidFormData(
formData: QueryFormData,
): formData is DruidFormData {
return 'granularity' in formData;
}
export default {};

View File

@ -30,7 +30,6 @@ export type TimeColumnConfigKey =
| '__time_col'
| '__time_grain'
| '__time_range'
| '__time_origin'
| '__granularity';
export type AppliedTimeExtras = Partial<

View File

@ -19,13 +19,14 @@
/* eslint sort-keys: 'off' */
/** The form data defined here is based on default visualizations packaged with Apache Superset */
import { TimeGranularity } from '@superset-ui/core';
export const bigNumberFormData = {
datasource: '3__table',
viz_type: 'big_number',
slice_id: 54,
granularity_sqla: 'ds',
time_grain_sqla: 'P1D',
time_grain_sqla: TimeGranularity.DAY,
time_range: '100 years ago : now',
metric: 'sum__num',
adhoc_filters: [],

View File

@ -16,13 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
import { TimeGranularity } from '@superset-ui/core';
import extractExtras from '../../src/query/extractExtras';
describe('extractExtras', () => {
const baseQueryFormData = {
datasource: '1__table',
granularity_sqla: 'ds',
time_grain_sqla: 'PT1M',
time_grain_sqla: TimeGranularity.MINUTE,
viz_type: 'my_viz',
};

View File

@ -28,7 +28,7 @@ describe('processFilters', () => {
}),
).toEqual(
expect.objectContaining({
extras: { having: '', having_druid: [], where: '' },
extras: { having: '', where: '' },
filters: [],
}),
);
@ -59,7 +59,6 @@ describe('processFilters', () => {
).toEqual({
extras: {
having: '',
having_druid: [],
where: '',
},
filters: [
@ -89,7 +88,6 @@ describe('processFilters', () => {
filters: [],
extras: {
having: '',
having_druid: [],
where: '(1 = 1)',
},
});
@ -115,20 +113,6 @@ describe('processFilters', () => {
operator: '==',
comparator: 'almond',
},
{
expressionType: 'SIMPLE',
clause: 'HAVING',
subject: 'sweetness',
operator: '>',
comparator: '0',
},
{
expressionType: 'SIMPLE',
clause: 'HAVING',
subject: 'sweetness',
operator: '<=',
comparator: '50',
},
{
expressionType: 'SQL',
clause: 'WHERE',
@ -154,18 +138,6 @@ describe('processFilters', () => {
).toEqual({
extras: {
having: '(ice = 25 OR ice = 50) AND (waitTime <= 180 -- comment\n)',
having_druid: [
{
col: 'sweetness',
op: '>',
val: '0',
},
{
col: 'sweetness',
op: '<=',
val: '50',
},
],
where: "(tea = 'jasmine') AND (cup = 'large' -- comment\n)",
},
filters: [

View File

@ -97,7 +97,6 @@ test('should compile query object A', () => {
filters: [],
extras: {
having: '',
having_druid: [],
time_grain_sqla: 'P1W',
where: "(foo in ('a', 'b'))",
},
@ -158,7 +157,6 @@ test('should compile query object B', () => {
filters: [],
extras: {
having: '',
having_druid: [],
time_grain_sqla: 'P1W',
where: "(name in ('c', 'd'))",
},
@ -282,7 +280,6 @@ test('should compile query objects with x-axis', () => {
filters: [],
extras: {
having: '',
having_druid: [],
time_grain_sqla: 'P1W',
where: "(foo in ('a', 'b'))",
},

View File

@ -589,9 +589,6 @@ class DatasourceEditor extends React.PureComponent {
}),
},
errors: [],
isDruid:
props.datasource.type === 'druid' ||
props.datasource.datasource_type === 'druid',
isSqla:
props.datasource.datasource_type === 'table' ||
props.datasource.type === 'table',
@ -1089,20 +1086,6 @@ class DatasourceEditor extends React.PureComponent {
/>
</>
)}
{this.state.isDruid && (
<Field
fieldKey="json"
label={t('JSON')}
description={
<div>
{t('The JSON metric or post aggregation definition.')}
</div>
}
control={
<TextAreaControl language="json" offerEditInModal={false} />
}
/>
)}
</div>
)}
{this.state.datasourceType === DATASOURCE_TYPES.physical.key && (

View File

@ -51,9 +51,6 @@ interface SliceData {
granularity_sqla?: string;
time_grain_sqla?: string;
time_range?: string;
druid_time_origin?: string;
show_druid_time_granularity?: boolean;
show_druid_time_origin?: boolean;
show_sqla_time_column?: boolean;
show_sqla_time_granularity?: boolean;
viz_type: string;
@ -205,12 +202,8 @@ export default function getNativeFilterConfig(
adhoc_filters = [],
datasource = '',
date_filter = false,
druid_time_origin,
filter_configs = [],
granularity,
granularity_sqla,
show_druid_time_granularity = false,
show_druid_time_origin = false,
show_sqla_time_column = false,
show_sqla_time_granularity = false,
time_grain_sqla,
@ -343,96 +336,6 @@ export default function getNativeFilterConfig(
}
filterConfig.push(timeColumnFilter);
}
if (show_druid_time_granularity) {
const { scope, immune }: FilterScopeType =
scopesByChartId[TIME_FILTER_MAP.granularity] ||
DASHBOARD_FILTER_SCOPE_GLOBAL;
const druidGranularityFilter: Filter = {
id: `NATIVE_FILTER-${shortid.generate()}`,
description: 'time grain filter',
controlValues: {},
name: TIME_FILTER_LABELS.granularity,
filterType: FILTER_COMPONENT_FILTER_TYPES.FILTER_TIMEGRAIN,
targets: [
{
datasetId: parseInt(datasource.split('__')[0], 10),
},
],
cascadeParentIds: [],
defaultDataMask: {},
type: NativeFilterType.NATIVE_FILTER,
scope: {
rootPath: scope,
excluded: immune,
},
};
filterBoxToFilterComponentMap[key][TIME_FILTER_MAP.granularity] =
druidGranularityFilter.id;
const dashboardDefaultValues = getDashboardDefaultValues(
key,
TIME_FILTER_MAP.granularity,
);
if (!isEmpty(dashboardDefaultValues)) {
druidGranularityFilter.defaultDataMask = {
extraFormData: {
granularity_sqla: (dashboardDefaultValues ||
granularity) as string,
},
filterState: {
value: setValuesInArray(dashboardDefaultValues, granularity),
},
};
}
filterConfig.push(druidGranularityFilter);
}
if (show_druid_time_origin) {
const { scope, immune }: FilterScopeType =
scopesByChartId[TIME_FILTER_MAP.druid_time_origin] ||
DASHBOARD_FILTER_SCOPE_GLOBAL;
const druidOriginFilter: Filter = {
id: `NATIVE_FILTER-${shortid.generate()}`,
description: 'time column filter',
controlValues: {},
name: TIME_FILTER_LABELS.druid_time_origin,
filterType: FILTER_COMPONENT_FILTER_TYPES.FILTER_TIMECOLUMN,
targets: [
{
datasetId: parseInt(datasource.split('__')[0], 10),
},
],
cascadeParentIds: [],
defaultDataMask: {},
type: NativeFilterType.NATIVE_FILTER,
scope: {
rootPath: scope,
excluded: immune,
},
};
filterBoxToFilterComponentMap[key][
TIME_FILTER_MAP.druid_time_origin
] = druidOriginFilter.id;
const dashboardDefaultValues = getDashboardDefaultValues(
key,
TIME_FILTER_MAP.druid_time_origin,
);
if (!isEmpty(dashboardDefaultValues)) {
druidOriginFilter.defaultDataMask = {
extraFormData: {
granularity_sqla: (dashboardDefaultValues ||
druid_time_origin) as string,
},
filterState: {
value: setValuesInArray(
dashboardDefaultValues,
druid_time_origin,
),
},
};
}
filterConfig.push(druidOriginFilter);
}
}
filter_configs.forEach(config => {

View File

@ -28,7 +28,6 @@ export default function getFilterConfigsFromFormdata(form_data = {}) {
date_filter,
filter_configs = [],
show_druid_time_granularity,
show_druid_time_origin,
show_sqla_time_column,
show_sqla_time_granularity,
} = form_data;
@ -101,13 +100,6 @@ export default function getFilterConfigsFromFormdata(form_data = {}) {
};
}
if (show_druid_time_origin) {
updatedColumns = {
...updatedColumns,
[TIME_FILTER_MAP.druid_time_origin]: form_data.druid_time_origin,
};
}
configs = {
...configs,
columns: updatedColumns,

View File

@ -174,9 +174,7 @@ const isTimeSection = (section: ControlPanelSectionConfig): boolean =>
sections.legacyTimeseriesTime.label === section.label);
const hasTimeColumn = (datasource: Dataset): boolean =>
datasource?.columns?.some(c => c.is_dttm) ||
datasource.type === DatasourceType.Druid;
datasource?.columns?.some(c => c.is_dttm);
const sectionsToExpand = (
sections: ControlPanelSectionConfig[],
datasource: Dataset,

View File

@ -222,14 +222,8 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => {
// via datasource saved metric
if (filterOptions.saved_metric_name) {
return new AdhocFilter({
expressionType:
datasource.type === 'druid'
? EXPRESSION_TYPES.SIMPLE
: EXPRESSION_TYPES.SQL,
subject:
datasource.type === 'druid'
? filterOptions.saved_metric_name
: getMetricExpression(filterOptions.saved_metric_name),
expressionType: EXPRESSION_TYPES.SQL,
subject: getMetricExpression(filterOptions.saved_metric_name),
operator:
OPERATOR_ENUM_TO_OPERATOR_TYPE[Operators.GREATER_THAN].operation,
operatorId: Operators.GREATER_THAN,
@ -240,14 +234,8 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => {
// has a custom label, meaning it's custom column
if (filterOptions.label) {
return new AdhocFilter({
expressionType:
datasource.type === 'druid'
? EXPRESSION_TYPES.SIMPLE
: EXPRESSION_TYPES.SQL,
subject:
datasource.type === 'druid'
? filterOptions.label
: new AdhocMetric(option).translateToSql(),
expressionType: EXPRESSION_TYPES.SQL,
subject: new AdhocMetric(option).translateToSql(),
operator:
OPERATOR_ENUM_TO_OPERATOR_TYPE[Operators.GREATER_THAN].operation,
operatorId: Operators.GREATER_THAN,

View File

@ -241,14 +241,8 @@ class AdhocFilterControl extends React.Component {
// via datasource saved metric
if (option.saved_metric_name) {
return new AdhocFilter({
expressionType:
this.props.datasource.type === 'druid'
? EXPRESSION_TYPES.SIMPLE
: EXPRESSION_TYPES.SQL,
subject:
this.props.datasource.type === 'druid'
? option.saved_metric_name
: this.getMetricExpression(option.saved_metric_name),
expressionType: EXPRESSION_TYPES.SQL,
subject: this.getMetricExpression(option.saved_metric_name),
operator:
OPERATOR_ENUM_TO_OPERATOR_TYPE[Operators.GREATER_THAN].operation,
comparator: 0,
@ -258,14 +252,8 @@ class AdhocFilterControl extends React.Component {
// has a custom label, meaning it's custom column
if (option.label) {
return new AdhocFilter({
expressionType:
this.props.datasource.type === 'druid'
? EXPRESSION_TYPES.SIMPLE
: EXPRESSION_TYPES.SQL,
subject:
this.props.datasource.type === 'druid'
? option.label
: new AdhocMetric(option).translateToSql(),
expressionType: EXPRESSION_TYPES.SQL,
subject: new AdhocMetric(option).translateToSql(),
operator:
OPERATOR_ENUM_TO_OPERATOR_TYPE[Operators.GREATER_THAN].operation,
comparator: 0,

View File

@ -19,7 +19,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Button from 'src/components/Button';
import { Tooltip } from 'src/components/Tooltip';
import { styled, t } from '@superset-ui/core';
import ErrorBoundary from 'src/components/ErrorBoundary';
@ -227,20 +226,7 @@ export default class AdhocFilterEditPopover extends React.Component {
<Tabs.TabPane
className="adhoc-filter-edit-tab"
key={EXPRESSION_TYPES.SQL}
tab={
datasource?.type === 'druid' ? (
<Tooltip
title={t(
'Custom SQL ad-hoc filters are not available for the native Druid connector',
)}
>
{t('Custom SQL')}
</Tooltip>
) : (
t('Custom SQL')
)
}
disabled={datasource?.type === 'druid'}
tab={t('Custom SQL')}
>
<ErrorBoundary>
<AdhocFilterEditPopoverSqlTabContent

View File

@ -235,17 +235,9 @@ describe('AdhocFilterEditPopoverSimpleTabContent', () => {
it('will filter operators for table datasources', () => {
const { props } = setup({ datasource: { type: 'table' } });
const { isOperatorRelevant } = useSimpleTabFilterProps(props);
expect(isOperatorRelevant(Operators.REGEX, 'value')).toBe(false);
expect(isOperatorRelevant(Operators.LIKE, 'value')).toBe(true);
});
it('will filter operators for druid datasources', () => {
const { props } = setup({ datasource: { type: 'druid' } });
const { isOperatorRelevant } = useSimpleTabFilterProps(props);
expect(isOperatorRelevant(Operators.REGEX, 'value')).toBe(true);
expect(isOperatorRelevant(Operators.LIKE, 'value')).toBe(false);
});
it('will show LATEST PARTITION operator', () => {
const { props } = setup({
datasource: {

View File

@ -23,8 +23,6 @@ import { t, SupersetClient, SupersetTheme, styled } from '@superset-ui/core';
import {
Operators,
OPERATORS_OPTIONS,
TABLE_ONLY_OPERATORS,
DRUID_ONLY_OPERATORS,
HAVING_OPERATORS,
MULTI_OPERATORS,
CUSTOM_OPERATORS,
@ -140,13 +138,9 @@ export const useSimpleTabFilterProps = (props: Props) => {
operator === Operators.IS_NULL || operator === Operators.IS_NOT_NULL
);
}
return !(
(props.datasource.type === 'druid' &&
TABLE_ONLY_OPERATORS.indexOf(operator) >= 0) ||
(props.datasource.type === 'table' &&
DRUID_ONLY_OPERATORS.indexOf(operator) >= 0) ||
(props.adhocFilter.clause === CLAUSES.HAVING &&
HAVING_OPERATORS.indexOf(operator) === -1)
return (
props.adhocFilter.clause !== CLAUSES.HAVING ||
HAVING_OPERATORS.indexOf(operator) !== -1
);
};
const onSubjectChange = (id: string) => {
@ -316,23 +310,13 @@ const AdhocFilterEditPopoverSimpleTabContent: React.FC<Props> = props => {
placeholder: '',
};
if (props.datasource.type === 'druid') {
subjectSelectProps.placeholder = t(
'%s column(s) and metric(s)',
columns.length,
);
} else {
// we cannot support simple ad-hoc filters for metrics because we don't know what type
// the value should be cast to (without knowing the output type of the aggregate, which
// becomes a rather complicated problem)
subjectSelectProps.placeholder =
props.adhocFilter.clause === CLAUSES.WHERE
? t('%s column(s)', columns.length)
: t('To filter on a metric, use Custom SQL tab.');
columns = props.options.filter(
option => 'column_name' in option && option.column_name,
);
}
subjectSelectProps.placeholder =
props.adhocFilter.clause === CLAUSES.WHERE
? t('%s column(s)', columns.length)
: t('To filter on a metric, use Custom SQL tab.');
columns = props.options.filter(
option => 'column_name' in option && option.column_name,
);
const operatorSelectProps = {
placeholder: t(

View File

@ -80,18 +80,6 @@ test('Should render correct elements for SQL', () => {
expect(screen.getByRole('tabpanel', { name: 'Saved' })).toBeVisible();
});
test('Should render correct elements for native Druid', () => {
const props = { ...createProps(), datasource: { type: 'druid' } };
render(<AdhocMetricEditPopover {...props} />);
expect(screen.getByRole('tab', { name: 'Custom SQL' })).toHaveAttribute(
'aria-disabled',
'true',
);
expect(screen.getByRole('tab', { name: 'Simple' })).toBeEnabled();
expect(screen.getByRole('tab', { name: 'Saved' })).toBeEnabled();
expect(screen.getByRole('tabpanel', { name: 'Saved' })).toBeVisible();
});
test('Should render correct elements for allow ad-hoc metrics', () => {
const props = {
...createProps(),

View File

@ -323,15 +323,6 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
autoFocus: true,
};
if (
this.props.datasource?.type === 'druid' &&
aggregateSelectProps.options
) {
aggregateSelectProps.options = aggregateSelectProps.options.filter(
aggregate => aggregate !== 'AVG',
);
}
const stateIsValid = adhocMetric.isValid() || savedMetric?.metric_name;
const hasUnsavedChanges =
!adhocMetric.equals(propsAdhocMetric) ||
@ -431,18 +422,11 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
<Tabs.TabPane
key={EXPRESSION_TYPES.SQL}
tab={
extra.disallow_adhoc_metrics ||
this.props.datasource?.type === 'druid' ? (
extra.disallow_adhoc_metrics ? (
<Tooltip
title={
this.props.datasource?.type === 'druid'
? t(
'Custom SQL ad-hoc metrics are not available for the native Druid connector',
)
: t(
'Custom SQL ad-hoc metrics are not enabled for this dataset',
)
}
title={t(
'Custom SQL ad-hoc metrics are not enabled for this dataset',
)}
>
{t('Custom SQL')}
</Tooltip>
@ -451,10 +435,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
)
}
data-test="adhoc-metric-edit-tab#custom"
disabled={
extra.disallow_adhoc_metrics ||
this.props.datasource?.type === 'druid'
}
disabled={extra.disallow_adhoc_metrics}
>
<SQLEditor
data-test="sql-editor"

View File

@ -85,7 +85,6 @@ export const OPERATOR_ENUM_TO_OPERATOR_TYPE: {
export const OPERATORS_OPTIONS = Object.values(Operators) as Operators[];
export const TABLE_ONLY_OPERATORS = [Operators.LIKE, Operators.ILIKE];
export const DRUID_ONLY_OPERATORS = [Operators.REGEX];
export const HAVING_OPERATORS = [
Operators.EQUALS,
Operators.NOT_EQUALS,
@ -119,7 +118,6 @@ export const TIME_FILTER_LABELS = {
time_range: t('Time range'),
granularity_sqla: t('Time column'),
time_grain_sqla: t('Time grain'),
druid_time_origin: t('Origin'),
granularity: t('Time granularity'),
};
@ -141,7 +139,6 @@ export const TIME_FILTER_MAP = {
time_range: '__time_range',
granularity_sqla: '__time_col',
time_grain_sqla: '__time_grain',
druid_time_origin: '__time_origin',
granularity: '__granularity',
};

View File

@ -21,13 +21,6 @@ import { t } from '@superset-ui/core';
import { ControlPanelSectionConfig } from '@superset-ui/chart-controls';
import { formatSelectOptions } from 'src/explore/exploreUtils';
export const druidTimeSeries: ControlPanelSectionConfig = {
label: t('Time'),
expanded: true,
description: t('Time related form attributes'),
controlSetRows: [['time_range']],
};
export const datasourceAndVizType: ControlPanelSectionConfig = {
label: t('Visualization type'),
expanded: true,

View File

@ -57,7 +57,7 @@ const getMemoizedSectionsToRender = memoizeOne(
// list of datasource-specific controls that should be removed
const invalidControls =
datasourceType === 'table'
? ['granularity', 'druid_time_origin']
? ['granularity']
: ['granularity_sqla', 'time_grain_sqla'];
return [datasourceAndVizType]

View File

@ -22,6 +22,7 @@ import {
AdhocMetricSQL,
getChartControlPanelRegistry,
QueryFormData,
TimeGranularity,
} from '@superset-ui/core';
import TableChartPlugin from '@superset-ui/plugin-chart-table';
import { BigNumberTotalChartPlugin } from '@superset-ui/plugin-chart-echarts';
@ -83,7 +84,7 @@ describe('should collect control values and create SFD', () => {
const publicControlsFormData = {
// time section
granularity_sqla: 'time_column',
time_grain_sqla: 'P1D',
time_grain_sqla: TimeGranularity.DAY,
time_range: '2000 : today',
// filters
adhoc_filters: [],
@ -115,6 +116,7 @@ describe('should collect control values and create SFD', () => {
datasource: '100__table',
viz_type: 'source_viz',
};
const sourceMockStore = {
form_data: sourceMockFormData,
controls: Object.fromEntries(
@ -128,6 +130,7 @@ describe('should collect control values and create SFD', () => {
columns: [],
},
};
beforeAll(() => {
getChartControlPanelRegistry().registerValue('source_viz', {
controlPanelSections: [
@ -272,7 +275,7 @@ describe('should transform form_data between table and bigNumberTotal', () => {
datasource: '30__table',
viz_type: 'table',
granularity_sqla: 'ds',
time_grain_sqla: 'P1D',
time_grain_sqla: TimeGranularity.DAY,
time_range: 'No filter',
query_mode: 'aggregate',
groupby: ['name', 'gender', adhocColumn],

View File

@ -145,7 +145,6 @@ export class StandardizedFormData {
if (this.has(vizType)) {
return this.get(vizType);
}
return this.memorizedFormData.slice(-1)[0][1];
}
@ -205,6 +204,7 @@ export class StandardizedFormData {
...getFormDataFromControls(targetControlsState),
standardizedFormData: this.serialize(),
};
let rv = {
formData: targetFormData,
controlsState: targetControlsState,

View File

@ -246,21 +246,6 @@ export const controls = {
description: t('One or many controls to pivot as columns'),
},
druid_time_origin: {
type: 'SelectControl',
freeForm: true,
label: TIME_FILTER_LABELS.druid_time_origin,
choices: [
['', 'default'],
['now', 'now'],
],
default: null,
description: t(
'Defines the origin where time buckets start, ' +
'accepts natural dates as in `now`, `sunday` or `1970-01-01`',
),
},
granularity: {
type: 'SelectControl',
freeForm: true,
@ -286,7 +271,7 @@ export const controls = {
],
description: t(
'The time granularity for the visualization. Note that you ' +
'can type and use simple natural language as in `10 seconds`, ' +
'can type and use simple natural language as in `10 seconds`,' +
'`1 day` or `56 weeks`',
),
},

View File

@ -45,7 +45,6 @@ export function getControlsState(state, inputFormData) {
formData.viz_type || state.common?.conf.DEFAULT_VIZ_TYPE || 'table';
handleDeprecatedControls(formData);
const controlsState = getAllControlsState(
vizType,
state.datasource.type,

View File

@ -81,8 +81,6 @@ const propTypes = {
showDateFilter: PropTypes.bool,
showSqlaTimeGrain: PropTypes.bool,
showSqlaTimeColumn: PropTypes.bool,
showDruidTimeGrain: PropTypes.bool,
showDruidTimeOrigin: PropTypes.bool,
};
const defaultProps = {
origSelectedValues: {},
@ -92,8 +90,6 @@ const defaultProps = {
showDateFilter: false,
showSqlaTimeGrain: false,
showSqlaTimeColumn: false,
showDruidTimeGrain: false,
showDruidTimeOrigin: false,
instantFiltering: false,
};
@ -319,19 +315,12 @@ class FilterBox extends React.PureComponent {
}
renderDatasourceFilters() {
const {
showSqlaTimeGrain,
showSqlaTimeColumn,
showDruidTimeGrain,
showDruidTimeOrigin,
} = this.props;
const { showSqlaTimeGrain, showSqlaTimeColumn } = this.props;
const datasourceFilters = [];
const sqlaFilters = [];
const druidFilters = [];
if (showSqlaTimeGrain) sqlaFilters.push('time_grain_sqla');
if (showSqlaTimeColumn) sqlaFilters.push('granularity_sqla');
if (showDruidTimeGrain) druidFilters.push('granularity');
if (showDruidTimeOrigin) druidFilters.push('druid_time_origin');
if (sqlaFilters.length) {
datasourceFilters.push(
<ControlRow

View File

@ -851,10 +851,6 @@ class ChartDataExtrasSchema(Schema):
description="HAVING clause to be added to aggregate queries using "
"AND operator.",
)
having_druid = fields.List(
fields.Nested(ChartDataFilterSchema),
description="HAVING filters to be added to legacy Druid datasource queries.",
)
time_grain_sqla = fields.String(
description="To what level of granularity should the temporal column be "
"aggregated. Supports "
@ -869,11 +865,6 @@ class ChartDataExtrasSchema(Schema):
example="P1D",
allow_none=True,
)
druid_time_origin = fields.String(
description="Starting point for time grain counting on legacy Druid "
"datasources. Used to change e.g. Monday/Sunday first-day-of-week.",
allow_none=True,
)
class AnnotationLayerSchema(Schema):
@ -1175,6 +1166,7 @@ class ChartDataQueryObjectSchema(Schema):
"This field is deprecated and should be passed to `extras` "
"as `druid_time_origin`.",
allow_none=True,
deprecated=True,
)
url_params = fields.Dict(
description="Optional query parameters passed to a dashboard or Explore view",

View File

@ -73,8 +73,6 @@ DEPRECATED_FIELDS = (
DEPRECATED_EXTRAS_FIELDS = (
DeprecatedField(old_name="where", new_name="where"),
DeprecatedField(old_name="having", new_name="having"),
DeprecatedField(old_name="having_filters", new_name="having_druid"),
DeprecatedField(old_name="druid_time_origin", new_name="druid_time_origin"),
)

View File

@ -147,7 +147,6 @@ EXTRA_FORM_DATA_OVERRIDE_REGULAR_MAPPINGS = {
"time_column": "time_column",
"time_grain": "time_grain",
"time_range": "time_range",
"druid_time_origin": "druid_time_origin",
"time_grain_sqla": "time_grain_sqla",
}

View File

@ -219,7 +219,6 @@ class ExtraFiltersTimeColumnType(str, Enum):
class ExtraFiltersReasonType(str, Enum):
NO_TEMPORAL_COLUMN = "no_temporal_column"
COL_NOT_IN_DATASOURCE = "not_in_datasource"
NOT_DRUID_DATASOURCE = "not_druid_datasource"
class FilterOperator(str, Enum):
@ -1145,7 +1144,6 @@ def merge_extra_filters(form_data: Dict[str, Any]) -> None:
"__time_range": "time_range",
"__time_col": "granularity_sqla",
"__time_grain": "time_grain_sqla",
"__time_origin": "druid_time_origin",
"__granularity": "granularity",
}
# Grab list of existing filters 'keyed' on the column and operator
@ -1763,28 +1761,6 @@ def get_time_filter_status(
}
)
if ExtraFiltersTimeColumnType.TIME_ORIGIN in applied_time_extras:
if datasource.type == "druid":
applied.append({"column": ExtraFiltersTimeColumnType.TIME_ORIGIN})
else:
rejected.append(
{
"reason": ExtraFiltersReasonType.NOT_DRUID_DATASOURCE,
"column": ExtraFiltersTimeColumnType.TIME_ORIGIN,
}
)
if ExtraFiltersTimeColumnType.GRANULARITY in applied_time_extras:
if datasource.type == "druid":
applied.append({"column": ExtraFiltersTimeColumnType.GRANULARITY})
else:
rejected.append(
{
"reason": ExtraFiltersReasonType.NOT_DRUID_DATASOURCE,
"column": ExtraFiltersTimeColumnType.GRANULARITY,
}
)
return applied, rejected

View File

@ -63,10 +63,6 @@ def convert_filter_scopes(
add_filter_scope(filter_fields, "__time_col", filter_id)
if slice_params.get("show_sqla_time_granularity"):
add_filter_scope(filter_fields, "__time_grain", filter_id)
if slice_params.get("show_druid_time_granularity"):
add_filter_scope(filter_fields, "__granularity", filter_id)
if slice_params.get("show_druid_time_origin"):
add_filter_scope(filter_fields, "druid_time_origin", filter_id)
for config in configs:
add_filter_scope(filter_fields, config.get("column"), filter_id)

View File

@ -397,9 +397,7 @@ class BaseViz: # pylint: disable=too-many-public-methods
# extras are used to query elements specific to a datasource type
# for instance the extra where clause that applies only to Tables
extras = {
"druid_time_origin": self.form_data.get("druid_time_origin", ""),
"having": self.form_data.get("having", ""),
"having_druid": self.form_data.get("having_filters", []),
"time_grain_sqla": self.form_data.get("time_grain_sqla"),
"where": self.form_data.get("where", ""),
}

View File

@ -181,7 +181,7 @@ class TestPostChartDataApi(BaseTestChartDataApi):
"superset.utils.core.current_app.config",
{**app.config, "SQL_MAX_ROW": 5},
)
def test_as_samples_with_row_limit_bigger_then_sql_max_row__rowcount_as_sql_max_row(
def test_as_samples_with_row_limit_bigger_then_sql_max_row_rowcount_as_sql_max_row(
self,
):
expected_row_count = app.config["SQL_MAX_ROW"]
@ -335,12 +335,6 @@ class TestPostChartDataApi(BaseTestChartDataApi):
{"column": "__time_range"},
],
)
self.assertEqual(
data["result"][0]["rejected_filters"],
[
{"column": "__time_origin", "reason": "not_druid_datasource"},
],
)
expected_row_count = self.get_expected_row_count("client_id_2")
self.assertEqual(data["result"][0]["rowcount"], expected_row_count)
@ -798,7 +792,6 @@ class TestGetChartDataApi(BaseTestChartDataApi):
"filters": [],
"extras": {
"having": "",
"having_druid": [],
"where": "",
},
"applied_time_extras": {},

View File

@ -283,7 +283,6 @@ class TestQueryContext(SupersetTestCase):
self.assertEqual(query_object.columns, columns)
self.assertEqual(query_object.series_limit, 99)
self.assertEqual(query_object.series_limit_metric, "sum__num")
self.assertIn("having_druid", query_object.extras)
@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
def test_csv_response_format(self):

View File

@ -228,7 +228,6 @@ class TestUtils(SupersetTestCase):
{"col": "__time_col", "op": "in", "val": "birth_year"},
{"col": "__time_grain", "op": "in", "val": "years"},
{"col": "A", "op": "like", "val": "hello"},
{"col": "__time_origin", "op": "in", "val": "now"},
{"col": "__granularity", "op": "in", "val": "90 seconds"},
]
}
@ -248,12 +247,10 @@ class TestUtils(SupersetTestCase):
"granularity_sqla": "birth_year",
"time_grain_sqla": "years",
"granularity": "90 seconds",
"druid_time_origin": "now",
"applied_time_extras": {
"__time_range": "1 year ago :",
"__time_col": "birth_year",
"__time_grain": "years",
"__time_origin": "now",
"__granularity": "90 seconds",
},
}

View File

@ -288,13 +288,6 @@ class TestTableViz(SupersetTestCase):
"operator": ">",
"comparator": "100",
},
{
"expressionType": "SIMPLE",
"clause": "HAVING",
"subject": "SUM(value1)",
"operator": "<",
"comparator": "10",
},
{
"expressionType": "SQL",
"clause": "HAVING",
@ -313,10 +306,6 @@ class TestTableViz(SupersetTestCase):
self.assertEqual(
[{"col": "value2", "val": "100", "op": ">"}], query_obj["filter"]
)
self.assertEqual(
[{"op": "<", "val": "10", "col": "SUM(value1)"}],
query_obj["extras"]["having_druid"],
)
self.assertEqual("(value3 in ('North America'))", query_obj["extras"]["where"])
self.assertEqual("(SUM(value1) > 5)", query_obj["extras"]["having"])
@ -352,7 +341,6 @@ class TestTableViz(SupersetTestCase):
self.assertEqual(
[{"col": "value2", "val": "100", "op": ">"}], query_obj["filter"]
)
self.assertEqual([], query_obj["extras"]["having_druid"])
self.assertEqual("(value3 in ('North America'))", query_obj["extras"]["where"])
self.assertEqual("", query_obj["extras"]["having"])