Skip to content

Commit 68c145a

Browse files
feat(semantic layers): add metadata on additive metrics (#40279)
1 parent 4a9aecd commit 68c145a

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

superset-core/src/superset_core/semantic_layers/types.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,26 @@ class Dimension:
9292
grain: Grain | None = None
9393

9494

95+
class AggregationType(str, enum.Enum):
96+
"""
97+
Aggregation function applied by a metric.
98+
99+
Additivity (across an arbitrary set of grouping dimensions):
100+
* ``SUM``, ``COUNT``: fully additive — sub-group sums roll up via ``sum``.
101+
* ``MIN``, ``MAX``: roll up via ``min`` / ``max`` of sub-group values.
102+
* ``AVG``, ``COUNT_DISTINCT``, ``OTHER``: not safely roll-uppable from
103+
sub-aggregates without auxiliary data.
104+
"""
105+
106+
SUM = "SUM"
107+
COUNT = "COUNT"
108+
MIN = "MIN"
109+
MAX = "MAX"
110+
AVG = "AVG"
111+
COUNT_DISTINCT = "COUNT_DISTINCT"
112+
OTHER = "OTHER"
113+
114+
95115
@dataclass(frozen=True)
96116
class Metric:
97117
id: str
@@ -100,6 +120,7 @@ class Metric:
100120

101121
definition: str
102122
description: str | None = None
123+
aggregation: AggregationType | None = None
103124

104125

105126
@dataclass(frozen=True)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
from __future__ import annotations
19+
20+
import pyarrow as pa
21+
from superset_core.semantic_layers.types import AggregationType, Metric
22+
23+
24+
def test_metric_aggregation_defaults_to_none() -> None:
25+
metric = Metric(
26+
id="x",
27+
name="x",
28+
type=pa.float64(),
29+
definition="sum(x)",
30+
)
31+
assert metric.aggregation is None
32+
33+
34+
def test_metric_accepts_aggregation_type() -> None:
35+
metric = Metric(
36+
id="x",
37+
name="x",
38+
type=pa.float64(),
39+
definition="sum(x)",
40+
aggregation=AggregationType.SUM,
41+
)
42+
assert metric.aggregation is AggregationType.SUM
43+
44+
45+
def test_aggregation_type_is_string_enum() -> None:
46+
# Behaves as a string for equality and serialization, so it can be sent
47+
# over JSON without an explicit converter.
48+
assert AggregationType.SUM == "SUM"
49+
assert AggregationType.COUNT_DISTINCT.value == "COUNT_DISTINCT"
50+
assert {a.value for a in AggregationType} == {
51+
"SUM",
52+
"COUNT",
53+
"MIN",
54+
"MAX",
55+
"AVG",
56+
"COUNT_DISTINCT",
57+
"OTHER",
58+
}

0 commit comments

Comments
 (0)