diff --git a/superset/assets/javascripts/explore/components/controls/MetricsControl.jsx b/superset/assets/javascripts/explore/components/controls/MetricsControl.jsx index 9a16f525a0ec5..ffc2fe26d64e6 100644 --- a/superset/assets/javascripts/explore/components/controls/MetricsControl.jsx +++ b/superset/assets/javascripts/explore/components/controls/MetricsControl.jsx @@ -74,13 +74,8 @@ function getDefaultAggregateForColumn(column) { return null; } -const autoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|AVG|MAX|MIN|COUNT)\([A-Z_][A-Z0-9_]*\)$/i; -function isAutoGeneratedMetric(savedMetric) { - return ( - autoGeneratedMetricRegex.test(savedMetric.expression) || - autoGeneratedMetricRegex.test(savedMetric.verbose_name) - ); -} +const sqlaAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|AVG|MAX|MIN|COUNT)\([A-Z_][A-Z0-9_]*\)$/i; +const druidAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|MAX|MIN|COUNT)\([A-Z_][A-Z0-9_]*\)$/i; export default class MetricsControl extends React.PureComponent { constructor(props) { @@ -90,6 +85,7 @@ export default class MetricsControl extends React.PureComponent { this.checkIfAggregateInInput = this.checkIfAggregateInInput.bind(this); this.optionsForSelect = this.optionsForSelect.bind(this); this.selectFilterOption = this.selectFilterOption.bind(this); + this.isAutoGeneratedMetric = this.isAutoGeneratedMetric.bind(this); this.optionRenderer = VirtualizedRendererWrap(option => ( ), { ignoreAutogeneratedMetrics: true }); @@ -209,6 +205,13 @@ export default class MetricsControl extends React.PureComponent { }); } + isAutoGeneratedMetric(savedMetric) { + if (this.props.datasourceType === 'druid') { + return druidAutoGeneratedMetricRegex.test(savedMetric.verbose_name); + } + return sqlaAutoGeneratedMetricRegex.test(savedMetric.expression); + } + selectFilterOption(option, filterValue) { if (this.state.aggregateInInput) { let endIndex = filterValue.length; @@ -220,7 +223,7 @@ export default class MetricsControl extends React.PureComponent { (option.column_name.toLowerCase().indexOf(valueAfterAggregate.toLowerCase()) >= 0); } return option.optionName && - (!option.metric_name || !isAutoGeneratedMetric(option)) && + (!option.metric_name || !this.isAutoGeneratedMetric(option)) && (option.optionName.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0); } diff --git a/superset/assets/spec/javascripts/explore/components/MetricsControl_spec.jsx b/superset/assets/spec/javascripts/explore/components/MetricsControl_spec.jsx index 346a2872cda34..23c8776322557 100644 --- a/superset/assets/spec/javascripts/explore/components/MetricsControl_spec.jsx +++ b/superset/assets/spec/javascripts/explore/components/MetricsControl_spec.jsx @@ -24,6 +24,7 @@ const defaultProps = { { metric_name: 'sum__value', expression: 'SUM(energy_usage.value)' }, { metric_name: 'avg__value', expression: 'AVG(energy_usage.value)' }, ], + datasourceType: 'sqla', }; function setup(overrides) { @@ -188,7 +189,7 @@ describe('MetricsControl', () => { describe('option filter', () => { it('includes user defined metrics', () => { - const { wrapper } = setup(); + const { wrapper } = setup({ datasourceType: 'druid' }); expect(!!wrapper.instance().selectFilterOption( { @@ -200,6 +201,19 @@ describe('MetricsControl', () => { )).to.be.true; }); + it('includes auto generated avg metrics for druid', () => { + const { wrapper } = setup({ datasourceType: 'druid' }); + + expect(!!wrapper.instance().selectFilterOption( + { + metric_name: 'a_metric', + optionName: 'a_metric', + expression: 'AVG(metric)', + }, + 'a', + )).to.be.true; + }); + it('includes columns and aggregates', () => { const { wrapper } = setup(); @@ -214,6 +228,19 @@ describe('MetricsControl', () => { )).to.be.true; }); + it('excludes auto generated avg metrics for sqla', () => { + const { wrapper } = setup(); + + expect(!!wrapper.instance().selectFilterOption( + { + metric_name: 'a_metric', + optionName: 'a_metric', + expression: 'AVG(metric)', + }, + 'a', + )).to.be.false; + }); + it('excludes auto generated metrics', () => { const { wrapper } = setup();