Skip to content

Commit

Permalink
pingcap#22316 add a function tryFillViewColumnType, so we can reuse it.
Browse files Browse the repository at this point in the history
  • Loading branch information
beihaiguaishou committed Jan 12, 2021
1 parent 11494cd commit b041a85
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 40 deletions.
24 changes: 3 additions & 21 deletions executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"github.com/pingcap/tidb/ddl/placement"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/domain/infosync"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/meta/autoid"
plannercore "github.com/pingcap/tidb/planner/core"
Expand All @@ -51,7 +50,6 @@ import (
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/hint"
"github.com/pingcap/tidb/util/pdapi"
"github.com/pingcap/tidb/util/set"
"github.com/pingcap/tidb/util/sqlexec"
Expand Down Expand Up @@ -568,25 +566,9 @@ func (e *hugeMemTableRetriever) setDataForColumns(ctx context.Context, sctx sess
}

func (e *hugeMemTableRetriever) dataForColumnsInTable(ctx context.Context, sctx sessionctx.Context, schema *model.DBInfo, tbl *model.TableInfo) {
if tbl.IsView() {
// Retrieve view columns info.
planBuilder, _ := plannercore.NewPlanBuilder(sctx, infoschema.GetInfoSchema(sctx), &hint.BlockHintProcessor{})
if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, schema.Name, tbl); err == nil {
viewSchema := viewLogicalPlan.Schema()
viewOutputNames := viewLogicalPlan.OutputNames()
for _, col := range tbl.Columns {
idx := expression.FindFieldNameIdxByColName(viewOutputNames, col.Name.L)
if idx >= 0 {
col.FieldType = *viewSchema.Columns[idx].GetType()
}
if col.Tp == mysql.TypeVarString {
col.Tp = mysql.TypeVarchar
}
}
} else {
sctx.GetSessionVars().StmtCtx.AppendWarning(err)
return
}
if err := tryFillViewColumnType(ctx, sctx, infoschema.GetInfoSchema(sctx), schema.Name, tbl); err != nil {
sctx.GetSessionVars().StmtCtx.AppendWarning(err)
return
}
for i, col := range tbl.Columns {
if col.Hidden {
Expand Down
47 changes: 28 additions & 19 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,25 +459,8 @@ func (e *ShowExec) fetchShowColumns(ctx context.Context) error {
} else {
cols = tb.VisibleCols()
}
if tb.Meta().IsView() {
// Because view's undertable's column could change or recreate, so view's column type may change overtime.
// To avoid this situation we need to generate a logical plan and extract current column types from Schema.
planBuilder, _ := plannercore.NewPlanBuilder(e.ctx, e.is, &hint.BlockHintProcessor{})
viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, e.DBName, tb.Meta())
if err != nil {
return err
}
viewSchema := viewLogicalPlan.Schema()
viewOutputNames := viewLogicalPlan.OutputNames()
for _, col := range cols {
idx := expression.FindFieldNameIdxByColName(viewOutputNames, col.Name.L)
if idx >= 0 {
col.FieldType = *viewSchema.Columns[idx].GetType()
}
if col.Tp == mysql.TypeVarString {
col.Tp = mysql.TypeVarchar
}
}
if err := tryFillViewColumnType(ctx, e.ctx, e.is, e.DBName, tb.Meta()); err != nil {
return err
}
for _, col := range cols {
if e.Column != nil && e.Column.Name.L != col.Name.L {
Expand Down Expand Up @@ -1645,3 +1628,29 @@ func (e *ShowExec) fetchShowBuiltins() error {
}
return nil
}

// tryFillViewColumnType fill the columns type info of a view.
// Because view's underlying table's column could change or recreate, so view's column type may change over time.
// To avoid this situation we need to generate a logical plan and extract current column types from Schema.
func tryFillViewColumnType(ctx context.Context, sctx sessionctx.Context, is infoschema.InfoSchema, dbName model.CIStr, tbl *model.TableInfo) error {
if tbl.IsView() {
// Retrieve view columns info.
planBuilder, _ := plannercore.NewPlanBuilder(sctx, is, &hint.BlockHintProcessor{})
if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, dbName, tbl); err == nil {
viewSchema := viewLogicalPlan.Schema()
viewOutputNames := viewLogicalPlan.OutputNames()
for _, col := range tbl.Columns {
idx := expression.FindFieldNameIdxByColName(viewOutputNames, col.Name.L)
if idx >= 0 {
col.FieldType = *viewSchema.Columns[idx].GetType()
}
if col.Tp == mysql.TypeVarString {
col.Tp = mysql.TypeVarchar
}
}
} else {
return err
}
}
return nil
}

0 comments on commit b041a85

Please sign in to comment.