diff --git a/ddl/error.go b/ddl/error.go index 75924ccba7053..a773edb8500a4 100644 --- a/ddl/error.go +++ b/ddl/error.go @@ -134,6 +134,8 @@ var ( ErrPrimaryCantHaveNull = terror.ClassDDL.New(mysql.ErrPrimaryCantHaveNull, mysql.MySQLErrName[mysql.ErrPrimaryCantHaveNull]) // ErrErrorOnRename returns error for wrong database name in alter table rename ErrErrorOnRename = terror.ClassDDL.New(mysql.ErrErrorOnRename, mysql.MySQLErrName[mysql.ErrErrorOnRename]) + // ErrViewSelectClause returns error for create view with select into clause + ErrViewSelectClause = terror.ClassDDL.New(mysql.ErrViewSelectClause, mysql.MySQLErrName[mysql.ErrViewSelectClause]) // ErrNotAllowedTypeInPartition returns not allowed type error when creating table partition with unsupported expression type. ErrNotAllowedTypeInPartition = terror.ClassDDL.New(mysql.ErrFieldTypeNotAllowedAsPartitionField, mysql.MySQLErrName[mysql.ErrFieldTypeNotAllowedAsPartitionField]) diff --git a/planner/core/preprocess.go b/planner/core/preprocess.go index d566b12af6c76..d098df8008c5b 100644 --- a/planner/core/preprocess.go +++ b/planner/core/preprocess.go @@ -94,6 +94,7 @@ func (p *preprocessor) Enter(in ast.Node) (out ast.Node, skipChildren bool) { case *ast.CreateViewStmt: p.flag |= inCreateOrDropTable p.checkCreateViewGrammar(node) + p.checkCreateViewWithSelectGrammar(node) case *ast.DropTableStmt: p.flag |= inCreateOrDropTable p.checkDropTableGrammar(node) @@ -459,6 +460,31 @@ func (p *preprocessor) checkCreateViewGrammar(stmt *ast.CreateViewStmt) { } } +func (p *preprocessor) checkCreateViewWithSelect(stmt *ast.SelectStmt) { + if stmt.SelectIntoOpt != nil { + p.err = ddl.ErrViewSelectClause.GenWithStackByArgs("INFO") + return + } + if stmt.LockTp != ast.SelectLockNone { + stmt.LockTp = ast.SelectLockNone + return + } +} + +func (p *preprocessor) checkCreateViewWithSelectGrammar(stmt *ast.CreateViewStmt) { + switch stmt := stmt.Select.(type) { + case *ast.SelectStmt: + p.checkCreateViewWithSelect(stmt) + case *ast.UnionStmt: + for _, selectStmt := range stmt.SelectList.Selects { + p.checkCreateViewWithSelect(selectStmt) + if p.err != nil { + return + } + } + } +} + func (p *preprocessor) checkDropSequenceGrammar(stmt *ast.DropSequenceStmt) { p.checkDropTableNames(stmt.Sequences) } diff --git a/planner/core/preprocess_test.go b/planner/core/preprocess_test.go index 95fad746cbb5f..b1143203ace7d 100644 --- a/planner/core/preprocess_test.go +++ b/planner/core/preprocess_test.go @@ -202,6 +202,9 @@ func (s *testValidatorSuite) TestValidator(c *C) { {"select * from (select 1 ) a , (select 2) b, (select * from (select 3) a join (select 4) b) c;", false, nil}, {"CREATE VIEW V (a,b,c) AS SELECT 1,1,3;", false, nil}, + {"CREATE VIEW V AS SELECT 5 INTO OUTFILE 'ttt'", true, ddl.ErrViewSelectClause.GenWithStackByArgs("INFO")}, + {"CREATE VIEW V AS SELECT 5 FOR UPDATE", false, nil}, + {"CREATE VIEW V AS SELECT 5 LOCK IN SHARE MODE", false, nil}, // issue 9464 {"CREATE TABLE t1 (id INT NOT NULL, c1 VARCHAR(20) AS ('foo') VIRTUAL KEY NULL, PRIMARY KEY (id));", false, core.ErrUnsupportedOnGeneratedColumn},