Skip to content

Commit

Permalink
planner: Do not allow variables in create view (#57474) (#59323)
Browse files Browse the repository at this point in the history
close #53176
  • Loading branch information
ti-chi-bot authored Feb 11, 2025
1 parent b26098f commit ea34b0b
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 3 deletions.
8 changes: 8 additions & 0 deletions cmd/explaintest/r/ddl.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
create view sql_mode_view as select @@sql_mode;
Error 1351: View's SELECT contains a variable or parameter
create view sql_mode_view as select @@global.sql_mode;
Error 1351: View's SELECT contains a variable or parameter
create view sql_mode_view as select @a;
Error 1351: View's SELECT contains a variable or parameter
create view sql_mode_view as select 1 where @a = 4;
Error 1351: View's SELECT contains a variable or parameter
9 changes: 9 additions & 0 deletions cmd/explaintest/t/ddl.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# issue 53176
-- error 1351
create view sql_mode_view as select @@sql_mode;
-- error 1351
create view sql_mode_view as select @@global.sql_mode;
-- error 1351
create view sql_mode_view as select @a;
-- error 1351
create view sql_mode_view as select 1 where @a = 4;
5 changes: 5 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,11 @@ error = '''
View's SELECT contains a '%s' clause
'''

["ddl:1351"]
error = '''
View's SELECT contains a variable or parameter
'''

["ddl:1353"]
error = '''
In definition of view, derived table or common table expression, SELECT list and column names list have different column counts
Expand Down
5 changes: 2 additions & 3 deletions executor/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,8 @@ func TestCreateView(t *testing.T) {
// drop multiple views in a statement
tk.MustExec("drop view v1,v2,v3,v4,v5,v6")
// view with variable
tk.MustExec("create view v1 (c,d) as select a,b+@@global.max_user_connections from t1")
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")
tk.MustExec("drop view v1")
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")
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")
// view with different col counts
tk.MustGetErrCode("create view v1 (c,d,e) as select a,b from t1 ", errno.ErrViewWrongList)
tk.MustGetErrCode("create view v1 (c) as select a,b from t1 ", errno.ErrViewWrongList)
Expand Down
30 changes: 30 additions & 0 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4443,6 +4443,32 @@ func convertValueListToData(valueList []ast.ExprNode, handleColInfos []*model.Co
return data, nil
}

type userVariableChecker struct {
hasUserVariables bool
}

func (e *userVariableChecker) Enter(in ast.Node) (ast.Node, bool) {
if _, ok := in.(*ast.VariableExpr); ok {
e.hasUserVariables = true
return in, true
}
return in, false
}

func (*userVariableChecker) Leave(in ast.Node) (ast.Node, bool) {
return in, true
}

// Check for UserVariables
func checkForUserVariables(in ast.Node) error {
v := &userVariableChecker{hasUserVariables: false}
_, ok := in.Accept(v)
if !ok || v.hasUserVariables {
return dbterror.ErrViewSelectVariable
}
return nil
}

func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, error) {
var authErr error
switch v := node.(type) {
Expand Down Expand Up @@ -4582,6 +4608,10 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
v.ReferTable.Name.L, "", authErr)
}
case *ast.CreateViewStmt:
err := checkForUserVariables(v.Select)
if err != nil {
return nil, err
}
b.isCreateView = true
b.capFlag |= canExpandAST | renameView
b.renamingViewName = v.ViewName.Schema.L + "." + v.ViewName.Name.L
Expand Down
2 changes: 2 additions & 0 deletions util/dbterror/ddl_terror.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ var (
ErrErrorOnRename = ClassDDL.NewStd(mysql.ErrErrorOnRename)
// ErrViewSelectClause returns error for create view with select into clause
ErrViewSelectClause = ClassDDL.NewStd(mysql.ErrViewSelectClause)
// ErrViewSelectVariable returns error for create view with select into clause
ErrViewSelectVariable = ClassDDL.NewStd(mysql.ErrViewSelectVariable)

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

0 comments on commit ea34b0b

Please sign in to comment.