Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release-19.2: backport avg for interval #42679

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/generated/sql/aggregates.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
</span></td></tr>
<tr><td><code>avg(arg1: <a href="int.html">int</a>) &rarr; <a href="decimal.html">decimal</a></code></td><td><span class="funcdesc"><p>Calculates the average of the selected values.</p>
</span></td></tr>
<tr><td><code>avg(arg1: <a href="interval.html">interval</a>) &rarr; <a href="interval.html">interval</a></code></td><td><span class="funcdesc"><p>Calculates the average of the selected values.</p>
</span></td></tr>
<tr><td><code>bool_and(arg1: <a href="bool.html">bool</a>) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Calculates the boolean value of <code>AND</code>ing all selected values.</p>
</span></td></tr>
<tr><td><code>bool_or(arg1: <a href="bool.html">bool</a>) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Calculates the boolean value of <code>OR</code>ing all selected values.</p>
Expand Down
25 changes: 18 additions & 7 deletions pkg/sql/logictest/testdata/logic_test/aggregate
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ CREATE TABLE kv (
k INT PRIMARY KEY,
v INT,
w INT,
s STRING
s STRING,
i INTERVAL
)

# Aggregate functions return NULL if there are no rows.
Expand Down Expand Up @@ -36,6 +37,11 @@ SELECT jsonb_agg(1) FROM kv
----
NULL

query TTTT
SELECT min(i), avg(i), max(i), sum(i) FROM kv
----
NULL NULL NULL NULL

query IIIIRRRRBBT
SELECT min(v), max(v), count(v), sum_int(1), avg(v), sum(v), stddev(v), variance(v), bool_and(v = 1), bool_and(v = 1), xor_agg(s::bytes) FROM kv
----
Expand Down Expand Up @@ -147,12 +153,12 @@ SELECT (SELECT COALESCE(max(1), 0) FROM generate_series(1,0))

statement OK
INSERT INTO kv VALUES
(1, 2, 3, 'a'),
(3, 4, 5, 'a'),
(5, NULL, 5, NULL),
(6, 2, 3, 'b'),
(7, 2, 2, 'b'),
(8, 4, 2, 'A')
(1, 2, 3, 'a', '1min'),
(3, 4, 5, 'a', '2sec'),
(5, NULL, 5, NULL, NULL),
(6, 2, 3, 'b', '1ms'),
(7, 2, 2, 'b', '4 days'),
(8, 4, 2, 'A', '3 years')

# Aggregate functions triggers aggregation and computation for every row even when applied to a constant.
# NB: The XOR result is 00 because \x01 is XOR'd an even number of times.
Expand Down Expand Up @@ -588,6 +594,11 @@ SELECT avg(k), avg(v), sum(k), sum(v) FROM kv
----
5 2.8 30 14

query TTTT
SELECT min(i), avg(i), max(i), sum(i) FROM kv
----
00:00:00.001 7 mons 6 days 19:12:12.4002 3 years 3 years 4 days 00:01:02.001

query RRRR
SELECT avg(k::decimal), avg(v::decimal), sum(k::decimal), sum(v::decimal) FROM kv
----
Expand Down
75 changes: 45 additions & 30 deletions pkg/sql/logictest/testdata/logic_test/window
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@ CREATE TABLE kv (
d DECIMAL,
s STRING,
b BOOL,
i INTERVAL,
FAMILY (k, v, w, f, b),
FAMILY (d),
FAMILY (s)
)

statement OK
INSERT INTO kv VALUES
(1, 2, 3, 1.0, 1, 'a', true),
(3, 4, 5, 2, 8, 'a', true),
(5, NULL, 5, 9.9, -321, NULL, false),
(6, 2, 3, 4.4, 4.4, 'b', true),
(7, 2, 2, 6, 7.9, 'b', true),
(8, 4, 2, 3, 3, 'A', false)
(1, 2, 3, 1.0, 1, 'a', true, '1min'),
(3, 4, 5, 2, 8, 'a', true, '2sec'),
(5, NULL, 5, 9.9, -321, NULL, false, NULL),
(6, 2, 3, 4.4, 4.4, 'b', true, '1ms'),
(7, 2, 2, 6, 7.9, 'b', true, '4 days'),
(8, 4, 2, 3, 3, 'A', false, '3 years')

query error window functions are not allowed in GROUP BY
SELECT * FROM kv GROUP BY v, count(w) OVER ()
Expand Down Expand Up @@ -210,38 +211,38 @@ SELECT avg(k) OVER (w ORDER BY w) FROM kv WINDOW w AS (PARTITION BY v) ORDER BY
7
8

query IIIRRTBR colnames
query IIIRRTBTR colnames
SELECT *, avg(k) OVER (w ORDER BY w) FROM kv WINDOW w AS (PARTITION BY v) ORDER BY 1
----
k v w f d s b avg
1 2 3 1 1 a true 4.6666666666666666667
3 4 5 2 8 a true 5.5
5 NULL 5 9.9 -321 NULL false 5
6 2 3 4.4 4.4 b true 4.6666666666666666667
7 2 2 6 7.9 b true 7
8 4 2 3 3 A false 8
k v w f d s b i avg
1 2 3 1 1 a true 00:01:00 4.6666666666666666667
3 4 5 2 8 a true 00:00:02 5.5
5 NULL 5 9.9 -321 NULL false NULL 5
6 2 3 4.4 4.4 b true 00:00:00.001 4.6666666666666666667
7 2 2 6 7.9 b true 4 days 7
8 4 2 3 3 A false 3 years 8

query IIIRRTBR colnames
query IIIRRTBTR colnames
SELECT *, avg(k) OVER w FROM kv WINDOW w AS (PARTITION BY v ORDER BY w) ORDER BY avg(k) OVER w, k
----
k v w f d s b avg
1 2 3 1 1 a true 4.6666666666666666667
6 2 3 4.4 4.4 b true 4.6666666666666666667
5 NULL 5 9.9 -321 NULL false 5
3 4 5 2 8 a true 5.5
7 2 2 6 7.9 b true 7
8 4 2 3 3 A false 8
k v w f d s b i avg
1 2 3 1 1 a true 00:01:00 4.6666666666666666667
6 2 3 4.4 4.4 b true 00:00:00.001 4.6666666666666666667
5 NULL 5 9.9 -321 NULL false NULL 5
3 4 5 2 8 a true 00:00:02 5.5
7 2 2 6 7.9 b true 4 days 7
8 4 2 3 3 A false 3 years 8

query IIIRRTB colnames
query IIIRRTBT colnames
SELECT * FROM kv WINDOW w AS (PARTITION BY v ORDER BY w) ORDER BY avg(k) OVER w DESC, k
----
k v w f d s b
8 4 2 3 3 A false
7 2 2 6 7.9 b true
3 4 5 2 8 a true
5 NULL 5 9.9 -321 NULL false
1 2 3 1 1 a true
6 2 3 4.4 4.4 b true
k v w f d s b i
8 4 2 3 3 A false 3 years
7 2 2 6 7.9 b true 4 days
3 4 5 2 8 a true 00:00:02
5 NULL 5 9.9 -321 NULL false NULL
1 2 3 1 1 a true 00:01:00
6 2 3 4.4 4.4 b true 00:00:00.001

query error window "w" is already defined
SELECT avg(k) OVER w FROM kv WINDOW w AS (), w AS ()
Expand Down Expand Up @@ -1900,6 +1901,20 @@ DELETE FROM kv WHERE k = 12
query error FILTER specified but rank\(\) is not an aggregate function
SELECT k, rank() FILTER (WHERE k=1) OVER () FROM kv

query TT
SELECT i, avg(i) OVER (ORDER BY i) FROM kv ORDER BY i
----
NULL NULL
NULL NULL
NULL NULL
NULL NULL
00:00:00.001 00:00:00.001
00:00:02 00:00:01.0005
00:01:00 00:00:20.667
4 days 1 day 00:00:15.50025
3 years 7 mons 6 days 19:12:12.4002


# Issue #14606: correctly handle aggregation functions above the windowing level
query I
SELECT max(i) * (row_number() OVER (ORDER BY max(i))) FROM (SELECT 1 AS i, 2 AS j) GROUP BY j
Expand Down
9 changes: 9 additions & 0 deletions pkg/sql/sem/builtins/aggregate_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ var aggregates = map[string]builtinDefinition{
"Calculates the average of the selected values."),
makeAggOverload([]*types.T{types.Decimal}, types.Decimal, newDecimalAvgAggregate,
"Calculates the average of the selected values."),
makeAggOverload([]*types.T{types.Interval}, types.Interval, newIntervalAvgAggregate,
"Calculates the average of the selected values."),
),

"bool_and": makeBuiltin(aggProps(),
Expand Down Expand Up @@ -557,6 +559,11 @@ func newDecimalAvgAggregate(
) tree.AggregateFunc {
return &avgAggregate{agg: newDecimalSumAggregate(params, evalCtx, arguments)}
}
func newIntervalAvgAggregate(
params []*types.T, evalCtx *tree.EvalContext, arguments tree.Datums,
) tree.AggregateFunc {
return &avgAggregate{agg: newIntervalSumAggregate(params, evalCtx, arguments)}
}

// Add accumulates the passed datum into the average.
func (a *avgAggregate) Add(ctx context.Context, datum tree.Datum, other ...tree.Datum) error {
Expand Down Expand Up @@ -586,6 +593,8 @@ func (a *avgAggregate) Result() (tree.Datum, error) {
count := apd.New(int64(a.count), 0)
_, err := tree.DecimalCtx.Quo(&t.Decimal, &t.Decimal, count)
return t, err
case *tree.DInterval:
return &tree.DInterval{Duration: t.Duration.Div(int64(a.count))}, nil
default:
return nil, errors.AssertionFailedf("unexpected SUM result type: %s", t)
}
Expand Down
12 changes: 12 additions & 0 deletions pkg/sql/sem/builtins/aggregate_builtins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ func TestAvgDecimalResultDeepCopy(t *testing.T) {
testAggregateResultDeepCopy(t, newDecimalAvgAggregate, makeDecimalTestDatum(10))
}

func TestAvgIntervalResultDeepCopy(t *testing.T) {
testAggregateResultDeepCopy(t, newIntervalAvgAggregate, makeIntervalTestDatum(10))
}

func TestBoolAndResultDeepCopy(t *testing.T) {
testAggregateResultDeepCopy(t, newBoolAndAggregate, makeBoolTestDatum(10))
}
Expand Down Expand Up @@ -329,6 +333,14 @@ func BenchmarkAvgAggregateDecimal(b *testing.B) {
}
}

func BenchmarkAvgAggregateInterval(b *testing.B) {
for _, count := range []int{1000} {
b.Run(fmt.Sprintf("count=%d", count), func(b *testing.B) {
runBenchmarkAggregate(b, newIntervalAvgAggregate, makeIntervalTestDatum(count))
})
}
}

func BenchmarkCountAggregate(b *testing.B) {
for _, count := range []int{1000} {
b.Run(fmt.Sprintf("count=%d", count), func(b *testing.B) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/sql/sem/builtins/window_frame_builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ func (w *avgWindowFunc) Compute(
count := apd.New(int64(frameSize), 0)
_, err := tree.DecimalCtx.Quo(&avg.Decimal, &dd.Decimal, count)
return &avg, err
case *tree.DInterval:
return &tree.DInterval{Duration: t.Duration.Div(int64(frameSize))}, nil
default:
return nil, errors.AssertionFailedf("unexpected SUM result type: %s", t)
}
Expand Down