Skip to content

Commit

Permalink
executor: support "show create table" for View (#8865)
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewDi authored and zz-jason committed Jan 15, 2019
1 parent 41838ce commit e6a0eb9
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 5 deletions.
10 changes: 10 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,16 @@ func (d *ddl) CreateView(ctx sessionctx.Context, s *ast.CreateViewStmt) (err err
BinlogInfo: &model.HistoryInfo{},
Args: []interface{}{tbInfo, s.OrReplace},
}
if v, ok := ctx.GetSessionVars().GetSystemVar("character_set_client"); ok {
tbInfo.Charset = v
}
if v, ok := ctx.GetSessionVars().GetSystemVar("collation_connection"); ok {
tbInfo.Collate = v
}
err = checkCharsetAndCollation(tbInfo.Charset, tbInfo.Collate)
if err != nil {
return errors.Trace(err)
}
err = d.doDDLJob(ctx, job)

return d.callHookOnChanged(err)
Expand Down
23 changes: 22 additions & 1 deletion executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,12 @@ func (e *ShowExec) fetchShowCreateTable() error {

// TODO: let the result more like MySQL.
var buf bytes.Buffer
if tb.Meta().IsView() {
e.fetchShowCreateTable4View(tb.Meta(), &buf)
e.appendRow([]interface{}{tb.Meta().Name.O, buf.String(), tb.Meta().Charset, tb.Meta().Collate})
return nil
}

fmt.Fprintf(&buf, "CREATE TABLE %s (\n", escape(tb.Meta().Name, sqlMode))
var pkCol *table.Column
var hasAutoIncID bool
Expand Down Expand Up @@ -733,11 +739,26 @@ func (e *ShowExec) fetchShowCreateTable() error {
if len(tb.Meta().Comment) > 0 {
fmt.Fprintf(&buf, " COMMENT='%s'", format.OutputFormat(tb.Meta().Comment))
}

e.appendRow([]interface{}{tb.Meta().Name.O, buf.String()})
return nil
}

func (e *ShowExec) fetchShowCreateTable4View(tb *model.TableInfo, buf *bytes.Buffer) {
sqlMode := e.ctx.GetSessionVars().SQLMode

fmt.Fprintf(buf, "CREATE ALGORITHM=%s ", tb.View.Algorithm.String())
fmt.Fprintf(buf, "DEFINER=%s@%s ", escape(model.NewCIStr(tb.View.Definer.Username), sqlMode), escape(model.NewCIStr(tb.View.Definer.Hostname), sqlMode))
fmt.Fprintf(buf, "SQL SECURITY %s ", tb.View.Security.String())
fmt.Fprintf(buf, "VIEW %s (", escape(tb.Name, sqlMode))
for i, col := range tb.Columns {
fmt.Fprintf(buf, "%s", escape(col.Name, sqlMode))
if i < len(tb.Columns)-1 {
fmt.Fprintf(buf, ", ")
}
}
fmt.Fprintf(buf, ") AS %s", tb.View.SelectStmt)
}

func appendPartitionInfo(partitionInfo *model.PartitionInfo, buf *bytes.Buffer) {
if partitionInfo == nil {
return
Expand Down
14 changes: 14 additions & 0 deletions executor/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,20 @@ func (s *testSuite2) TestShowSlow(c *C) {
tk.MustQuery(`admin show slow top all 3`)
}

func (s *testSuite2) TestShowCreateTable(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int,b int)")
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.MustExec("drop view v1")
tk.MustExec("drop table t1")
}

func (s *testSuite2) TestShowEscape(c *C) {
tk := testkit.NewTestKit(c, s.store)

Expand Down
14 changes: 11 additions & 3 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -936,15 +936,19 @@ func (b *PlanBuilder) buildShow(show *ast.ShowStmt) (Plan, error) {
case ast.ShowWarnings, ast.ShowErrors:
p.SetSchema(buildShowWarningsSchema())
default:
isView := false
switch showTp {
case ast.ShowTables, ast.ShowTableStatus:
if p.DBName == "" {
return nil, ErrNoDB
}
case ast.ShowCreateTable:
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.AllPrivMask, show.Table.Schema.L, show.Table.Name.L, "", nil)
if table, err := b.is.TableByName(show.Table.Schema, show.Table.Name); err == nil {
isView = table.Meta().IsView()
}
}
p.SetSchema(buildShowSchema(show))
p.SetSchema(buildShowSchema(show, isView))
}
for _, col := range p.schema.Columns {
col.UniqueID = b.ctx.GetSessionVars().AllocPlanColumnID()
Expand Down Expand Up @@ -1667,7 +1671,7 @@ func buildShowWarningsSchema() *expression.Schema {
}

// buildShowSchema builds column info for ShowStmt including column name and type.
func buildShowSchema(s *ast.ShowStmt) (schema *expression.Schema) {
func buildShowSchema(s *ast.ShowStmt, isView bool) (schema *expression.Schema) {
var names []string
var ftypes []byte
switch s.Tp {
Expand Down Expand Up @@ -1704,7 +1708,11 @@ func buildShowSchema(s *ast.ShowStmt) (schema *expression.Schema) {
ftypes = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong,
mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong}
case ast.ShowCreateTable:
names = []string{"Table", "Create Table"}
if !isView {
names = []string{"Table", "Create Table"}
} else {
names = []string{"View", "Create View", "character_set_client", "collation_connection"}
}
case ast.ShowCreateDatabase:
names = []string{"Database", "Create Database"}
case ast.ShowGrants:
Expand Down
2 changes: 1 addition & 1 deletion planner/core/planbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *testPlanBuilderSuite) TestShow(c *C) {
}
for _, tp := range tps {
node.Tp = tp
schema := buildShowSchema(node)
schema := buildShowSchema(node, false)
for _, col := range schema.Columns {
c.Assert(col.RetType.Flen, Greater, 0)
}
Expand Down

0 comments on commit e6a0eb9

Please sign in to comment.