Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infoschema: Migrate the infoschema's retrieving data logic for 'schemata' to executor #14704

Merged
merged 49 commits into from
Feb 18, 2020
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
fca2edb
Merge pull request #1 from pingcap/master
reafans Nov 26, 2019
c1d631e
Merge remote-tracking branch 'origin/master'
reafans Nov 26, 2019
43000f4
Merge remote-tracking branch 'origin/master'
reafans Nov 27, 2019
f028aa5
Merge pull request #2 from pingcap/master
reafans Nov 27, 2019
46bd5cd
Merge remote-tracking branch 'origin/master'
reafans Dec 2, 2019
a633220
Merge pull request #4 from pingcap/master
reafans Dec 4, 2019
ff562d4
Merge pull request #6 from pingcap/master
reafans Dec 4, 2019
3cb0499
Merge pull request #7 from pingcap/master
reafans Dec 10, 2019
ccea6bb
Merge pull request #8 from pingcap/master
reafans Dec 12, 2019
9e1ac7e
Merge pull request #10 from pingcap/master
reafans Dec 13, 2019
3a0858b
Merge remote-tracking branch 'origin/master'
reafans Dec 17, 2019
9897e0f
Merge remote-tracking branch 'origin/master'
reafans Dec 19, 2019
5fac8ba
Merge branch 'master' of github.com:pingcap/tidb
reafans Jan 3, 2020
30acb58
Merge pull request #12 from pingcap/master
reafans Jan 6, 2020
b17d74a
Merge branch 'master' of https://github.com/pingcap/tidb
reafans Feb 2, 2020
af7949a
Merge branch 'master' of https://github.com/pingcap/tidb
reafans Feb 7, 2020
248b921
migrate retrieving data operation from infoschema pkg to executor pkg
reafans Feb 10, 2020
0fa8e1e
update
reafans Feb 10, 2020
a5e198e
fmt code
reafans Feb 10, 2020
f402b0d
fixed the comment
reafans Feb 10, 2020
404153a
update
reafans Feb 10, 2020
18b2ff5
add comment
reafans Feb 10, 2020
3dbf2cb
fixed bug
reafans Feb 10, 2020
572f82a
update
reafans Feb 10, 2020
ebc21bf
update
reafans Feb 10, 2020
19ca286
Merge branch 'master' into infoschema_to_executor
reafans Feb 10, 2020
f14730a
update
reafans Feb 10, 2020
e854952
remove the table struct, bound the getRow func to InfoschemaReaderExec
reafans Feb 11, 2020
6b565cf
address comment
reafans Feb 12, 2020
e57d613
Merge branch 'master' into infoschema_to_executor
reafans Feb 12, 2020
e234e08
fmt code
reafans Feb 12, 2020
c6d8759
format the import
reafans Feb 13, 2020
beaa367
Merge branch 'master' into infoschema_to_executor
reafans Feb 13, 2020
31bd3c9
add retriever implement
reafans Feb 14, 2020
8dca6eb
update
reafans Feb 14, 2020
e8ac309
fmt
reafans Feb 14, 2020
b4573a0
Merge branch 'infoschema_to_executor' of https://github.com/reafans/t…
reafans Feb 14, 2020
5f91c8c
Merge branch 'master' into infoschema_to_executor
reafans Feb 14, 2020
c48a796
Update infoschema_reader.go
reafans Feb 14, 2020
45f88d5
addressd comment
reafans Feb 14, 2020
0daf30f
Merge branch 'infoschema_to_executor' of https://github.com/reafans/t…
reafans Feb 14, 2020
91718ca
Merge branch 'master' into infoschema_to_executor
reafans Feb 14, 2020
5322d1f
add tableViews
reafans Feb 17, 2020
0098817
add comment
reafans Feb 17, 2020
ab59a34
fmt
reafans Feb 17, 2020
13d4946
Merge branch 'master' into infoschema_to_executor
reafans Feb 17, 2020
582721e
address comment
reafans Feb 17, 2020
4ee3479
Merge branch 'infoschema_to_executor' of https://github.com/reafans/t…
reafans Feb 17, 2020
a0039a7
Merge branch 'master' into infoschema_to_executor
crazycs520 Feb 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,7 @@ func (b *executorBuilder) getStartTS() (uint64, error) {
func (b *executorBuilder) buildMemTable(v *plannercore.PhysicalMemTable) Executor {
switch v.DBName.L {
case util.MetricSchemaName.L:
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &MetricRetriever{
table: v.Table,
Expand All @@ -1277,66 +1277,74 @@ func (b *executorBuilder) buildMemTable(v *plannercore.PhysicalMemTable) Executo
case util.InformationSchemaName.L:
switch v.Table.Name.L {
case strings.ToLower(infoschema.TableClusterConfig):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &clusterConfigRetriever{
extractor: v.Extractor.(*plannercore.ClusterTableExtractor),
},
}
case strings.ToLower(infoschema.TableClusterLoad):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &clusterServerInfoRetriever{
extractor: v.Extractor.(*plannercore.ClusterTableExtractor),
serverInfoType: diagnosticspb.ServerInfoType_LoadInfo,
},
}
case strings.ToLower(infoschema.TableClusterHardware):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &clusterServerInfoRetriever{
extractor: v.Extractor.(*plannercore.ClusterTableExtractor),
serverInfoType: diagnosticspb.ServerInfoType_HardwareInfo,
},
}
case strings.ToLower(infoschema.TableClusterSystemInfo):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &clusterServerInfoRetriever{
extractor: v.Extractor.(*plannercore.ClusterTableExtractor),
serverInfoType: diagnosticspb.ServerInfoType_SystemInfo,
},
}
case strings.ToLower(infoschema.TableClusterLog):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &clusterLogRetriever{
extractor: v.Extractor.(*plannercore.ClusterLogTableExtractor),
},
}
case strings.ToLower(infoschema.TableInspectionResult):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &inspectionRetriever{
extractor: v.Extractor.(*plannercore.InspectionResultTableExtractor),
},
}
case strings.ToLower(infoschema.TableMetricSummary):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &MetricSummaryRetriever{
table: v.Table,
extractor: v.Extractor.(*plannercore.MetricTableExtractor),
},
}
case strings.ToLower(infoschema.TableMetricSummaryByLabel):
return &ClusterReaderExec{
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &MetricSummaryByLabelRetriever{
table: v.Table,
extractor: v.Extractor.(*plannercore.MetricTableExtractor),
},
}
case strings.ToLower(infoschema.TableSchemata), strings.ToLower(infoschema.TableViews):
return &MemTableReaderExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ExplainID()),
retriever: &memtableRetriever{
table: v.Table,
columns: v.Columns,
},
}
}
}
tb, _ := b.is.TableByID(v.Table.ID)
Expand Down
16 changes: 8 additions & 8 deletions executor/cluster_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,19 @@ type dummyCloser struct{}

func (dummyCloser) close() error { return nil }

type clusterRetriever interface {
type memTableRetriever interface {
retrieve(ctx context.Context, sctx sessionctx.Context) ([][]types.Datum, error)
close() error
}

// ClusterReaderExec executes cluster information retrieving from the cluster components
type ClusterReaderExec struct {
// MemTableReaderExec executes memTable information retrieving from the MemTable components
type MemTableReaderExec struct {
baseExecutor
retriever clusterRetriever
retriever memTableRetriever
}

// Next implements the Executor Next interface.
func (e *ClusterReaderExec) Next(ctx context.Context, req *chunk.Chunk) error {
func (e *MemTableReaderExec) Next(ctx context.Context, req *chunk.Chunk) error {
rows, err := e.retriever.retrieve(ctx, e.ctx)
if err != nil {
return err
Expand All @@ -86,7 +86,7 @@ func (e *ClusterReaderExec) Next(ctx context.Context, req *chunk.Chunk) error {
}

// Close implements the Executor Close interface.
func (e *ClusterReaderExec) Close() error {
func (e *MemTableReaderExec) Close() error {
return e.retriever.close()
}

Expand All @@ -96,7 +96,7 @@ type clusterConfigRetriever struct {
extractor *plannercore.ClusterTableExtractor
}

// retrieve implements the clusterRetriever interface
// retrieve implements the memTableRetriever interface
func (e *clusterConfigRetriever) retrieve(_ context.Context, sctx sessionctx.Context) ([][]types.Datum, error) {
if e.extractor.SkipRequest || e.retrieved {
return nil, nil
Expand Down Expand Up @@ -224,7 +224,7 @@ type clusterServerInfoRetriever struct {
retrieved bool
}

// retrieve implements the clusterRetriever interface
// retrieve implements the memTableRetriever interface
func (e *clusterServerInfoRetriever) retrieve(ctx context.Context, sctx sessionctx.Context) ([][]types.Datum, error) {
if e.extractor.SkipRequest || e.retrieved {
return nil, nil
Expand Down
155 changes: 155 additions & 0 deletions executor/infoschema_reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package executor

import (
"context"
"sort"

"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
)

type memtableRetriever struct {
dummyCloser
table *model.TableInfo
columns []*model.ColumnInfo
rows [][]types.Datum
rowIdx int
retrieved bool
initialized bool
}

// retrieve implements the infoschemaRetriever interface
func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Context) ([][]types.Datum, error) {
if e.retrieved {
return nil, nil
}

//Cache the ret full rows in schemataRetriever
if !e.initialized {
is := infoschema.GetInfoSchema(sctx)
dbs := is.AllSchemas()
sort.Sort(infoschema.SchemasSorter(dbs))
var err error
switch e.table.Name.O {
case infoschema.TableSchemata:
e.rows = dataForSchemata(sctx, dbs)
case infoschema.TableViews:
e.rows, err = dataForViews(sctx, dbs)
}
if err != nil {
return nil, err
}
e.initialized = true
}

//Adjust the amount of each return
maxCount := 1024
retCount := maxCount
if e.rowIdx+maxCount > len(e.rows) {
retCount = len(e.rows) - e.rowIdx
e.retrieved = true
}
ret := make([][]types.Datum, retCount)
for i := e.rowIdx; i < e.rowIdx+retCount; i++ {
ret[i-e.rowIdx] = e.rows[i]
}
e.rowIdx += retCount
if len(e.columns) == len(e.table.Columns) {
return ret, nil
}
rows := make([][]types.Datum, len(ret))
for i, fullRow := range ret {
row := make([]types.Datum, len(e.columns))
for j, col := range e.columns {
row[j] = fullRow[col.Offset]
}
rows[i] = row
}
return rows, nil
}

func dataForSchemata(ctx sessionctx.Context, schemas []*model.DBInfo) [][]types.Datum {
checker := privilege.GetPrivilegeManager(ctx)
rows := make([][]types.Datum, 0, len(schemas))

for _, schema := range schemas {

charset := mysql.DefaultCharset
collation := mysql.DefaultCollationName

if len(schema.Charset) > 0 {
charset = schema.Charset // Overwrite default
}

if len(schema.Collate) > 0 {
collation = schema.Collate // Overwrite default
}

if checker != nil && !checker.RequestVerification(ctx.GetSessionVars().ActiveRoles, schema.Name.L, "", "", mysql.AllPrivMask) {
continue
}
record := types.MakeDatums(
infoschema.CatalogVal, // CATALOG_NAME
schema.Name.O, // SCHEMA_NAME
charset, // DEFAULT_CHARACTER_SET_NAME
collation, // DEFAULT_COLLATION_NAME
nil,
)
rows = append(rows, record)
}
return rows
}

func dataForViews(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.Datum, error) {
checker := privilege.GetPrivilegeManager(ctx)
var rows [][]types.Datum
for _, schema := range schemas {
for _, table := range schema.Tables {
if !table.IsView() {
continue
}
collation := table.Collate
charset := table.Charset
if collation == "" {
collation = mysql.DefaultCollationName
}
if charset == "" {
charset = mysql.DefaultCharset
}
if checker != nil && !checker.RequestVerification(ctx.GetSessionVars().ActiveRoles, schema.Name.L, table.Name.L, "", mysql.AllPrivMask) {
continue
}
record := types.MakeDatums(
infoschema.CatalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
table.View.SelectStmt, // VIEW_DEFINITION
table.View.CheckOption.String(), // CHECK_OPTION
"NO", // IS_UPDATABLE
table.View.Definer.String(), // DEFINER
table.View.Security.String(), // SECURITY_TYPE
charset, // CHARACTER_SET_CLIENT
collation, // COLLATION_CONNECTION
)
rows = append(rows, record)
}
}
return rows, nil
}
85 changes: 85 additions & 0 deletions executor/infoschema_reader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2020 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package executor_test

import (
. "github.com/pingcap/check"
"github.com/pingcap/parser/auth"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/util/testkit"
)

var _ = Suite(&testInfoschemaTableSuite{})

type testInfoschemaTableSuite struct {
store kv.Storage
dom *domain.Domain
}

func (s *testInfoschemaTableSuite) SetUpSuite(c *C) {
store, dom, err := newStoreWithBootstrap()
c.Assert(err, IsNil)
s.store = store
s.dom = dom
}

func (s *testInfoschemaTableSuite) TearDownSuite(c *C) {
s.dom.Close()
s.store.Close()
}
func (s *testInfoschemaTableSuite) TestSchemataTables(c *C) {
tk := testkit.NewTestKit(c, s.store)

tk.MustQuery("select * from information_schema.SCHEMATA where schema_name='mysql';").Check(
testkit.Rows("def mysql utf8mb4 utf8mb4_bin <nil>"))

//test the privilege of new user for information_schema.schemata
tk.MustExec("create user schemata_tester")
schemataTester := testkit.NewTestKit(c, s.store)
schemataTester.MustExec("use information_schema")
c.Assert(schemataTester.Se.Auth(&auth.UserIdentity{
Username: "schemata_tester",
Hostname: "127.0.0.1",
}, nil, nil), IsTrue)
schemataTester.MustQuery("select count(*) from information_schema.SCHEMATA;").Check(testkit.Rows("1"))
schemataTester.MustQuery("select * from information_schema.SCHEMATA where schema_name='mysql';").Check(
[][]interface{}{})
schemataTester.MustQuery("select * from information_schema.SCHEMATA where schema_name='INFORMATION_SCHEMA';").Check(
testkit.Rows("def INFORMATION_SCHEMA utf8mb4 utf8mb4_bin <nil>"))

//test the privilege of user with privilege of mysql for information_schema.schemata
tk.MustExec("CREATE ROLE r_mysql_priv;")
tk.MustExec("GRANT ALL PRIVILEGES ON mysql.* TO r_mysql_priv;")
tk.MustExec("GRANT r_mysql_priv TO schemata_tester;")
schemataTester.MustExec("set role r_mysql_priv")
schemataTester.MustQuery("select count(*) from information_schema.SCHEMATA;").Check(testkit.Rows("2"))
schemataTester.MustQuery("select * from information_schema.SCHEMATA;").Check(
testkit.Rows("def INFORMATION_SCHEMA utf8mb4 utf8mb4_bin <nil>", "def mysql utf8mb4 utf8mb4_bin <nil>"))
}

func (s *testInfoschemaTableSuite) TestSchemataCharacterSet(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("CREATE DATABASE `foo` DEFAULT CHARACTER SET = 'utf8mb4'")
tk.MustQuery("select default_character_set_name, default_collation_name FROM information_schema.SCHEMATA WHERE schema_name = 'foo'").Check(
testkit.Rows("utf8mb4 utf8mb4_bin"))
tk.MustExec("drop database `foo`")
}

func (s *testInfoschemaTableSuite) TestViews(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("CREATE DEFINER='root'@'localhost' VIEW test.v1 AS SELECT 1")
tk.MustQuery("SELECT * FROM information_schema.views WHERE table_schema='test' AND table_name='v1'").Check(testkit.Rows("def test v1 SELECT 1 CASCADED NO root@localhost DEFINER utf8mb4 utf8mb4_bin"))
tk.MustQuery("SELECT table_catalog, table_schema, table_name, table_type, engine, version, row_format, table_rows, avg_row_length, data_length, max_data_length, index_length, data_free, auto_increment, update_time, check_time, table_collation, checksum, create_options, table_comment FROM information_schema.tables WHERE table_schema='test' AND table_name='v1'").Check(testkit.Rows("def test v1 VIEW <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> VIEW"))
}
Loading