This is an automated email from the ASF dual-hosted git repository.
yongjiezhao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 25e572a56e fix: count(distinct column_name) in metrics (#19842)
25e572a56e is described below
commit 25e572a56e8cca1c9dd466fcd64ad610e86a385c
Author: Yongjie Zhao <[email protected]>
AuthorDate: Tue Apr 26 20:03:55 2022 +0800
fix: count(distinct column_name) in metrics (#19842)
---
.../controls/MetricControl/AdhocMetric.js | 21 ++++++++++---
.../controls/MetricControl/AdhocMetric.test.js | 36 ++++++++++++++++++++++
.../MetricControl/AdhocMetricEditPopover/index.jsx | 5 ++-
3 files changed, 57 insertions(+), 5 deletions(-)
diff --git
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
index 01fea2dab6..5b29d7418c 100644
---
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
+++
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
@@ -16,7 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { sqlaAutoGeneratedMetricRegex } from 'src/explore/constants';
+import {
+ sqlaAutoGeneratedMetricRegex,
+ AGGREGATES,
+} from 'src/explore/constants';
export const EXPRESSION_TYPES = {
SIMPLE: 'SIMPLE',
@@ -86,20 +89,30 @@ export default class AdhocMetric {
}
getDefaultLabel() {
- const label = this.translateToSql(true);
+ const label = this.translateToSql({ useVerboseName: true });
return label.length < 43 ? label : `${label.substring(0, 40)}...`;
}
- translateToSql(useVerboseName = false) {
+ translateToSql(
+ params = { useVerboseName: false, transformCountDistinct: false },
+ ) {
if (this.expressionType === EXPRESSION_TYPES.SIMPLE) {
const aggregate = this.aggregate || '';
// eslint-disable-next-line camelcase
const column =
- useVerboseName && this.column?.verbose_name
+ params.useVerboseName && this.column?.verbose_name
? `(${this.column.verbose_name})`
: this.column?.column_name
? `(${this.column.column_name})`
: '';
+ // transform from `count_distinct(column)` to `count(distinct column)`
+ if (
+ params.transformCountDistinct &&
+ aggregate === AGGREGATES.COUNT_DISTINCT &&
+ /^\(.*\)$/.test(column)
+ ) {
+ return `COUNT(DISTINCT ${column.slice(1, -1)})`;
+ }
return aggregate + column;
}
if (this.expressionType === EXPRESSION_TYPES.SQL) {
diff --git
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.test.js
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.test.js
index f3b7d08dca..336b194e00 100644
---
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.test.js
+++
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.test.js
@@ -216,4 +216,40 @@ describe('AdhocMetric', () => {
expect(adhocMetric3.aggregate).toBe(AGGREGATES.AVG);
expect(adhocMetric3.column.column_name).toBe('value');
});
+
+ it('should transform count_distinct SQL and do not change label if does not
set metric label', () => {
+ const withBrackets = new AdhocMetric({
+ column: { type: 'TEXT', column_name: '(column-with-barckets)' },
+ aggregate: AGGREGATES.COUNT_DISTINCT,
+ hasCustomLabel: false,
+ });
+ expect(withBrackets.translateToSql({ transformCountDistinct: true })).toBe(
+ 'COUNT(DISTINCT (column-with-barckets))',
+ );
+ expect(withBrackets.getDefaultLabel()).toBe(
+ 'COUNT_DISTINCT((column-with-barckets))',
+ );
+
+ const withoutBrackets = new AdhocMetric({
+ column: { type: 'TEXT', column_name: 'column-without-barckets' },
+ aggregate: AGGREGATES.COUNT_DISTINCT,
+ hasCustomLabel: false,
+ });
+ expect(
+ withoutBrackets.translateToSql({ transformCountDistinct: true }),
+ ).toBe('COUNT(DISTINCT column-without-barckets)');
+ expect(withoutBrackets.getDefaultLabel()).toBe(
+ 'COUNT_DISTINCT(column-without-barckets)',
+ );
+
+ const emptyColumnName = new AdhocMetric({
+ column: { type: 'TEXT', column_name: '' },
+ aggregate: AGGREGATES.COUNT_DISTINCT,
+ hasCustomLabel: false,
+ });
+ expect(
+ emptyColumnName.translateToSql({ transformCountDistinct: true }),
+ ).toBe('COUNT_DISTINCT');
+ expect(emptyColumnName.getDefaultLabel()).toBe('COUNT_DISTINCT');
+ });
});
diff --git
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
index be5d15ffb5..decad4c12d 100644
---
a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
+++
b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover/index.jsx
@@ -465,7 +465,10 @@ export default class AdhocMetricEditPopover extends
React.PureComponent {
onChange={this.onSqlExpressionChange}
width="100%"
showGutter={false}
- value={adhocMetric.sqlExpression || adhocMetric.translateToSql()}
+ value={
+ adhocMetric.sqlExpression ||
+ adhocMetric.translateToSql({ transformCountDistinct: true })
+ }
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
className="filter-sql-editor"