From 4bd25cd8bae98dca281aaaa856a12af864e6cdb7 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Tue, 12 Feb 2019 22:14:46 +0800 Subject: [PATCH 1/3] executor,planner: support show create view --- executor/errors.go | 2 ++ executor/show.go | 23 +++++++++++++++++++++++ planner/core/planbuilder.go | 5 +++++ 3 files changed, 30 insertions(+) diff --git a/executor/errors.go b/executor/errors.go index 30662d0cc2368..959c1a52cd3e7 100644 --- a/executor/errors.go +++ b/executor/errors.go @@ -48,6 +48,7 @@ var ( ErrDBaccessDenied = terror.ClassExecutor.New(mysql.ErrDBaccessDenied, mysql.MySQLErrName[mysql.ErrDBaccessDenied]) ErrTableaccessDenied = terror.ClassExecutor.New(mysql.ErrTableaccessDenied, mysql.MySQLErrName[mysql.ErrTableaccessDenied]) ErrBadDB = terror.ClassExecutor.New(mysql.ErrBadDB, mysql.MySQLErrName[mysql.ErrBadDB]) + ErrTableIsNotView = terror.ClassExecutor.New(mysql.ErrWrongObject, "'%s.%s' is not VIEW") ) func init() { @@ -63,6 +64,7 @@ func init() { mysql.ErrDBaccessDenied: mysql.ErrDBaccessDenied, mysql.ErrTableaccessDenied: mysql.ErrTableaccessDenied, mysql.ErrBadDB: mysql.ErrBadDB, + mysql.ErrWrongObject: mysql.ErrWrongObject, } terror.ErrClassToMySQLCodes[terror.ClassExecutor] = tableMySQLErrCodes } diff --git a/executor/show.go b/executor/show.go index 7964a1407c4d7..6ff56888fa5b5 100644 --- a/executor/show.go +++ b/executor/show.go @@ -107,6 +107,8 @@ func (e *ShowExec) fetchAll() error { return e.fetchShowColumns() case ast.ShowCreateTable: return e.fetchShowCreateTable() + case ast.ShowCreateView: + return e.fetchShowCreateView() case ast.ShowCreateDatabase: return e.fetchShowCreateDatabase() case ast.ShowDatabases: @@ -746,6 +748,27 @@ func (e *ShowExec) fetchShowCreateTable() error { return nil } +func (e *ShowExec) fetchShowCreateView() error { + db, ok := e.is.SchemaByName(e.DBName) + if !ok { + return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(e.DBName.O) + } + + tb, err := e.getTable() + if err != nil { + return errors.Trace(err) + } + + if !tb.Meta().IsView() { + return ErrTableIsNotView.GenWithStackByArgs(db.Name.O, tb.Meta().Name.O) + } + + var buf bytes.Buffer + e.fetchShowCreateTable4View(tb.Meta(), &buf) + e.appendRow([]interface{}{tb.Meta().Name.O, buf.String(), tb.Meta().Charset, tb.Meta().Collate}) + return nil +} + func (e *ShowExec) fetchShowCreateTable4View(tb *model.TableInfo, buf *bytes.Buffer) { sqlMode := e.ctx.GetSessionVars().SQLMode diff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go index dbb44841995eb..685878127be97 100644 --- a/planner/core/planbuilder.go +++ b/planner/core/planbuilder.go @@ -969,6 +969,9 @@ func (b *PlanBuilder) buildShow(show *ast.ShowStmt) (Plan, error) { if table, err := b.is.TableByName(show.Table.Schema, show.Table.Name); err == nil { isView = table.Meta().IsView() } + case ast.ShowCreateView: + err := ErrSpecificAccessDenied.GenWithStackByArgs("SHOW VIEW") + b.visitInfo = appendVisitInfo(b.visitInfo, mysql.ShowViewPriv, "", "", "", err) } p.SetSchema(buildShowSchema(show, isView)) } @@ -1746,6 +1749,8 @@ func buildShowSchema(s *ast.ShowStmt, isView bool) (schema *expression.Schema) { } else { names = []string{"View", "Create View", "character_set_client", "collation_connection"} } + case ast.ShowCreateView: + names = []string{"View", "Create View", "character_set_client", "collation_connection"} case ast.ShowCreateDatabase: names = []string{"Database", "Create Database"} case ast.ShowGrants: From 0f0b11a49df8e37bbf9de2ceb0968b6d123f7fb8 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Thu, 14 Feb 2019 21:01:59 +0800 Subject: [PATCH 2/3] add test --- executor/show_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/executor/show_test.go b/executor/show_test.go index d4f56fc18ef2c..3628b335abb9b 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -309,6 +309,7 @@ func (s *testSuite2) TestShowCreateTable(c *C) { tk.MustExec("drop view if exists v1") tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v1 as select * from t1") tk.MustQuery("show create table v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS select * from t1 ")) + tk.MustQuery("show create view v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS select * from t1 ")) tk.MustExec("drop view v1") tk.MustExec("drop table t1") From 4c3b230c0f3aebd36163c3ec950415e697700fb1 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sat, 16 Feb 2019 16:07:46 +0800 Subject: [PATCH 3/3] fix error --- ddl/ddl.go | 6 ++---- ddl/ddl_api.go | 6 +++--- executor/ddl_test.go | 6 +++--- executor/errors.go | 2 +- executor/show.go | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/ddl/ddl.go b/ddl/ddl.go index ee99e8e597ef2..2980fe8c93483 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -203,10 +203,8 @@ var ( ErrCoalesceOnlyOnHashPartition = terror.ClassDDL.New(codeCoalesceOnlyOnHashPartition, mysql.MySQLErrName[mysql.ErrCoalesceOnlyOnHashPartition]) // ErrViewWrongList returns create view must include all columns in the select clause ErrViewWrongList = terror.ClassDDL.New(codeViewWrongList, mysql.MySQLErrName[mysql.ErrViewWrongList]) - // ErrTableIsNotView returns for table is not view. - ErrTableIsNotView = terror.ClassDDL.New(codeErrWrongObject, "'%s.%s' is not VIEW") - // ErrTableIsNotBaseTable returns for table is not base table. - ErrTableIsNotBaseTable = terror.ClassDDL.New(codeErrWrongObject, "'%s.%s' is not BASE TABLE") + // ErrWrongObject returns for wrong object. + ErrWrongObject = terror.ClassDDL.New(codeErrWrongObject, mysql.MySQLErrName[mysql.ErrWrongObject]) ) // DDL is responsible for updating schema in data store and maintaining in-memory InfoSchema cache. diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 1e785eee65f8c..56a9af25483db 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -1162,7 +1162,7 @@ func (d *ddl) CreateView(ctx sessionctx.Context, s *ast.CreateViewStmt) (err err var oldViewTblID int64 if oldView != nil { if !oldView.Meta().IsView() { - return ErrTableIsNotView.GenWithStackByArgs(ident.Schema, ident.Name) + return ErrWrongObject.GenWithStackByArgs(ident.Schema, ident.Name, "VIEW") } oldViewTblID = oldView.Meta().ID } @@ -1425,7 +1425,7 @@ func (d *ddl) AlterTable(ctx sessionctx.Context, ident ast.Ident, specs []*ast.A is := d.infoHandle.Get() if is.TableIsView(ident.Schema, ident.Name) { - return ErrTableIsNotBaseTable.GenWithStackByArgs(ident.Schema, ident.Name) + return ErrWrongObject.GenWithStackByArgs(ident.Schema, ident.Name, "BASE TABLE") } for _, spec := range validSpecs { @@ -2382,7 +2382,7 @@ func (d *ddl) DropView(ctx sessionctx.Context, ti ast.Ident) (err error) { } if !tb.Meta().IsView() { - return ErrTableIsNotView.GenWithStackByArgs(ti.Schema, ti.Name) + return ErrWrongObject.GenWithStackByArgs(ti.Schema, ti.Name, "VIEW") } job := &model.Job{ diff --git a/executor/ddl_test.go b/executor/ddl_test.go index 2a7849595483e..d3d2f49800259 100644 --- a/executor/ddl_test.go +++ b/executor/ddl_test.go @@ -185,7 +185,7 @@ func (s *testSuite3) TestCreateView(c *C) { tk.MustExec("create or replace view v1 (c,d) as select a,b from t1 ") tk.MustExec("create table if not exists t1 (a int ,b int)") _, err = tk.Exec("create or replace view t1 as select * from t1") - c.Assert(err.Error(), Equals, ddl.ErrTableIsNotView.GenWithStackByArgs("test", "t1").Error()) + c.Assert(err.Error(), Equals, ddl.ErrWrongObject.GenWithStackByArgs("test", "t1", "VIEW").Error()) } func (s *testSuite3) TestCreateDropDatabase(c *C) { @@ -264,7 +264,7 @@ func (s *testSuite3) TestAlterTableAddColumn(c *C) { tk.MustQuery("select c3 from alter_test").Check(testkit.Rows("CURRENT_TIMESTAMP")) tk.MustExec("create or replace view alter_view as select c1,c2 from alter_test") _, err = tk.Exec("alter table alter_view add column c4 varchar(50)") - c.Assert(err.Error(), Equals, ddl.ErrTableIsNotBaseTable.GenWithStackByArgs("test", "alter_view").Error()) + c.Assert(err.Error(), Equals, ddl.ErrWrongObject.GenWithStackByArgs("test", "alter_view", "BASE TABLE").Error()) tk.MustExec("drop view alter_view") } @@ -312,7 +312,7 @@ func (s *testSuite3) TestAlterTableModifyColumn(c *C) { c.Assert(createSQL, Equals, expected) tk.MustExec("create or replace view alter_view as select c1,c2 from mc") _, err = tk.Exec("alter table alter_view modify column c2 text") - c.Assert(err.Error(), Equals, ddl.ErrTableIsNotBaseTable.GenWithStackByArgs("test", "alter_view").Error()) + c.Assert(err.Error(), Equals, ddl.ErrWrongObject.GenWithStackByArgs("test", "alter_view", "BASE TABLE").Error()) tk.MustExec("drop view alter_view") } diff --git a/executor/errors.go b/executor/errors.go index 959c1a52cd3e7..9b5caa85ac18b 100644 --- a/executor/errors.go +++ b/executor/errors.go @@ -48,7 +48,7 @@ var ( ErrDBaccessDenied = terror.ClassExecutor.New(mysql.ErrDBaccessDenied, mysql.MySQLErrName[mysql.ErrDBaccessDenied]) ErrTableaccessDenied = terror.ClassExecutor.New(mysql.ErrTableaccessDenied, mysql.MySQLErrName[mysql.ErrTableaccessDenied]) ErrBadDB = terror.ClassExecutor.New(mysql.ErrBadDB, mysql.MySQLErrName[mysql.ErrBadDB]) - ErrTableIsNotView = terror.ClassExecutor.New(mysql.ErrWrongObject, "'%s.%s' is not VIEW") + ErrWrongObject = terror.ClassExecutor.New(mysql.ErrWrongObject, mysql.MySQLErrName[mysql.ErrWrongObject]) ) func init() { diff --git a/executor/show.go b/executor/show.go index c76a78330d93f..e2105b60e34ba 100644 --- a/executor/show.go +++ b/executor/show.go @@ -761,7 +761,7 @@ func (e *ShowExec) fetchShowCreateView() error { } if !tb.Meta().IsView() { - return ErrTableIsNotView.GenWithStackByArgs(db.Name.O, tb.Meta().Name.O) + return ErrWrongObject.GenWithStackByArgs(db.Name.O, tb.Meta().Name.O, "VIEW") } var buf bytes.Buffer