Skip to content

Commit

Permalink
cherry pick pingcap#33946 to release-5.3
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
tangenta authored and ti-srebot committed Apr 26, 2022
1 parent b8fbab3 commit bd3f520
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 3 deletions.
58 changes: 58 additions & 0 deletions executor/infoschema_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -986,3 +986,61 @@ func (s *testInfoschemaTableSuite) TestTablesPKType(c *C) {
tk.MustQuery("SELECT TIDB_PK_TYPE FROM information_schema.tables where table_schema = 'test' and table_name = 't_common'").Check(testkit.Rows("CLUSTERED"))
tk.MustQuery("SELECT TIDB_PK_TYPE FROM information_schema.tables where table_schema = 'INFORMATION_SCHEMA' and table_name = 'TABLES'").Check(testkit.Rows("NONCLUSTERED"))
}

// https://github.com/pingcap/tidb/issues/32459.
func TestJoinSystemTableContainsView(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t (a timestamp, b int);")
tk.MustExec("insert into t values (null, 100);")
tk.MustExec("create view v as select * from t;")
// This is used by grafana when TiDB is specified as the data source.
// See https://github.com/grafana/grafana/blob/e86b6662a187c77656f72bef3b0022bf5ced8b98/public/app/plugins/datasource/mysql/meta_query.ts#L31
for i := 0; i < 10; i++ {
tk.MustQuery(`
SELECT
table_name as table_name,
( SELECT
column_name as column_name
FROM information_schema.columns c
WHERE
c.table_schema = t.table_schema AND
c.table_name = t.table_name AND
c.data_type IN ('timestamp', 'datetime')
ORDER BY ordinal_position LIMIT 1
) AS time_column,
( SELECT
column_name AS column_name
FROM information_schema.columns c
WHERE
c.table_schema = t.table_schema AND
c.table_name = t.table_name AND
c.data_type IN('float', 'int', 'bigint')
ORDER BY ordinal_position LIMIT 1
) AS value_column
FROM information_schema.tables t
WHERE
t.table_schema = database() AND
EXISTS
( SELECT 1
FROM information_schema.columns c
WHERE
c.table_schema = t.table_schema AND
c.table_name = t.table_name AND
c.data_type IN ('timestamp', 'datetime')
) AND
EXISTS
( SELECT 1
FROM information_schema.columns c
WHERE
c.table_schema = t.table_schema AND
c.table_name = t.table_name AND
c.data_type IN('float', 'int', 'bigint')
)
LIMIT 1
;
`).Check(testkit.Rows("t a b"))
}
}
29 changes: 26 additions & 3 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -1842,9 +1842,15 @@ func (e *ShowExec) fetchShowBuiltins() error {
// 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() {
if !tbl.IsView() {
return nil
}
// We need to run the build plan process in another session because there may be
// multiple goroutines running at the same time while session is not goroutine-safe.
// Take joining system table as an example, `fetchBuildSideRows` and `fetchProbeSideChunks` can be run concurrently.
return runWithSystemSession(sctx, func(s sessionctx.Context) error {
// Retrieve view columns info.
planBuilder, _ := plannercore.NewPlanBuilder().Init(sctx, is, &hint.BlockHintProcessor{})
planBuilder, _ := plannercore.NewPlanBuilder().Init(s, is, &hint.BlockHintProcessor{})
if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, dbName, tbl); err == nil {
viewSchema := viewLogicalPlan.Schema()
viewOutputNames := viewLogicalPlan.OutputNames()
Expand All @@ -1860,6 +1866,23 @@ func tryFillViewColumnType(ctx context.Context, sctx sessionctx.Context, is info
} else {
return err
}
return nil
})
}

func runWithSystemSession(sctx sessionctx.Context, fn func(sessionctx.Context) error) error {
b := &baseExecutor{ctx: sctx}
sysCtx, err := b.getSysSession()
if err != nil {
return err
}
return nil
// TODO(tangenta): remove the CurrentDB assignment after
// https://github.com/pingcap/tidb/issues/34090 is fixed.
originDB := sysCtx.GetSessionVars().CurrentDB
sysCtx.GetSessionVars().CurrentDB = sctx.GetSessionVars().CurrentDB
defer func() {
sysCtx.GetSessionVars().CurrentDB = originDB
}()
defer b.releaseSysSession(sysCtx)
return fn(sysCtx)
}

0 comments on commit bd3f520

Please sign in to comment.