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

planner/core: check the window func arg first before checking window specs #11613

Merged
merged 14 commits into from
Aug 10, 2019
Merged
Show file tree
Hide file tree
Changes from 10 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
3 changes: 1 addition & 2 deletions cmd/explaintest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,9 @@ func (t *tester) execute(query query) error {
gotBuf := t.buf.Bytes()[offset:]

buf := make([]byte, t.buf.Len()-offset)
if _, err = t.resultFD.ReadAt(buf, int64(offset)); err != nil {
if _, err = t.resultFD.ReadAt(buf, int64(offset)); !(err == nil || err == io.EOF) {
return errors.Trace(errors.Errorf("run \"%v\" at line %d err, we got \n%s\nbut read result err %s", st.Text(), query.Line, gotBuf, err))
}

if !bytes.Equal(gotBuf, buf) {
return errors.Trace(errors.Errorf("run \"%v\" at line %d err, we need:\n%s\nbut got:\n%s\n", query.Query, query.Line, buf, gotBuf))
}
Expand Down
66 changes: 33 additions & 33 deletions cmd/explaintest/r/window_function.result
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,48 @@ create table t (a int, b int, c timestamp, index idx(a));
set @@tidb_enable_window_function = 1;
explain select sum(a) over() from t;
id count task operator info
Projection_7 10000.00 root sum(a) over()
└─Window_8 10000.00 root sum(cast(test.t.a)) over()
└─TableReader_10 10000.00 root data:TableScan_9
└─TableScan_9 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_8 10000.00 root sum(a) over()
└─Window_9 10000.00 root sum(cast(test.t.a)) over()
└─TableReader_11 10000.00 root data:TableScan_10
└─TableScan_10 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
explain select sum(a) over(partition by a) from t;
id count task operator info
Projection_7 10000.00 root sum(a) over(partition by a)
└─Window_8 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a)
└─IndexReader_10 10000.00 root index:IndexScan_9
└─IndexScan_9 10000.00 cop table:t, index:a, range:[NULL,+inf], keep order:true, stats:pseudo
Projection_8 10000.00 root sum(a) over(partition by a)
└─Window_9 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a)
└─IndexReader_11 10000.00 root index:IndexScan_10
└─IndexScan_10 10000.00 cop table:t, index:a, range:[NULL,+inf], keep order:true, stats:pseudo
explain select sum(a) over(partition by a order by b) from t;
id count task operator info
Projection_7 10000.00 root sum(a) over(partition by a order by b)
└─Window_8 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc range between unbounded preceding and current row)
└─Sort_11 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_10 10000.00 root data:TableScan_9
└─TableScan_9 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_8 10000.00 root sum(a) over(partition by a order by b)
└─Window_9 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc range between unbounded preceding and current row)
└─Sort_12 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_11 10000.00 root data:TableScan_10
└─TableScan_10 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
explain select sum(a) over(partition by a order by b rows unbounded preceding) from t;
id count task operator info
Projection_7 10000.00 root sum(a) over(partition by a order by b rows unbounded preceding)
└─Window_8 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc rows between unbounded preceding and current row)
└─Sort_11 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_10 10000.00 root data:TableScan_9
└─TableScan_9 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_8 10000.00 root sum(a) over(partition by a order by b rows unbounded preceding)
└─Window_9 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc rows between unbounded preceding and current row)
└─Sort_12 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_11 10000.00 root data:TableScan_10
└─TableScan_10 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
explain select sum(a) over(partition by a order by b rows between 1 preceding and 1 following) from t;
id count task operator info
Projection_7 10000.00 root sum(a) over(partition by a order by b rows between 1 preceding and 1 following)
└─Window_8 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc rows between 1 preceding and 1 following)
└─Sort_11 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_10 10000.00 root data:TableScan_9
└─TableScan_9 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_8 10000.00 root sum(a) over(partition by a order by b rows between 1 preceding and 1 following)
└─Window_9 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc rows between 1 preceding and 1 following)
└─Sort_12 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_11 10000.00 root data:TableScan_10
└─TableScan_10 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
explain select sum(a) over(partition by a order by b range between 1 preceding and 1 following) from t;
id count task operator info
Projection_7 10000.00 root sum(a) over(partition by a order by b range between 1 preceding and 1 following)
└─Window_8 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc range between 1 preceding and 1 following)
└─Sort_11 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_10 10000.00 root data:TableScan_9
└─TableScan_9 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_8 10000.00 root sum(a) over(partition by a order by b range between 1 preceding and 1 following)
└─Window_9 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.b asc range between 1 preceding and 1 following)
└─Sort_12 10000.00 root test.t.a:asc, test.t.b:asc
└─TableReader_11 10000.00 root data:TableScan_10
└─TableScan_10 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
explain select sum(a) over(partition by a order by c range between interval '2:30' minute_second preceding and interval '2:30' minute_second following) from t;
id count task operator info
Projection_7 10000.00 root sum(a) over(partition by a order by c range between interval '2:30' minute_second preceding and interval '2:30' minute_second following)
└─Window_8 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.c asc range between interval "2:30" "MINUTE_SECOND" preceding and interval "2:30" "MINUTE_SECOND" following)
└─Sort_11 10000.00 root test.t.a:asc, test.t.c:asc
└─TableReader_10 10000.00 root data:TableScan_9
└─TableScan_9 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
Projection_8 10000.00 root sum(a) over(partition by a order by c range between interval '2:30' minute_second preceding and interval '2:30' minute_second following)
└─Window_9 10000.00 root sum(cast(test.t.a)) over(partition by test.t.a order by test.t.c asc range between interval "2:30" "MINUTE_SECOND" preceding and interval "2:30" "MINUTE_SECOND" following)
└─Sort_12 10000.00 root test.t.a:asc, test.t.c:asc
└─TableReader_11 10000.00 root data:TableScan_10
└─TableScan_10 10000.00 cop table:t, range:[-inf,+inf], keep order:false, stats:pseudo
22 changes: 22 additions & 0 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2099,6 +2099,11 @@ func (b *PlanBuilder) buildSelect(ctx context.Context, sel *ast.SelectStmt) (p L
var windowMapper map[*ast.WindowFuncExpr]int
if hasWindowFuncField {
windowFuncs := extractWindowFuncs(sel.Fields.Fields)
// we need to check the func args first before we check the window spec
err := b.checkWindowFuncArgs(ctx, p, windowFuncs, windowAggMap)
if err != nil {
return nil, err
}
groupedFuncs, err := b.groupWindowFuncs(windowFuncs)
if err != nil {
return nil, err
Expand Down Expand Up @@ -3220,6 +3225,23 @@ func (b *PlanBuilder) buildWindowFunctionFrame(ctx context.Context, spec *ast.Wi
return frame, err
}

func (b *PlanBuilder) checkWindowFuncArgs(ctx context.Context, p LogicalPlan, windowFuncExprs []*ast.WindowFuncExpr, windowAggMap map[*ast.AggregateFuncExpr]int) error {
for _, windowFuncExpr := range windowFuncExprs {
_, _, _, args, err := b.buildProjectionForWindow(ctx, p, &ast.WindowSpec{}, windowFuncExpr.Args, windowAggMap)
alivxxx marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
desc, err := aggregation.NewWindowFuncDesc(b.ctx, windowFuncExpr.F, args)
if err != nil {
return err
}
if desc == nil {
return ErrWrongArguments.GenWithStackByArgs(strings.ToLower(windowFuncExpr.F))
}
}
return nil
}

func getAllByItems(itemsBuf []*ast.ByItem, spec *ast.WindowSpec) []*ast.ByItem {
itemsBuf = itemsBuf[:0]
if spec.PartitionBy != nil {
Expand Down
8 changes: 8 additions & 0 deletions planner/core/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,14 @@ func (s *testPlanSuite) TestWindowFunction(c *C) {
sql: "SELECT NTH_VALUE(a, 1) FROM LAST IGNORE NULLS over (partition by b order by b), a FROM t",
result: "[planner:1235]This version of TiDB doesn't yet support 'IGNORE NULLS'",
},
{
sql: "SELECT NTH_VALUE(fieldA, ATAN(-1)) OVER (w1) AS 'ntile', fieldA, fieldB FROM ( SELECT a AS fieldA, b AS fieldB FROM t ) as te WINDOW w1 AS ( ORDER BY fieldB ASC, fieldA DESC )",
result: "[planner:1210]Incorrect arguments to nth_value",
},
{
sql: "SELECT NTH_VALUE(fieldA, -1) OVER (w1 PARTITION BY fieldB ORDER BY fieldB , fieldA ) AS 'ntile', fieldA, fieldB FROM ( SELECT a AS fieldA, b AS fieldB FROM t ) as temp WINDOW w1 AS ( ORDER BY fieldB ASC, fieldA DESC )",
result: "[planner:1210]Incorrect arguments to nth_value",
},
}

s.Parser.EnableWindowFunc(true)
Expand Down