diff --git a/frontend/src/metabase-lib/lib/Dimension.js b/frontend/src/metabase-lib/lib/Dimension.js index 24efb7ac781e7b1709561589e81676042c6fac92..4867920a9efa49d7b3eab2dd1948b8a6944ec09f 100644 --- a/frontend/src/metabase-lib/lib/Dimension.js +++ b/frontend/src/metabase-lib/lib/Dimension.js @@ -847,22 +847,30 @@ export class AggregationDimension extends Dimension { } column(extra = {}) { - const aggregation = this.aggregation(); - const { special_type, ...column } = super.column(); return { - ...column, - // don't pass through `special_type` when aggregating these types - ...(!UNAGGREGATED_SPECIAL_TYPES.has(special_type) && { special_type }), - base_type: aggregation ? aggregation.baseType() : TYPE.Float, + ...super.column(), source: "aggregation", ...extra, }; } field() { - // FIXME: it isn't really correct to return the unaggregated field. return a fake Field object? - const dimension = this.aggregation().dimension(); - return dimension ? dimension.field() : super.field(); + const aggregation = this.aggregation(); + if (!aggregation) { + return super.field(); + } + const dimension = aggregation.dimension(); + const field = dimension && dimension.field(); + const { special_type } = field || {}; + return new Field({ + name: aggregation.columnName(), + display_name: aggregation.displayName(), + base_type: aggregation.baseType(), + // don't pass through `special_type` when aggregating these types + ...(!UNAGGREGATED_SPECIAL_TYPES.has(special_type) && { special_type }), + query: this._query, + metadata: this._metadata, + }); } /** diff --git a/frontend/test/metabase-lib/lib/Dimension.unit.spec.js b/frontend/test/metabase-lib/lib/Dimension.unit.spec.js index ab733bd5fd686bcd9f0037fe4eb65b33a80430b2..dfaa971aaa86ce842c8ad71bc8030fa4f9fde4ef 100644 --- a/frontend/test/metabase-lib/lib/Dimension.unit.spec.js +++ b/frontend/test/metabase-lib/lib/Dimension.unit.spec.js @@ -509,17 +509,21 @@ describe("Dimension", () => { }); }); + function aggregation(agg) { + const query = new StructuredQuery(ORDERS.question(), { + type: "query", + database: SAMPLE_DATASET.id, + query: { + "source-table": ORDERS.id, + aggregation: [agg], + }, + }); + return Dimension.parseMBQL(["aggregation", 0], metadata, query); + } + describe("column()", () => { function sumOf(column) { - const query = new StructuredQuery(ORDERS.question(), { - type: "query", - database: SAMPLE_DATASET.id, - query: { - "source-table": ORDERS.id, - aggregation: [["sum", ["field-id", column.id]]], - }, - }); - return Dimension.parseMBQL(["aggregation", 0], metadata, query); + return aggregation(["sum", ["field-id", column.id]]); } it("should clear unaggregated special types", () => { @@ -534,6 +538,29 @@ describe("Dimension", () => { expect(special_type).toBe("type/Currency"); }); }); + + describe("field()", () => { + it("should return a float field for sum of order total", () => { + const { base_type } = aggregation([ + "sum", + ["field-id", ORDERS.TOTAL.id], + ]).field(); + expect(base_type).toBe("type/Float"); + }); + + it("should return an int field for count distinct of product category", () => { + const { base_type } = aggregation([ + "distinct", + ["field-id", PRODUCTS.CATEGORY.id], + ]).field(); + expect(base_type).toBe("type/Integer"); + }); + + it("should return an int field for count", () => { + const { base_type } = aggregation(["count"]).field(); + expect(base_type).toBe("type/Integer"); + }); + }); }); }); });