Skip to content

Commit 0308d9f

Browse files
authored
Merge pull request #3178 from dolthub/angela/window
Do not materialize any output for WindowPartitionIter if input is empty
2 parents 53ac7a8 + 23c3566 commit 0308d9f

File tree

5 files changed

+66
-25
lines changed

5 files changed

+66
-25
lines changed

enginetest/queries/logic_test_scripts.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,6 @@ var SQLLogicSubqueryTests = []ScriptTest{
951951
},
952952
},
953953
{
954-
Skip: true,
955954
Query: "SELECT * FROM (SELECT c_id AS c_c_id, bill FROM c) sq1, LATERAL (SELECT row_number() OVER () AS rownum FROM o WHERE c_id = c_c_id) sq2 ORDER BY c_c_id, bill, rownum;",
956955
Expected: []sql.Row{
957956
{1, "CA", 1},

enginetest/queries/script_queries.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11584,6 +11584,7 @@ select * from t1 except (
1158411584
Query: "select * from test01 where pk in (11)",
1158511585
Expected: []sql.Row{
1158611586
{"11"},
11587+
{"11-5"},
1158711588
{"11d"},
1158811589
{"11wha?"},
1158911590
},
@@ -11628,6 +11629,64 @@ select * from t1 except (
1162811629
},
1162911630
},
1163011631
},
11632+
{
11633+
// https://github.com/dolthub/dolt/issues/6899
11634+
Name: "window function tests",
11635+
SetUpScript: []string{
11636+
"CREATE TABLE c (c_id INT PRIMARY KEY, bill TEXT);",
11637+
"CREATE TABLE o (o_id INT PRIMARY KEY, c_id INT, ship TEXT);",
11638+
"INSERT INTO c VALUES (1, 'CA'), (2, 'TX'), (3, 'MA'), (4, 'TX'), (5, NULL), (6, 'FL');",
11639+
"INSERT INTO o VALUES (10, 1, 'CA'), (20, 1, 'CA'), (30, 1, 'CA'), (40, 2, 'CA'), (50, 2, 'TX'), (60, 2, NULL), (70, 4, 'WY'), (80, 4, NULL), (90, 6, 'WA');",
11640+
},
11641+
Assertions: []ScriptTestAssertion{
11642+
{
11643+
Query: "select row_number() over () as rn from o where c_id=-999",
11644+
Expected: []sql.Row{},
11645+
},
11646+
{
11647+
// TODO: valid query in Postgres. https://github.com/dolthub/doltgresql/issues/1796
11648+
Dialect: "mysql",
11649+
Query: "select row_number() over () as rn from o where c_id=1",
11650+
Expected: []sql.Row{{1}, {2}, {3}},
11651+
},
11652+
{
11653+
Query: "select rank() over() as rnk from o where c_id=-999",
11654+
Expected: []sql.Row{},
11655+
},
11656+
{
11657+
// TODO: valid query in Postgres. https://github.com/dolthub/doltgresql/issues/1796
11658+
Dialect: "mysql",
11659+
Query: "select o_id, c_id, rank() over(order by o_id) as rnk from o where c_id=1",
11660+
Expected: []sql.Row{
11661+
{10, 1, uint64(1)},
11662+
{20, 1, uint64(2)},
11663+
{30, 1, uint64(3)},
11664+
},
11665+
},
11666+
{
11667+
Query: "select dense_rank() over() as rnk from o where c_id=-999",
11668+
Expected: []sql.Row{},
11669+
},
11670+
{
11671+
// TODO: valid query in Postgres. But Postgres orders nil at the end. Maybe rewrite query to filter out
11672+
// ship=null https://github.com/dolthub/doltgresql/issues/1796
11673+
Dialect: "mysql",
11674+
Query: "select ship, dense_rank() over (order by ship) as drnk from o where c_id in (1, 2) order by ship",
11675+
Expected: []sql.Row{
11676+
{nil, uint64(1)},
11677+
{"CA", uint64(2)},
11678+
{"CA", uint64(2)},
11679+
{"CA", uint64(2)},
11680+
{"CA", uint64(2)},
11681+
{"TX", uint64(3)},
11682+
},
11683+
},
11684+
{
11685+
Query: "select count(*) from o where c_id=-999",
11686+
Expected: []sql.Row{{0}},
11687+
},
11688+
},
11689+
},
1163111690
}
1163211691

1163311692
var SpatialScriptTests = []ScriptTest{

sql/expression/function/aggregation/window_framer.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,11 @@ func isNewOrderByValue(ctx *sql.Context, orderByExprs []sql.Expression, last sql
598598
}
599599

600600
for i := range lastExp {
601-
if lastExp[i] != thisExp[i] {
601+
compare, err := orderByExprs[i].Type().Compare(ctx, lastExp[i], thisExp[i])
602+
if err != nil {
603+
return false, err
604+
}
605+
if compare != 0 {
602606
return true, nil
603607
}
604608
}

sql/expression/function/aggregation/window_partition.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,7 @@ func (i *WindowPartitionIter) initializePartitions(ctx *sql.Context) ([]sql.Wind
232232
// At this stage, result rows are appended with the original row index for resorting. The size of
233233
// [i.output] will be smaller than [i.input] if the outer sql.Node is a plan.GroupBy with fewer partitions than rows.
234234
func (i *WindowPartitionIter) materializeOutput(ctx *sql.Context) (sql.WindowBuffer, error) {
235-
// handle nil input specially if no partition clause
236-
// ex: COUNT(*) on nil rows returns 0, not nil
237-
if len(i.input) == 0 && len(i.w.PartitionBy) > 0 {
235+
if len(i.input) == 0 {
238236
return nil, io.EOF
239237
}
240238

sql/expression/function/aggregation/window_partition_test.go

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323

2424
"github.com/dolthub/go-mysql-server/memory"
2525
"github.com/dolthub/go-mysql-server/sql"
26-
"github.com/dolthub/go-mysql-server/sql/expression"
2726
"github.com/dolthub/go-mysql-server/sql/types"
2827
)
2928

@@ -216,7 +215,7 @@ func TestWindowPartition_MaterializeOutput(t *testing.T) {
216215
require.ElementsMatch(t, expOutput, output)
217216
})
218217

219-
t.Run("nil input with partition by", func(t *testing.T) {
218+
t.Run("nil input", func(t *testing.T) {
220219
ctx := sql.NewEmptyContext()
221220
i := NewWindowPartitionIter(
222221
&WindowPartition{
@@ -232,24 +231,6 @@ func TestWindowPartition_MaterializeOutput(t *testing.T) {
232231
require.Equal(t, io.EOF, err)
233232
require.ElementsMatch(t, nil, output)
234233
})
235-
236-
t.Run("nil input no partition by", func(t *testing.T) {
237-
ctx := sql.NewEmptyContext()
238-
i := NewWindowPartitionIter(
239-
&WindowPartition{
240-
PartitionBy: nil,
241-
Aggs: []*Aggregation{
242-
NewAggregation(NewCountAgg(expression.NewGetField(0, types.Int64, "z", true)), NewGroupByFramer()),
243-
},
244-
})
245-
i.input = []sql.Row{}
246-
i.partitions = []sql.WindowInterval{{0, 0}}
247-
i.outputOrdering = nil
248-
output, err := i.materializeOutput(ctx)
249-
require.NoError(t, err)
250-
expOutput := []sql.Row{{int64(0), nil}}
251-
require.ElementsMatch(t, expOutput, output)
252-
})
253234
}
254235

255236
func TestWindowPartition_SortAndFilterOutput(t *testing.T) {

0 commit comments

Comments
 (0)