Skip to content

Commit ea34b0b

Browse files
authored
planner: Do not allow variables in create view (#57474) (#59323)
close #53176
1 parent b26098f commit ea34b0b

File tree

6 files changed

+56
-3
lines changed

6 files changed

+56
-3
lines changed

cmd/explaintest/r/ddl.result

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
create view sql_mode_view as select @@sql_mode;
2+
Error 1351: View's SELECT contains a variable or parameter
3+
create view sql_mode_view as select @@global.sql_mode;
4+
Error 1351: View's SELECT contains a variable or parameter
5+
create view sql_mode_view as select @a;
6+
Error 1351: View's SELECT contains a variable or parameter
7+
create view sql_mode_view as select 1 where @a = 4;
8+
Error 1351: View's SELECT contains a variable or parameter

cmd/explaintest/t/ddl.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# issue 53176
2+
-- error 1351
3+
create view sql_mode_view as select @@sql_mode;
4+
-- error 1351
5+
create view sql_mode_view as select @@global.sql_mode;
6+
-- error 1351
7+
create view sql_mode_view as select @a;
8+
-- error 1351
9+
create view sql_mode_view as select 1 where @a = 4;

errors.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,11 @@ error = '''
856856
View's SELECT contains a '%s' clause
857857
'''
858858

859+
["ddl:1351"]
860+
error = '''
861+
View's SELECT contains a variable or parameter
862+
'''
863+
859864
["ddl:1353"]
860865
error = '''
861866
In definition of view, derived table or common table expression, SELECT list and column names list have different column counts

executor/ddl_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,8 @@ func TestCreateView(t *testing.T) {
232232
// drop multiple views in a statement
233233
tk.MustExec("drop view v1,v2,v3,v4,v5,v6")
234234
// view with variable
235-
tk.MustExec("create view v1 (c,d) as select a,b+@@global.max_user_connections from t1")
236-
tk.MustGetErrMsg("create view v1 (c,d) as select a,b from t1 where a = @@global.max_user_connections", "[schema:1050]Table 'test.v1' already exists")
237-
tk.MustExec("drop view v1")
235+
tk.MustGetErrMsg("create view v1 (c,d) as select a,b+@@global.max_user_connections from t1", "[ddl:1351]View's SELECT contains a variable or parameter")
236+
tk.MustGetErrMsg("create view v1 (c,d) as select a,b from t1 where a = @@global.max_user_connections", "[ddl:1351]View's SELECT contains a variable or parameter")
238237
// view with different col counts
239238
tk.MustGetErrCode("create view v1 (c,d,e) as select a,b from t1 ", errno.ErrViewWrongList)
240239
tk.MustGetErrCode("create view v1 (c) as select a,b from t1 ", errno.ErrViewWrongList)

planner/core/planbuilder.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4443,6 +4443,32 @@ func convertValueListToData(valueList []ast.ExprNode, handleColInfos []*model.Co
44434443
return data, nil
44444444
}
44454445

4446+
type userVariableChecker struct {
4447+
hasUserVariables bool
4448+
}
4449+
4450+
func (e *userVariableChecker) Enter(in ast.Node) (ast.Node, bool) {
4451+
if _, ok := in.(*ast.VariableExpr); ok {
4452+
e.hasUserVariables = true
4453+
return in, true
4454+
}
4455+
return in, false
4456+
}
4457+
4458+
func (*userVariableChecker) Leave(in ast.Node) (ast.Node, bool) {
4459+
return in, true
4460+
}
4461+
4462+
// Check for UserVariables
4463+
func checkForUserVariables(in ast.Node) error {
4464+
v := &userVariableChecker{hasUserVariables: false}
4465+
_, ok := in.Accept(v)
4466+
if !ok || v.hasUserVariables {
4467+
return dbterror.ErrViewSelectVariable
4468+
}
4469+
return nil
4470+
}
4471+
44464472
func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, error) {
44474473
var authErr error
44484474
switch v := node.(type) {
@@ -4582,6 +4608,10 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
45824608
v.ReferTable.Name.L, "", authErr)
45834609
}
45844610
case *ast.CreateViewStmt:
4611+
err := checkForUserVariables(v.Select)
4612+
if err != nil {
4613+
return nil, err
4614+
}
45854615
b.isCreateView = true
45864616
b.capFlag |= canExpandAST | renameView
45874617
b.renamingViewName = v.ViewName.Schema.L + "." + v.ViewName.Name.L

util/dbterror/ddl_terror.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ var (
222222
ErrErrorOnRename = ClassDDL.NewStd(mysql.ErrErrorOnRename)
223223
// ErrViewSelectClause returns error for create view with select into clause
224224
ErrViewSelectClause = ClassDDL.NewStd(mysql.ErrViewSelectClause)
225+
// ErrViewSelectVariable returns error for create view with select into clause
226+
ErrViewSelectVariable = ClassDDL.NewStd(mysql.ErrViewSelectVariable)
225227

226228
// ErrNotAllowedTypeInPartition returns not allowed type error when creating table partition with unsupported expression type.
227229
ErrNotAllowedTypeInPartition = ClassDDL.NewStd(mysql.ErrFieldTypeNotAllowedAsPartitionField)

0 commit comments

Comments
 (0)