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,executor: Add CHECK_CONSTRAINTS I_S table #46428

Merged
merged 8 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions executor/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ go_test(
"index_lookup_join_test.go",
"index_lookup_merge_join_test.go",
"infoschema_cluster_table_test.go",
"infoschema_reader_internal_test.go",
"infoschema_reader_test.go",
"insert_test.go",
"inspection_common_test.go",
Expand Down
3 changes: 2 additions & 1 deletion executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,8 @@ func (b *executorBuilder) buildMemTable(v *plannercore.PhysicalMemTable) exec.Ex
strings.ToLower(infoschema.ClusterTableMemoryUsage),
strings.ToLower(infoschema.ClusterTableMemoryUsageOpsHistory),
strings.ToLower(infoschema.TableResourceGroups),
strings.ToLower(infoschema.TableRunawayWatches):
strings.ToLower(infoschema.TableRunawayWatches),
strings.ToLower(infoschema.TableCheckConstraints):
return &MemTableReaderExec{
BaseExecutor: exec.NewBaseExecutor(b.ctx, v.Schema(), v.ID()),
table: v.Table,
Expand Down
30 changes: 30 additions & 0 deletions executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Contex
err = e.setDataFromResourceGroups()
case infoschema.TableRunawayWatches:
err = e.setDataFromRunawayWatches(sctx)
case infoschema.TableCheckConstraints:
err = e.setDataFromCheckConstraints(sctx, dbs)
}
if err != nil {
return nil, err
Expand Down Expand Up @@ -627,6 +629,34 @@ func (e *memtableRetriever) setDataFromTables(ctx context.Context, sctx sessionc
return nil
}

func (e *memtableRetriever) setDataFromCheckConstraints(sctx sessionctx.Context, schemas []*model.DBInfo) error {
var rows [][]types.Datum
checker := privilege.GetPrivilegeManager(sctx)
for _, schema := range schemas {
for _, table := range schema.Tables {
if len(table.Constraints) > 0 {
if checker != nil && !checker.RequestVerification(sctx.GetSessionVars().ActiveRoles, schema.Name.L, table.Name.L, "", mysql.SelectPriv) {
continue
}
for _, constraint := range table.Constraints {
if constraint.State != model.StatePublic {
continue
}
record := types.MakeDatums(
infoschema.CatalogVal, // CONSTRAINT_CATALOG
schema.Name.O, // CONSTRAINT_SCHEMA
constraint.Name.O, // CONSTRAINT_NAME
fmt.Sprintf("(%s)", constraint.ExprString), // CHECK_CLAUSE
)
rows = append(rows, record)
}
}
}
}
e.rows = rows
return nil
}

func (e *hugeMemTableRetriever) setDataForColumns(ctx context.Context, sctx sessionctx.Context, extractor *plannercore.ColumnsTableExtractor) error {
checker := privilege.GetPrivilegeManager(sctx)
e.rows = e.rows[:0]
Expand Down
73 changes: 73 additions & 0 deletions executor/infoschema_reader_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2023 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package executor

import (
"testing"

"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/types"
"github.com/stretchr/testify/require"
)

func TestSetDataFromCheckConstraints(t *testing.T) {
mt := memtableRetriever{}
sctx := defaultCtx()
dbs := []*model.DBInfo{
{
ID: 1,
Name: model.NewCIStr("test"),
Tables: []*model.TableInfo{
{
ID: 1,
Name: model.NewCIStr("t1"),
},
{
ID: 2,
Name: model.NewCIStr("t2"),
Constraints: []*model.ConstraintInfo{
{
Name: model.NewCIStr("t2_c1"),
Table: model.NewCIStr("t2"),
ExprString: "id<10",
State: model.StatePublic,
},
},
},
{
ID: 3,
Name: model.NewCIStr("t3"),
Constraints: []*model.ConstraintInfo{
{
Name: model.NewCIStr("t3_c1"),
Table: model.NewCIStr("t3"),
ExprString: "id<10",
State: model.StateDeleteOnly,
},
},
},
},
},
}
err := mt.setDataFromCheckConstraints(sctx, dbs)
require.NoError(t, err)

require.Equal(t, 1, len(mt.rows)) // 1 row
require.Equal(t, 4, len(mt.rows[0])) // 4 columns
require.Equal(t, types.NewStringDatum("def"), mt.rows[0][0])
require.Equal(t, types.NewStringDatum("test"), mt.rows[0][1])
require.Equal(t, types.NewStringDatum("t2_c1"), mt.rows[0][2])
require.Equal(t, types.NewStringDatum("(id<10)"), mt.rows[0][3])
}
11 changes: 11 additions & 0 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ const (
TableResourceGroups = "RESOURCE_GROUPS"
// TableRunawayWatches is the query list of runaway watch.
TableRunawayWatches = "RUNAWAY_WATCHES"
// TableCheckConstraints is the list of CHECK constraints.
TableCheckConstraints = "CHECK_CONSTRAINTS"
)

const (
Expand Down Expand Up @@ -314,6 +316,7 @@ var tableIDMap = map[string]int64{
ClusterTableMemoryUsageOpsHistory: autoid.InformationSchemaDBID + 87,
TableResourceGroups: autoid.InformationSchemaDBID + 88,
TableRunawayWatches: autoid.InformationSchemaDBID + 89,
TableCheckConstraints: autoid.InformationSchemaDBID + 90,
}

// columnInfo represents the basic column information of all kinds of INFORMATION_SCHEMA tables
Expand Down Expand Up @@ -1625,6 +1628,13 @@ var tableRunawayWatchListCols = []columnInfo{
{name: "ACTION", tp: mysql.TypeVarchar, size: 12, flag: mysql.NotNullFlag},
}

var tableCheckConstraintsCols = []columnInfo{
{name: "CONSTRAINT_CATALOG", tp: mysql.TypeVarchar, size: 64, flag: mysql.NotNullFlag},
{name: "CONSTRAINT_SCHEMA", tp: mysql.TypeVarchar, size: 64, flag: mysql.NotNullFlag},
{name: "CONSTRAINT_NAME", tp: mysql.TypeVarchar, size: 64, flag: mysql.NotNullFlag},
{name: "CHECK_CLAUSE", tp: mysql.TypeLongBlob, size: types.UnspecifiedLength, flag: mysql.NotNullFlag},
}

// GetShardingInfo returns a nil or description string for the sharding information of given TableInfo.
// The returned description string may be:
// - "NOT_SHARDED": for tables that SHARD_ROW_ID_BITS is not specified.
Expand Down Expand Up @@ -2138,6 +2148,7 @@ var tableNameToColumns = map[string][]columnInfo{
TableMemoryUsageOpsHistory: tableMemoryUsageOpsHistoryCols,
TableResourceGroups: tableResourceGroupsCols,
TableRunawayWatches: tableRunawayWatchListCols,
TableCheckConstraints: tableCheckConstraintsCols,
}

func createInfoSchemaTable(_ autoid.Allocators, meta *model.TableInfo) (table.Table, error) {
Expand Down
30 changes: 30 additions & 0 deletions infoschema/test/clustertablestest/tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1811,3 +1811,33 @@ func TestAddFieldsForBinding(t *testing.T) {
require.Equal(t, rows[0][7], "use_index(@`sel_1` `test`.`t` ), ignore_index(`t` `a`)")
require.Equal(t, rows[0][8], "select * from `t` where `a` = ?")
}

func TestCheckConstraints(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("SET GLOBAL tidb_enable_check_constraint = ON")

tk.MustExec("CREATE TABLE test.t1 (id INT PRIMARY KEY, CHECK (id<10))")
rows := tk.MustQuery("SELECT * FROM information_schema.CHECK_CONSTRAINTS").Rows()
require.Equal(t, len(rows), 1)
require.Equal(t, rows[0][0], "def")
require.Equal(t, rows[0][1], "test")
require.Equal(t, rows[0][2], "t1_chk_1")
require.Equal(t, rows[0][3], "(`id` < 10)")

tk.MustExec("ALTER TABLE test.t1 DROP CONSTRAINT t1_chk_1")
rows = tk.MustQuery("SELECT * FROM information_schema.CHECK_CONSTRAINTS").Rows()
require.Equal(t, len(rows), 0)

tk.MustExec("CREATE TABLE test.t2 (id INT PRIMARY KEY, CHECK (id<20))")
rows = tk.MustQuery("SELECT * FROM information_schema.CHECK_CONSTRAINTS").Rows()
require.Equal(t, len(rows), 1)
require.Equal(t, rows[0][0], "def")
require.Equal(t, rows[0][1], "test")
require.Equal(t, rows[0][2], "t2_chk_1")
require.Equal(t, rows[0][3], "(`id` < 20)")

tk.MustExec("DROP TABLE test.t2")
rows = tk.MustQuery("SELECT * FROM information_schema.CHECK_CONSTRAINTS").Rows()
require.Equal(t, len(rows), 0)
}