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

executor: fix LEAD and LAG's default value can not adapt to field type #20747

Merged
merged 7 commits into from
Dec 11, 2020
21 changes: 14 additions & 7 deletions executor/aggfuncs/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ func BuildWindowFunctions(ctx sessionctx.Context, windowFuncDesc *aggregation.Ag
case ast.WindowFuncPercentRank:
return buildPercenRank(ordinal, orderByCols)
case ast.WindowFuncLead:
return buildLead(windowFuncDesc, ordinal)
return buildLead(ctx, windowFuncDesc, ordinal)
case ast.WindowFuncLag:
return buildLag(windowFuncDesc, ordinal)
return buildLag(ctx, windowFuncDesc, ordinal)
case ast.AggFuncMax:
// The max/min aggFunc using in the window function will using the sliding window algo.
return buildMaxMinInWindowFunction(windowFuncDesc, ordinal, true)
Expand Down Expand Up @@ -692,7 +692,7 @@ func buildPercenRank(ordinal int, orderByCols []*expression.Column) AggFunc {
return &percentRank{baseAggFunc: base, rowComparer: buildRowComparer(orderByCols)}
}

func buildLeadLag(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) baseLeadLag {
func buildLeadLag(ctx sessionctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) baseLeadLag {
offset := uint64(1)
if len(aggFuncDesc.Args) >= 2 {
offset, _, _ = expression.GetUint64FromConstant(aggFuncDesc.Args[1])
Expand All @@ -701,6 +701,13 @@ func buildLeadLag(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) baseLeadLag
defaultExpr = expression.NewNull()
if len(aggFuncDesc.Args) == 3 {
defaultExpr = aggFuncDesc.Args[2]
switch et := defaultExpr.(type) {
case *expression.Constant:
res, err1 := et.Value.ConvertTo(ctx.GetSessionVars().StmtCtx, aggFuncDesc.RetTp)
if err1 == nil {
defaultExpr = &expression.Constant{Value: res, RetType: aggFuncDesc.RetTp}
}
Comment on lines +707 to +709
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if err1 is not nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if err1 not null, the type conversion is failed, just do nothing and go to the normal process

}
}
base := baseAggFunc{
args: aggFuncDesc.Args,
Expand All @@ -710,10 +717,10 @@ func buildLeadLag(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) baseLeadLag
return baseLeadLag{baseAggFunc: base, offset: offset, defaultExpr: defaultExpr, valueEvaluator: ve}
}

func buildLead(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc {
return &lead{buildLeadLag(aggFuncDesc, ordinal)}
func buildLead(ctx sessionctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc {
return &lead{buildLeadLag(ctx, aggFuncDesc, ordinal)}
}

func buildLag(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc {
return &lag{buildLeadLag(aggFuncDesc, ordinal)}
func buildLag(ctx sessionctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc {
return &lag{buildLeadLag(ctx, aggFuncDesc, ordinal)}
}
9 changes: 9 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7783,6 +7783,15 @@ func (s *testIntegrationSuite) TestIssue20180(c *C) {
tk.MustQuery("select * from t where a > 1 and a = \"b\";").Check(testkit.Rows("b"))
}

func (s *testIntegrationSuite) TestIssue11755(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists lt;")
tk.MustExec("create table lt (d decimal(10, 4));")
tk.MustExec("insert into lt values(0.2),(0.2);")
tk.MustQuery("select LEAD(d,1,1) OVER(), LAG(d,1,1) OVER() from lt;").Check(testkit.Rows("0.2000 1.0000", "1.0000 0.2000"))
}

func (s *testIntegrationSuite) TestIssue20369(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down