@@ -5809,11 +5809,11 @@ func (b *PlanBuilder) buildWindowFunctionFrameBound(ctx context.Context, spec *a
5809
5809
}
5810
5810
expr := expression.Constant {Value : val , RetType : boundClause .Expr .GetType ()}
5811
5811
5812
- checker := & paramMarkerInPrepareChecker {}
5812
+ checker := & expression. ParamMarkerInPrepareChecker {}
5813
5813
boundClause .Expr .Accept (checker )
5814
5814
5815
5815
// If it has paramMarker and is in prepare stmt. We don't need to eval it since its value is not decided yet.
5816
- if ! checker .inPrepareStmt {
5816
+ if ! checker .InPrepareStmt {
5817
5817
// Do not raise warnings for truncate.
5818
5818
oriIgnoreTruncate := b .ctx .GetSessionVars ().StmtCtx .IgnoreTruncate
5819
5819
b .ctx .GetSessionVars ().StmtCtx .IgnoreTruncate = true
@@ -5862,26 +5862,6 @@ func (b *PlanBuilder) buildWindowFunctionFrameBound(ctx context.Context, spec *a
5862
5862
return bound , nil
5863
5863
}
5864
5864
5865
- // paramMarkerInPrepareChecker checks whether the given ast tree has paramMarker and is in prepare statement.
5866
- type paramMarkerInPrepareChecker struct {
5867
- inPrepareStmt bool
5868
- }
5869
-
5870
- // Enter implements Visitor Interface.
5871
- func (pc * paramMarkerInPrepareChecker ) Enter (in ast.Node ) (out ast.Node , skipChildren bool ) {
5872
- switch v := in .(type ) {
5873
- case * driver.ParamMarkerExpr :
5874
- pc .inPrepareStmt = ! v .InExecute
5875
- return v , true
5876
- }
5877
- return in , false
5878
- }
5879
-
5880
- // Leave implements Visitor Interface.
5881
- func (pc * paramMarkerInPrepareChecker ) Leave (in ast.Node ) (out ast.Node , ok bool ) {
5882
- return in , true
5883
- }
5884
-
5885
5865
// buildWindowFunctionFrame builds the window function frames.
5886
5866
// See https://dev.mysql.com/doc/refman/8.0/en/window-functions-frames.html
5887
5867
func (b * PlanBuilder ) buildWindowFunctionFrame (ctx context.Context , spec * ast.WindowSpec , orderByItems []property.SortItem ) (* WindowFrame , error ) {
@@ -5900,6 +5880,7 @@ func (b *PlanBuilder) buildWindowFunctionFrame(ctx context.Context, spec *ast.Wi
5900
5880
}
5901
5881
5902
5882
func (b * PlanBuilder ) checkWindowFuncArgs (ctx context.Context , p LogicalPlan , windowFuncExprs []* ast.WindowFuncExpr , windowAggMap map [* ast.AggregateFuncExpr ]int ) error {
5883
+ checker := & expression.ParamMarkerInPrepareChecker {}
5903
5884
for _ , windowFuncExpr := range windowFuncExprs {
5904
5885
if strings .ToLower (windowFuncExpr .F ) == ast .AggFuncGroupConcat {
5905
5886
return ErrNotSupportedYet .GenWithStackByArgs ("group_concat as window function" )
@@ -5908,7 +5889,11 @@ func (b *PlanBuilder) checkWindowFuncArgs(ctx context.Context, p LogicalPlan, wi
5908
5889
if err != nil {
5909
5890
return err
5910
5891
}
5911
- desc , err := aggregation .NewWindowFuncDesc (b .ctx , windowFuncExpr .F , args )
5892
+ checker .InPrepareStmt = false
5893
+ for _ , expr := range windowFuncExpr .Args {
5894
+ expr .Accept (checker )
5895
+ }
5896
+ desc , err := aggregation .NewWindowFuncDesc (b .ctx , windowFuncExpr .F , args , checker .InPrepareStmt )
5912
5897
if err != nil {
5913
5898
return err
5914
5899
}
@@ -6018,8 +6003,13 @@ func (b *PlanBuilder) buildWindowFunctions(ctx context.Context, p LogicalPlan, g
6018
6003
schema := np .Schema ().Clone ()
6019
6004
descs := make ([]* aggregation.WindowFuncDesc , 0 , len (funcs ))
6020
6005
preArgs := 0
6006
+ checker := & expression.ParamMarkerInPrepareChecker {}
6021
6007
for _ , windowFunc := range funcs {
6022
- desc , err := aggregation .NewWindowFuncDesc (b .ctx , windowFunc .F , args [preArgs :preArgs + len (windowFunc .Args )])
6008
+ checker .InPrepareStmt = false
6009
+ for _ , expr := range windowFunc .Args {
6010
+ expr .Accept (checker )
6011
+ }
6012
+ desc , err := aggregation .NewWindowFuncDesc (b .ctx , windowFunc .F , args [preArgs :preArgs + len (windowFunc .Args )], checker .InPrepareStmt )
6023
6013
if err != nil {
6024
6014
return nil , nil , err
6025
6015
}
0 commit comments