1 Star 0 Fork 0

zhoujin826/tidb

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
tables.go 47.50 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
// Copyright 2016 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 infoschema
import (
"fmt"
"sort"
"github.com/juju/errors"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/charset"
"github.com/pingcap/tidb/util/sqlexec"
)
const (
tableSchemata = "SCHEMATA"
tableTables = "TABLES"
tableColumns = "COLUMNS"
tableStatistics = "STATISTICS"
tableCharacterSets = "CHARACTER_SETS"
tableCollations = "COLLATIONS"
tableFiles = "FILES"
catalogVal = "def"
tableProfiling = "PROFILING"
tablePartitions = "PARTITIONS"
tableKeyColumm = "KEY_COLUMN_USAGE"
tableReferConst = "REFERENTIAL_CONSTRAINTS"
tableSessionVar = "SESSION_VARIABLES"
tablePlugins = "PLUGINS"
tableConstraints = "TABLE_CONSTRAINTS"
tableTriggers = "TRIGGERS"
tableUserPrivileges = "USER_PRIVILEGES"
tableSchemaPrivileges = "SCHEMA_PRIVILEGES"
tableTablePrivileges = "TABLE_PRIVILEGES"
tableColumnPrivileges = "COLUMN_PRIVILEGES"
tableEngines = "ENGINES"
tableViews = "VIEWS"
tableRoutines = "ROUTINES"
tableParameters = "PARAMETERS"
tableEvents = "EVENTS"
tableGlobalStatus = "GLOBAL_STATUS"
tableGlobalVariables = "GLOBAL_VARIABLES"
tableSessionStatus = "SESSION_STATUS"
tableOptimizerTrace = "OPTIMIZER_TRACE"
tableTableSpaces = "TABLESPACES"
tableCollationCharacterSetApplicability = "COLLATION_CHARACTER_SET_APPLICABILITY"
)
type columnInfo struct {
name string
tp byte
size int
flag uint
deflt interface{}
elems []string
}
func buildColumnInfo(tableName string, col columnInfo) *model.ColumnInfo {
mCharset := charset.CharsetBin
mCollation := charset.CharsetBin
mFlag := mysql.UnsignedFlag
if col.tp == mysql.TypeVarchar || col.tp == mysql.TypeBlob {
mCharset = mysql.DefaultCharset
mCollation = mysql.DefaultCollationName
mFlag = col.flag
}
fieldType := types.FieldType{
Charset: mCharset,
Collate: mCollation,
Tp: col.tp,
Flen: col.size,
Flag: mFlag,
}
return &model.ColumnInfo{
Name: model.NewCIStr(col.name),
FieldType: fieldType,
State: model.StatePublic,
}
}
func buildTableMeta(tableName string, cs []columnInfo) *model.TableInfo {
cols := make([]*model.ColumnInfo, 0, len(cs))
for _, c := range cs {
cols = append(cols, buildColumnInfo(tableName, c))
}
for i, col := range cols {
col.Offset = i
}
return &model.TableInfo{
Name: model.NewCIStr(tableName),
Columns: cols,
State: model.StatePublic,
Charset: mysql.DefaultCharset,
Collate: mysql.DefaultCollationName,
}
}
var schemataCols = []columnInfo{
{"CATALOG_NAME", mysql.TypeVarchar, 512, 0, nil, nil},
{"SCHEMA_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"DEFAULT_CHARACTER_SET_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"DEFAULT_COLLATION_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"SQL_PATH", mysql.TypeVarchar, 512, 0, nil, nil},
}
var tablesCols = []columnInfo{
{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
{"ENGINE", mysql.TypeVarchar, 64, 0, nil, nil},
{"VERSION", mysql.TypeLonglong, 21, 0, nil, nil},
{"ROW_FORMAT", mysql.TypeVarchar, 10, 0, nil, nil},
{"TABLE_ROWS", mysql.TypeLonglong, 21, 0, nil, nil},
{"AVG_ROW_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"MAX_DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"INDEX_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"DATA_FREE", mysql.TypeLonglong, 21, 0, nil, nil},
{"AUTO_INCREMENT", mysql.TypeLonglong, 21, 0, nil, nil},
{"CREATE_TIME", mysql.TypeDatetime, 19, 0, nil, nil},
{"UPDATE_TIME", mysql.TypeDatetime, 19, 0, nil, nil},
{"CHECK_TIME", mysql.TypeDatetime, 19, 0, nil, nil},
{"TABLE_COLLATION", mysql.TypeVarchar, 32, mysql.NotNullFlag, "utf8_bin", nil},
{"CHECK_SUM", mysql.TypeLonglong, 21, 0, nil, nil},
{"CREATE_OPTIONS", mysql.TypeVarchar, 255, 0, nil, nil},
{"TABLE_COMMENT", mysql.TypeVarchar, 2048, 0, nil, nil},
}
// See: http://dev.mysql.com/doc/refman/5.7/en/columns-table.html
var columnsCols = []columnInfo{
{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"COLUMN_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"ORDINAL_POSITION", mysql.TypeLonglong, 64, 0, nil, nil},
{"COLUMN_DEFAULT", mysql.TypeBlob, 196606, 0, nil, nil},
{"IS_NULLABLE", mysql.TypeVarchar, 3, 0, nil, nil},
{"DATA_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
{"CHARACTER_MAXIMUM_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"CHARACTER_OCTET_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"NUMERIC_PRECISION", mysql.TypeLonglong, 21, 0, nil, nil},
{"NUMERIC_SCALE", mysql.TypeLonglong, 21, 0, nil, nil},
{"DATETIME_PRECISION", mysql.TypeLonglong, 21, 0, nil, nil},
{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"COLLATION_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"COLUMN_TYPE", mysql.TypeBlob, 196606, 0, nil, nil},
{"COLUMN_KEY", mysql.TypeVarchar, 3, 0, nil, nil},
{"EXTRA", mysql.TypeVarchar, 30, 0, nil, nil},
{"PRIVILEGES", mysql.TypeVarchar, 80, 0, nil, nil},
{"COLUMN_COMMENT", mysql.TypeVarchar, 1024, 0, nil, nil},
}
var statisticsCols = []columnInfo{
{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"NON_UNIQUE", mysql.TypeVarchar, 1, 0, nil, nil},
{"INDEX_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"INDEX_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"SEQ_IN_INDEX", mysql.TypeLonglong, 2, 0, nil, nil},
{"COLUMN_NAME", mysql.TypeVarchar, 21, 0, nil, nil},
{"COLLATION", mysql.TypeVarchar, 1, 0, nil, nil},
{"CARDINALITY", mysql.TypeLonglong, 21, 0, nil, nil},
{"SUB_PART", mysql.TypeLonglong, 3, 0, nil, nil},
{"PACKED", mysql.TypeVarchar, 10, 0, nil, nil},
{"NULLABLE", mysql.TypeVarchar, 3, 0, nil, nil},
{"INDEX_TYPE", mysql.TypeVarchar, 16, 0, nil, nil},
{"COMMENT", mysql.TypeVarchar, 16, 0, nil, nil},
{"INDEX_COMMENT", mysql.TypeVarchar, 1024, 0, nil, nil},
}
var profilingCols = []columnInfo{
{"QUERY_ID", mysql.TypeLong, 20, 0, nil, nil},
{"SEQ", mysql.TypeLong, 20, 0, nil, nil},
{"STATE", mysql.TypeVarchar, 30, 0, nil, nil},
{"DURATION", mysql.TypeNewDecimal, 9, 0, nil, nil},
{"CPU_USER", mysql.TypeNewDecimal, 9, 0, nil, nil},
{"CPU_SYSTEM", mysql.TypeNewDecimal, 9, 0, nil, nil},
{"CONTEXT_VOLUNTARY", mysql.TypeLong, 20, 0, nil, nil},
{"CONTEXT_INVOLUNTARY", mysql.TypeLong, 20, 0, nil, nil},
{"BLOCK_OPS_IN", mysql.TypeLong, 20, 0, nil, nil},
{"BLOCK_OPS_OUT", mysql.TypeLong, 20, 0, nil, nil},
{"MESSAGES_SENT", mysql.TypeLong, 20, 0, nil, nil},
{"MESSAGES_RECEIVED", mysql.TypeLong, 20, 0, nil, nil},
{"PAGE_FAULTS_MAJOR", mysql.TypeLong, 20, 0, nil, nil},
{"PAGE_FAULTS_MINOR", mysql.TypeLong, 20, 0, nil, nil},
{"SWAPS", mysql.TypeLong, 20, 0, nil, nil},
{"SOURCE_FUNCTION", mysql.TypeVarchar, 30, 0, nil, nil},
{"SOURCE_FILE", mysql.TypeVarchar, 20, 0, nil, nil},
{"SOURCE_LINE", mysql.TypeLong, 20, 0, nil, nil},
}
var charsetCols = []columnInfo{
{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"DEFAULT_COLLATE_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"DESCRIPTION", mysql.TypeVarchar, 60, 0, nil, nil},
{"MAXLEN", mysql.TypeLonglong, 3, 0, nil, nil},
}
var collationsCols = []columnInfo{
{"COLLATION_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
{"ID", mysql.TypeLonglong, 11, 0, nil, nil},
{"IS_DEFAULT", mysql.TypeVarchar, 3, 0, nil, nil},
{"IS_COMPILED", mysql.TypeVarchar, 3, 0, nil, nil},
{"SORTLEN", mysql.TypeLonglong, 3, 0, nil, nil},
}
var keyColumnUsageCols = []columnInfo{
{"CONSTRAINT_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"CONSTRAINT_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"CONSTRAINT_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"TABLE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"COLUMN_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"ORDINAL_POSITION", mysql.TypeLonglong, 10, mysql.NotNullFlag, nil, nil},
{"POSITION_IN_UNIQUE_CONSTRAINT", mysql.TypeLonglong, 10, 0, nil, nil},
{"REFERENCED_TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"REFERENCED_TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"REFERENCED_COLUMN_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
}
// See http://dev.mysql.com/doc/refman/5.7/en/referential-constraints-table.html
var referConstCols = []columnInfo{
{"CONSTRAINT_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"CONSTRAINT_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"CONSTRAINT_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"UNIQUE_CONSTRAINT_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"UNIQUE_CONSTRAINT_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"UNIQUE_CONSTRAINT_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"MATCH_OPTION", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"UPDATE_RULE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"DELETE_RULE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"REFERENCED_TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
}
// See http://dev.mysql.com/doc/refman/5.7/en/variables-table.html
var sessionVarCols = []columnInfo{
{"VARIABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"VARIABLE_VALUE", mysql.TypeVarchar, 1024, 0, nil, nil},
}
// See https://dev.mysql.com/doc/refman/5.7/en/plugins-table.html
var pluginsCols = []columnInfo{
{"PLUGIN_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"PLUGIN_VERSION", mysql.TypeVarchar, 20, 0, nil, nil},
{"PLUGIN_STATUS", mysql.TypeVarchar, 10, 0, nil, nil},
{"PLUGIN_TYPE", mysql.TypeVarchar, 80, 0, nil, nil},
{"PLUGIN_TYPE_VERSION", mysql.TypeVarchar, 20, 0, nil, nil},
{"PLUGIN_LIBRARY", mysql.TypeVarchar, 64, 0, nil, nil},
{"PLUGIN_LIBRARY_VERSION", mysql.TypeVarchar, 20, 0, nil, nil},
{"PLUGIN_AUTHOR", mysql.TypeVarchar, 64, 0, nil, nil},
{"PLUGIN_DESCRIPTION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
{"PLUGIN_LICENSE", mysql.TypeVarchar, 80, 0, nil, nil},
{"LOAD_OPTION", mysql.TypeVarchar, 64, 0, nil, nil},
}
// See https://dev.mysql.com/doc/refman/5.7/en/partitions-table.html
var partitionsCols = []columnInfo{
{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"PARTITION_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"SUBPARTITION_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"PARTITION_ORDINAL_POSITION", mysql.TypeLonglong, 21, 0, nil, nil},
{"SUBPARTITION_ORDINAL_POSITION", mysql.TypeLonglong, 21, 0, nil, nil},
{"PARTITION_METHOD", mysql.TypeVarchar, 18, 0, nil, nil},
{"SUBPARTITION_METHOD", mysql.TypeVarchar, 12, 0, nil, nil},
{"PARTITION_EXPRESSION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
{"SUBPARTITION_EXPRESSION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
{"PARTITION_DESCRIPTION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
{"TABLE_ROWS", mysql.TypeLonglong, 21, 0, nil, nil},
{"AVG_ROW_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"MAX_DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"INDEX_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"DATA_FREE", mysql.TypeLonglong, 21, 0, nil, nil},
{"CREATE_TIME", mysql.TypeDatetime, 0, 0, nil, nil},
{"UPDATE_TIME", mysql.TypeDatetime, 0, 0, nil, nil},
{"CHECK_TIME", mysql.TypeDatetime, 0, 0, nil, nil},
{"CHECKSUM", mysql.TypeLonglong, 21, 0, nil, nil},
{"PARTITION_COMMENT", mysql.TypeVarchar, 80, 0, nil, nil},
{"NODEGROUP", mysql.TypeVarchar, 12, 0, nil, nil},
{"TABLESPACE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
}
var tableConstraintsCols = []columnInfo{
{"CONSTRAINT_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"CONSTRAINT_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"CONSTRAINT_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"CONSTRAINT_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
}
var tableTriggersCols = []columnInfo{
{"TRIGGER_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"TRIGGER_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TRIGGER_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"EVENT_MANIPULATION", mysql.TypeVarchar, 6, 0, nil, nil},
{"EVENT_OBJECT_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"EVENT_OBJECT_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"EVENT_OBJECT_TABLE", mysql.TypeVarchar, 64, 0, nil, nil},
{"ACTION_ORDER", mysql.TypeLonglong, 4, 0, nil, nil},
{"ACTION_CONDITION", mysql.TypeBlob, -1, 0, nil, nil},
{"ACTION_STATEMENT", mysql.TypeBlob, -1, 0, nil, nil},
{"ACTION_ORIENTATION", mysql.TypeVarchar, 9, 0, nil, nil},
{"ACTION_TIMING", mysql.TypeVarchar, 6, 0, nil, nil},
{"ACTION_REFERENCE_OLD_TABLE", mysql.TypeVarchar, 64, 0, nil, nil},
{"ACTION_REFERENCE_NEW_TABLE", mysql.TypeVarchar, 64, 0, nil, nil},
{"ACTION_REFERENCE_OLD_ROW", mysql.TypeVarchar, 3, 0, nil, nil},
{"ACTION_REFERENCE_NEW_ROW", mysql.TypeVarchar, 3, 0, nil, nil},
{"CREATED", mysql.TypeDatetime, 2, 0, nil, nil},
{"SQL_MODE", mysql.TypeVarchar, 8192, 0, nil, nil},
{"DEFINER", mysql.TypeVarchar, 77, 0, nil, nil},
{"CHARACTER_SET_CLIENT", mysql.TypeVarchar, 32, 0, nil, nil},
{"COLLATION_CONNECTION", mysql.TypeVarchar, 32, 0, nil, nil},
{"DATABASE_COLLATION", mysql.TypeVarchar, 32, 0, nil, nil},
}
var tableUserPrivilegesCols = []columnInfo{
{"GRANTEE", mysql.TypeVarchar, 81, 0, nil, nil},
{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
{"PRIVILEGE_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
{"IS_GRANTABLE", mysql.TypeVarchar, 3, 0, nil, nil},
}
var tableSchemaPrivilegesCols = []columnInfo{
{"GRANTEE", mysql.TypeVarchar, 81, mysql.NotNullFlag, nil, nil},
{"TABLE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"PRIVILEGE_TYPE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"IS_GRANTABLE", mysql.TypeVarchar, 3, mysql.NotNullFlag, nil, nil},
}
var tableTablePrivilegesCols = []columnInfo{
{"GRANTEE", mysql.TypeVarchar, 81, mysql.NotNullFlag, nil, nil},
{"TABLE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"PRIVILEGE_TYPE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"IS_GRANTABLE", mysql.TypeVarchar, 3, mysql.NotNullFlag, nil, nil},
}
var tableColumnPrivilegesCols = []columnInfo{
{"GRANTEE", mysql.TypeVarchar, 81, mysql.NotNullFlag, nil, nil},
{"TABLE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"COLUMN_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"PRIVILEGE_TYPE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"IS_GRANTABLE", mysql.TypeVarchar, 3, mysql.NotNullFlag, nil, nil},
}
var tableEnginesCols = []columnInfo{
{"ENGINE", mysql.TypeVarchar, 64, 0, nil, nil},
{"SUPPORT", mysql.TypeVarchar, 8, 0, nil, nil},
{"COMMENT", mysql.TypeVarchar, 80, 0, nil, nil},
{"TRANSACTIONS", mysql.TypeVarchar, 3, 0, nil, nil},
{"XA", mysql.TypeVarchar, 3, 0, nil, nil},
{"SAVEPOINTS", mysql.TypeVarchar, 3, 0, nil, nil},
}
var tableViewsCols = []columnInfo{
{"TABLE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"VIEW_DEFINITION", mysql.TypeLongBlob, 0, mysql.NotNullFlag, nil, nil},
{"CHECK_OPTION", mysql.TypeVarchar, 8, mysql.NotNullFlag, nil, nil},
{"IS_UPDATABLE", mysql.TypeVarchar, 3, mysql.NotNullFlag, nil, nil},
{"DEFINER", mysql.TypeVarchar, 77, mysql.NotNullFlag, nil, nil},
{"SECURITY_TYPE", mysql.TypeVarchar, 7, mysql.NotNullFlag, nil, nil},
{"CHARACTER_SET_CLIENT", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
{"COLLATION_CONNECTION", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
}
var tableRoutinesCols = []columnInfo{
{"SPECIFIC_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"ROUTINE_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"ROUTINE_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"ROUTINE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"ROUTINE_TYPE", mysql.TypeVarchar, 9, mysql.NotNullFlag, nil, nil},
{"DATA_TYPE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"CHARACTER_MAXIMUM_LENGTH", mysql.TypeLong, 21, 0, nil, nil},
{"CHARACTER_OCTET_LENGTH", mysql.TypeLong, 21, 0, nil, nil},
{"NUMERIC_PRECISION", mysql.TypeLonglong, 21, 0, nil, nil},
{"NUMERIC_SCALE", mysql.TypeLong, 21, 0, nil, nil},
{"DATETIME_PRECISION", mysql.TypeLonglong, 21, 0, nil, nil},
{"CHARACTER_SET_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"COLLATION_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"DTD_IDENTIFIER", mysql.TypeLongBlob, 0, 0, nil, nil},
{"ROUTINE_BODY", mysql.TypeVarchar, 8, mysql.NotNullFlag, nil, nil},
{"ROUTINE_DEFINITION", mysql.TypeLongBlob, 0, 0, nil, nil},
{"EXTERNAL_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"EXTERNAL_LANGUAGE", mysql.TypeVarchar, 64, 0, nil, nil},
{"PARAMETER_STYLE", mysql.TypeVarchar, 8, mysql.NotNullFlag, nil, nil},
{"IS_DETERMINISTIC", mysql.TypeVarchar, 3, mysql.NotNullFlag, nil, nil},
{"SQL_DATA_ACCESS", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"SQL_PATH", mysql.TypeVarchar, 64, 0, nil, nil},
{"SECURITY_TYPE", mysql.TypeVarchar, 7, mysql.NotNullFlag, nil, nil},
{"CREATED", mysql.TypeDatetime, 0, mysql.NotNullFlag, "0000-00-00 00:00:00", nil},
{"LAST_ALTERED", mysql.TypeDatetime, 0, mysql.NotNullFlag, "0000-00-00 00:00:00", nil},
{"SQL_MODE", mysql.TypeVarchar, 8192, mysql.NotNullFlag, nil, nil},
{"ROUTINE_COMMENT", mysql.TypeLongBlob, 0, 0, nil, nil},
{"DEFINER", mysql.TypeVarchar, 77, mysql.NotNullFlag, nil, nil},
{"CHARACTER_SET_CLIENT", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
{"COLLATION_CONNECTION", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
{"DATABASE_COLLATION", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
}
var tableParametersCols = []columnInfo{
{"SPECIFIC_CATALOG", mysql.TypeVarchar, 512, mysql.NotNullFlag, nil, nil},
{"SPECIFIC_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"SPECIFIC_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"ORDINAL_POSITION", mysql.TypeVarchar, 21, mysql.NotNullFlag, nil, nil},
{"PARAMETER_MODE", mysql.TypeVarchar, 5, 0, nil, nil},
{"PARAMETER_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"DATA_TYPE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"CHARACTER_MAXIMUM_LENGTH", mysql.TypeVarchar, 21, 0, nil, nil},
{"CHARACTER_OCTET_LENGTH", mysql.TypeVarchar, 21, 0, nil, nil},
{"NUMERIC_PRECISION", mysql.TypeVarchar, 21, 0, nil, nil},
{"NUMERIC_SCALE", mysql.TypeVarchar, 21, 0, nil, nil},
{"DATETIME_PRECISION", mysql.TypeVarchar, 21, 0, nil, nil},
{"CHARACTER_SET_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"COLLATION_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"DTD_IDENTIFIER", mysql.TypeLongBlob, 0, mysql.NotNullFlag, nil, nil},
{"ROUTINE_TYPE", mysql.TypeVarchar, 9, mysql.NotNullFlag, nil, nil},
}
var tableEventsCols = []columnInfo{
{"EVENT_CATALOG", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"EVENT_SCHEMA", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"EVENT_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"DEFINER", mysql.TypeVarchar, 77, mysql.NotNullFlag, nil, nil},
{"TIME_ZONE", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"EVENT_BODY", mysql.TypeVarchar, 8, mysql.NotNullFlag, nil, nil},
{"EVENT_DEFINITION", mysql.TypeLongBlob, 0, 0, nil, nil},
{"EVENT_TYPE", mysql.TypeVarchar, 9, mysql.NotNullFlag, nil, nil},
{"EXECUTE_AT", mysql.TypeDatetime, 0, 0, nil, nil},
{"INTERVAL_VALUE", mysql.TypeVarchar, 256, 0, nil, nil},
{"INTERVAL_FIELD", mysql.TypeVarchar, 18, 0, nil, nil},
{"SQL_MODE", mysql.TypeVarchar, 8192, mysql.NotNullFlag, nil, nil},
{"STARTS", mysql.TypeDatetime, 0, 0, nil, nil},
{"ENDS", mysql.TypeDatetime, 0, 0, nil, nil},
{"STATUS", mysql.TypeVarchar, 18, mysql.NotNullFlag, nil, nil},
{"ON_COMPLETION", mysql.TypeVarchar, 12, mysql.NotNullFlag, nil, nil},
{"CREATED", mysql.TypeDatetime, 0, mysql.NotNullFlag, "0000-00-00 00:00:00", nil},
{"LAST_ALTERED", mysql.TypeDatetime, 0, mysql.NotNullFlag, "0000-00-00 00:00:00", nil},
{"LAST_EXECUTED", mysql.TypeDatetime, 0, 0, nil, nil},
{"EVENT_COMMENT", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"ORIGINATOR", mysql.TypeLong, 10, mysql.NotNullFlag, 0, nil},
{"CHARACTER_SET_CLIENT", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
{"COLLATION_CONNECTION", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
{"DATABASE_COLLATION", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
}
var tableGlobalStatusCols = []columnInfo{
{"VARIABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"VARIABLE_VALUE", mysql.TypeVarchar, 1024, 0, nil, nil},
}
var tableGlobalVariablesCols = []columnInfo{
{"VARIABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"VARIABLE_VALUE", mysql.TypeVarchar, 1024, 0, nil, nil},
}
var tableSessionStatusCols = []columnInfo{
{"VARIABLE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, nil, nil},
{"VARIABLE_VALUE", mysql.TypeVarchar, 1024, 0, nil, nil},
}
var tableOptimizerTraceCols = []columnInfo{
{"QUERY", mysql.TypeLongBlob, 0, mysql.NotNullFlag, "", nil},
{"TRACE", mysql.TypeLongBlob, 0, mysql.NotNullFlag, "", nil},
{"MISSING_BYTES_BEYOND_MAX_MEM_SIZE", mysql.TypeShort, 20, mysql.NotNullFlag, 0, nil},
{"INSUFFICIENT_PRIVILEGES", mysql.TypeTiny, 1, mysql.NotNullFlag, 0, nil},
}
var tableTableSpacesCols = []columnInfo{
{"TABLESPACE_NAME", mysql.TypeVarchar, 64, mysql.NotNullFlag, "", nil},
{"ENGINE", mysql.TypeVarchar, 64, mysql.NotNullFlag, "", nil},
{"TABLESPACE_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
{"LOGFILE_GROUP_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"EXTENT_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
{"AUTOEXTEND_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
{"MAXIMUM_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
{"NODEGROUP_ID", mysql.TypeLonglong, 21, 0, nil, nil},
{"TABLESPACE_COMMENT", mysql.TypeVarchar, 2048, 0, nil, nil},
}
var tableCollationCharacterSetApplicabilityCols = []columnInfo{
{"COLLATION_NAME", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, mysql.NotNullFlag, nil, nil},
}
func dataForCharacterSets() (records [][]types.Datum) {
records = append(records,
types.MakeDatums("ascii", "ascii_general_ci", "US ASCII", 1),
types.MakeDatums("binary", "binary", "Binary pseudo charset", 1),
types.MakeDatums("latin1", "latin1_swedish_ci", "cp1252 West European", 1),
types.MakeDatums("utf8", "utf8_general_ci", "UTF-8 Unicode", 3),
types.MakeDatums("utf8mb4", "utf8mb4_general_ci", "UTF-8 Unicode", 4),
)
return records
}
func dataForColltions() (records [][]types.Datum) {
records = append(records,
types.MakeDatums("ascii_general_ci", "ascii", 1, "Yes", "Yes", 1),
types.MakeDatums("binary", "binary", 2, "Yes", "Yes", 1),
types.MakeDatums("latin1_swedish_ci", "latin1", 3, "Yes", "Yes", 1),
types.MakeDatums("utf8_general_ci", "utf8", 4, "Yes", "Yes", 1),
types.MakeDatums("utf8mb4_general_ci", "utf8mb4", 5, "Yes", "Yes", 1),
)
return records
}
func dataForCollationCharacterSetApplicability() (records [][]types.Datum) {
records = append(records,
types.MakeDatums("ascii_general_ci", "ascii"),
types.MakeDatums("binary", "binary"),
types.MakeDatums("latin1_swedish_ci", "latin1"),
types.MakeDatums("utf8_general_ci", "utf8"),
types.MakeDatums("utf8_bin", "utf8"),
types.MakeDatums("utf8mb4_general_ci", "utf8mb4"),
)
return records
}
func dataForSessionVar(ctx sessionctx.Context) (records [][]types.Datum, err error) {
sessionVars := ctx.GetSessionVars()
for _, v := range variable.SysVars {
var value string
value, err = variable.GetSessionSystemVar(sessionVars, v.Name)
if err != nil {
return nil, errors.Trace(err)
}
row := types.MakeDatums(v.Name, value)
records = append(records, row)
}
return
}
func dataForUserPrivileges(ctx sessionctx.Context) [][]types.Datum {
pm := privilege.GetPrivilegeManager(ctx)
return pm.UserPrivilegesTable()
}
func dataForEngines() (records [][]types.Datum) {
records = append(records,
types.MakeDatums("InnoDB", "DEFAULT", "Supports transactions, row-level locking, and foreign keys", "YES", "YES", "YES"),
types.MakeDatums("CSV", "YES", "CSV storage engine", "NO", "NO", "NO"),
types.MakeDatums("MRG_MYISAM", "YES", "Collection of identical MyISAM tables", "NO", "NO", "NO"),
types.MakeDatums("BLACKHOLE", "YES", "/dev/null storage engine (anything you write to it disappears)", "NO", "NO", "NO"),
types.MakeDatums("MyISAM", "YES", "MyISAM storage engine", "NO", "NO", "NO"),
types.MakeDatums("MEMORY", "YES", "Hash based, stored in memory, useful for temporary tables", "NO", "NO", "NO"),
types.MakeDatums("ARCHIVE", "YES", "Archive storage engine", "NO", "NO", "NO"),
types.MakeDatums("FEDERATED", "NO", "Federated MySQL storage engine", nil, nil, nil),
types.MakeDatums("PERFORMANCE_SCHEMA", "YES", "Performance Schema", "NO", "NO", "NO"),
)
return records
}
var filesCols = []columnInfo{
{"FILE_ID", mysql.TypeLonglong, 4, 0, nil, nil},
{"FILE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"FILE_TYPE", mysql.TypeVarchar, 20, 0, nil, nil},
{"TABLESPACE_NAME", mysql.TypeVarchar, 20, 0, nil, nil},
{"TABLE_CATALOG", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"LOGFILE_GROUP_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
{"LOGFILE_GROUP_NUMBER", mysql.TypeLonglong, 32, 0, nil, nil},
{"ENGINE", mysql.TypeVarchar, 64, 0, nil, nil},
{"FULLTEXT_KEYS", mysql.TypeVarchar, 64, 0, nil, nil},
{"DELETED_ROWS", mysql.TypeLonglong, 4, 0, nil, nil},
{"UPDATE_COUNT", mysql.TypeLonglong, 4, 0, nil, nil},
{"FREE_EXTENTS", mysql.TypeLonglong, 4, 0, nil, nil},
{"TOTAL_EXTENTS", mysql.TypeLonglong, 4, 0, nil, nil},
{"EXTENT_SIZE", mysql.TypeLonglong, 4, 0, nil, nil},
{"INITIAL_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
{"MAXIMUM_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
{"AUTOEXTEND_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
{"CREATION_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
{"LAST_UPDATE_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
{"LAST_ACCESS_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
{"RECOVER_TIME", mysql.TypeLonglong, 4, 0, nil, nil},
{"TRANSACTION_COUNTER", mysql.TypeLonglong, 4, 0, nil, nil},
{"VERSION", mysql.TypeLonglong, 21, 0, nil, nil},
{"ROW_FORMAT", mysql.TypeVarchar, 21, 0, nil, nil},
{"TABLE_ROWS", mysql.TypeLonglong, 21, 0, nil, nil},
{"AVG_ROW_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
{"DATA_FREE", mysql.TypeLonglong, 21, 0, nil, nil},
{"CREATE_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
{"UPDATE_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
{"CHECK_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
{"CHECKSUM", mysql.TypeLonglong, 21, 0, nil, nil},
{"STATUS", mysql.TypeVarchar, 20, 0, nil, nil},
{"EXTRA", mysql.TypeVarchar, 255, 0, nil, nil},
}
func dataForSchemata(schemas []*model.DBInfo) [][]types.Datum {
var rows [][]types.Datum
for _, schema := range schemas {
record := types.MakeDatums(
catalogVal, // CATALOG_NAME
schema.Name.O, // SCHEMA_NAME
mysql.DefaultCharset, // DEFAULT_CHARACTER_SET_NAME
mysql.DefaultCollationName, // DEFAULT_COLLATION_NAME
nil,
)
rows = append(rows, record)
}
return rows
}
func getRowCountAllTable(ctx sessionctx.Context) (map[int64]uint64, error) {
rows, _, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, "select table_id, count from mysql.stats_meta")
if err != nil {
return nil, errors.Trace(err)
}
rowCountMap := make(map[int64]uint64, len(rows))
for _, row := range rows {
tableID := row.GetInt64(0)
rowCnt := row.GetUint64(1)
rowCountMap[tableID] = rowCnt
}
return rowCountMap, nil
}
func dataForTables(ctx sessionctx.Context, schemas []*model.DBInfo) ([][]types.Datum, error) {
tableRowsMap, err := getRowCountAllTable(ctx)
if err != nil {
return nil, errors.Trace(err)
}
var rows [][]types.Datum
createTimeTp := tablesCols[15].tp
for _, schema := range schemas {
for _, table := range schema.Tables {
collation := table.Collate
if collation == "" {
collation = charset.CollationUTF8
}
createTime := types.Time{
Time: types.FromGoTime(table.GetUpdateTime()),
Type: createTimeTp,
}
record := types.MakeDatums(
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
"BASE TABLE", // TABLE_TYPE
"InnoDB", // ENGINE
uint64(10), // VERSION
"Compact", // ROW_FORMAT
tableRowsMap[table.ID], // TABLE_ROWS
uint64(0), // AVG_ROW_LENGTH
uint64(16384), // DATA_LENGTH
uint64(0), // MAX_DATA_LENGTH
uint64(0), // INDEX_LENGTH
uint64(0), // DATA_FREE
table.AutoIncID, // AUTO_INCREMENT
createTime, // CREATE_TIME
nil, // UPDATE_TIME
nil, // CHECK_TIME
collation, // TABLE_COLLATION
nil, // CHECKSUM
"", // CREATE_OPTIONS
table.Comment, // TABLE_COMMENT
)
rows = append(rows, record)
}
}
return rows, nil
}
func dataForColumns(schemas []*model.DBInfo) [][]types.Datum {
var rows [][]types.Datum
for _, schema := range schemas {
for _, table := range schema.Tables {
rs := dataForColumnsInTable(schema, table)
rows = append(rows, rs...)
}
}
return rows
}
func dataForColumnsInTable(schema *model.DBInfo, tbl *model.TableInfo) [][]types.Datum {
var rows [][]types.Datum
for i, col := range tbl.Columns {
colLen, decimal := col.Flen, col.Decimal
defaultFlen, defaultDecimal := mysql.GetDefaultFieldLengthAndDecimal(col.Tp)
if colLen == types.UnspecifiedLength {
colLen = defaultFlen
}
if decimal == types.UnspecifiedLength {
decimal = defaultDecimal
}
columnType := col.FieldType.InfoSchemaStr()
columnDesc := table.NewColDesc(table.ToColumn(col))
var columnDefault interface{}
if columnDesc.DefaultValue != nil {
columnDefault = fmt.Sprintf("%v", columnDesc.DefaultValue)
}
record := types.MakeDatums(
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
tbl.Name.O, // TABLE_NAME
col.Name.O, // COLUMN_NAME
i+1, // ORIGINAL_POSITION
columnDefault, // COLUMN_DEFAULT
columnDesc.Null, // IS_NULLABLE
types.TypeToStr(col.Tp, col.Charset), // DATA_TYPE
colLen, // CHARACTER_MAXIMUM_LENGTH
colLen, // CHARACTER_OCTET_LENGTH
decimal, // NUMERIC_PRECISION
0, // NUMERIC_SCALE
0, // DATETIME_PRECISION
col.Charset, // CHARACTER_SET_NAME
col.Collate, // COLLATION_NAME
columnType, // COLUMN_TYPE
columnDesc.Key, // COLUMN_KEY
columnDesc.Extra, // EXTRA
"select,insert,update,references", // PRIVILEGES
columnDesc.Comment, // COLUMN_COMMENT
)
// In mysql, 'character_set_name' and 'collation_name' are setted to null when column type is non-varchar or non-blob in information_schema.
if col.Tp != mysql.TypeVarchar && col.Tp != mysql.TypeBlob {
record[13].SetNull()
record[14].SetNull()
}
rows = append(rows, record)
}
return rows
}
func dataForStatistics(schemas []*model.DBInfo) [][]types.Datum {
var rows [][]types.Datum
for _, schema := range schemas {
for _, table := range schema.Tables {
rs := dataForStatisticsInTable(schema, table)
rows = append(rows, rs...)
}
}
return rows
}
func dataForStatisticsInTable(schema *model.DBInfo, table *model.TableInfo) [][]types.Datum {
var rows [][]types.Datum
if table.PKIsHandle {
for _, col := range table.Columns {
if mysql.HasPriKeyFlag(col.Flag) {
record := types.MakeDatums(
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
"0", // NON_UNIQUE
schema.Name.O, // INDEX_SCHEMA
"PRIMARY", // INDEX_NAME
1, // SEQ_IN_INDEX
col.Name.O, // COLUMN_NAME
"A", // COLLATION
0, // CARDINALITY
nil, // SUB_PART
nil, // PACKED
"", // NULLABLE
"BTREE", // INDEX_TYPE
"", // COMMENT
"", // INDEX_COMMENT
)
rows = append(rows, record)
}
}
}
nameToCol := make(map[string]*model.ColumnInfo, len(table.Columns))
for _, c := range table.Columns {
nameToCol[c.Name.L] = c
}
for _, index := range table.Indices {
nonUnique := "1"
if index.Unique {
nonUnique = "0"
}
for i, key := range index.Columns {
col := nameToCol[key.Name.L]
nullable := "YES"
if mysql.HasNotNullFlag(col.Flag) {
nullable = ""
}
record := types.MakeDatums(
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
nonUnique, // NON_UNIQUE
schema.Name.O, // INDEX_SCHEMA
index.Name.O, // INDEX_NAME
i+1, // SEQ_IN_INDEX
key.Name.O, // COLUMN_NAME
"A", // COLLATION
0, // CARDINALITY
nil, // SUB_PART
nil, // PACKED
nullable, // NULLABLE
"BTREE", // INDEX_TYPE
"", // COMMENT
"", // INDEX_COMMENT
)
rows = append(rows, record)
}
}
return rows
}
const (
primaryKeyType = "PRIMARY KEY"
primaryConstraint = "PRIMARY"
uniqueKeyType = "UNIQUE"
)
// dataForTableConstraints constructs data for table information_schema.constraints.See https://dev.mysql.com/doc/refman/5.7/en/table-constraints-table.html
func dataForTableConstraints(schemas []*model.DBInfo) [][]types.Datum {
var rows [][]types.Datum
for _, schema := range schemas {
for _, tbl := range schema.Tables {
if tbl.PKIsHandle {
record := types.MakeDatums(
catalogVal, // CONSTRAINT_CATALOG
schema.Name.O, // CONSTRAINT_SCHEMA
mysql.PrimaryKeyName, // CONSTRAINT_NAME
schema.Name.O, // TABLE_SCHEMA
tbl.Name.O, // TABLE_NAME
primaryKeyType, // CONSTRAINT_TYPE
)
rows = append(rows, record)
}
for _, idx := range tbl.Indices {
var cname, ctype string
if idx.Primary {
cname = mysql.PrimaryKeyName
ctype = primaryKeyType
} else if idx.Unique {
cname = idx.Name.O
ctype = uniqueKeyType
} else {
// The index has no constriant.
continue
}
record := types.MakeDatums(
catalogVal, // CONSTRAINT_CATALOG
schema.Name.O, // CONSTRAINT_SCHEMA
cname, // CONSTRAINT_NAME
schema.Name.O, // TABLE_SCHEMA
tbl.Name.O, // TABLE_NAME
ctype, // CONSTRAINT_TYPE
)
rows = append(rows, record)
}
}
}
return rows
}
// dataForPseudoProfiling returns pseudo data for table profiling when system variable `profiling` is set to `ON`.
func dataForPseudoProfiling() [][]types.Datum {
var rows [][]types.Datum
row := types.MakeDatums(
0, // QUERY_ID
0, // SEQ
"", // STATE
types.NewDecFromInt(0), // DURATION
types.NewDecFromInt(0), // CPU_USER
types.NewDecFromInt(0), // CPU_SYSTEM
0, // CONTEXT_VOLUNTARY
0, // CONTEXT_INVOLUNTARY
0, // BLOCK_OPS_IN
0, // BLOCK_OPS_OUT
0, // MESSAGES_SENT
0, // MESSAGES_RECEIVED
0, // PAGE_FAULTS_MAJOR
0, // PAGE_FAULTS_MINOR
0, // SWAPS
0, // SOURCE_FUNCTION
0, // SOURCE_FILE
0, // SOURCE_LINE
)
rows = append(rows, row)
return rows
}
func dataForKeyColumnUsage(schemas []*model.DBInfo) [][]types.Datum {
rows := make([][]types.Datum, 0, len(schemas)) // The capacity is not accurate, but it is not a big problem.
for _, schema := range schemas {
for _, table := range schema.Tables {
rs := keyColumnUsageInTable(schema, table)
rows = append(rows, rs...)
}
}
return rows
}
func keyColumnUsageInTable(schema *model.DBInfo, table *model.TableInfo) [][]types.Datum {
var rows [][]types.Datum
if table.PKIsHandle {
for _, col := range table.Columns {
if mysql.HasPriKeyFlag(col.Flag) {
record := types.MakeDatums(
catalogVal, // CONSTRAINT_CATALOG
schema.Name.O, // CONSTRAINT_SCHEMA
primaryConstraint, // CONSTRAINT_NAME
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
col.Name.O, // COLUMN_NAME
1, // ORDINAL_POSITION
1, // POSITION_IN_UNIQUE_CONSTRAINT
nil, // REFERENCED_TABLE_SCHEMA
nil, // REFERENCED_TABLE_NAME
nil, // REFERENCED_COLUMN_NAME
)
rows = append(rows, record)
break
}
}
}
nameToCol := make(map[string]*model.ColumnInfo, len(table.Columns))
for _, c := range table.Columns {
nameToCol[c.Name.L] = c
}
for _, index := range table.Indices {
var idxName string
if index.Primary {
idxName = primaryConstraint
} else if index.Unique {
idxName = index.Name.O
} else {
// Only handle unique/primary key
continue
}
for i, key := range index.Columns {
col := nameToCol[key.Name.L]
record := types.MakeDatums(
catalogVal, // CONSTRAINT_CATALOG
schema.Name.O, // CONSTRAINT_SCHEMA
idxName, // CONSTRAINT_NAME
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
col.Name.O, // COLUMN_NAME
i+1, // ORDINAL_POSITION,
nil, // POSITION_IN_UNIQUE_CONSTRAINT
nil, // REFERENCED_TABLE_SCHEMA
nil, // REFERENCED_TABLE_NAME
nil, // REFERENCED_COLUMN_NAME
)
rows = append(rows, record)
}
}
for _, fk := range table.ForeignKeys {
fkRefCol := ""
if len(fk.RefCols) > 0 {
fkRefCol = fk.RefCols[0].O
}
for i, key := range fk.Cols {
col := nameToCol[key.L]
record := types.MakeDatums(
catalogVal, // CONSTRAINT_CATALOG
schema.Name.O, // CONSTRAINT_SCHEMA
fk.Name.O, // CONSTRAINT_NAME
catalogVal, // TABLE_CATALOG
schema.Name.O, // TABLE_SCHEMA
table.Name.O, // TABLE_NAME
col.Name.O, // COLUMN_NAME
i+1, // ORDINAL_POSITION,
1, // POSITION_IN_UNIQUE_CONSTRAINT
schema.Name.O, // REFERENCED_TABLE_SCHEMA
fk.RefTable.O, // REFERENCED_TABLE_NAME
fkRefCol, // REFERENCED_COLUMN_NAME
)
rows = append(rows, record)
}
}
return rows
}
var tableNameToColumns = map[string][]columnInfo{
tableSchemata: schemataCols,
tableTables: tablesCols,
tableColumns: columnsCols,
tableStatistics: statisticsCols,
tableCharacterSets: charsetCols,
tableCollations: collationsCols,
tableFiles: filesCols,
tableProfiling: profilingCols,
tablePartitions: partitionsCols,
tableKeyColumm: keyColumnUsageCols,
tableReferConst: referConstCols,
tableSessionVar: sessionVarCols,
tablePlugins: pluginsCols,
tableConstraints: tableConstraintsCols,
tableTriggers: tableTriggersCols,
tableUserPrivileges: tableUserPrivilegesCols,
tableSchemaPrivileges: tableSchemaPrivilegesCols,
tableTablePrivileges: tableTablePrivilegesCols,
tableColumnPrivileges: tableColumnPrivilegesCols,
tableEngines: tableEnginesCols,
tableViews: tableViewsCols,
tableRoutines: tableRoutinesCols,
tableParameters: tableParametersCols,
tableEvents: tableEventsCols,
tableGlobalStatus: tableGlobalStatusCols,
tableGlobalVariables: tableGlobalVariablesCols,
tableSessionStatus: tableSessionStatusCols,
tableOptimizerTrace: tableOptimizerTraceCols,
tableTableSpaces: tableTableSpacesCols,
tableCollationCharacterSetApplicability: tableCollationCharacterSetApplicabilityCols,
}
func createInfoSchemaTable(handle *Handle, meta *model.TableInfo) *infoschemaTable {
columns := make([]*table.Column, len(meta.Columns))
for i, col := range meta.Columns {
columns[i] = table.ToColumn(col)
}
return &infoschemaTable{
handle: handle,
meta: meta,
cols: columns,
}
}
type infoschemaTable struct {
handle *Handle
meta *model.TableInfo
cols []*table.Column
rows [][]types.Datum
}
// schemasSorter implements the sort.Interface interface, sorts DBInfo by name.
type schemasSorter []*model.DBInfo
func (s schemasSorter) Len() int {
return len(s)
}
func (s schemasSorter) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s schemasSorter) Less(i, j int) bool {
return s[i].Name.L < s[j].Name.L
}
func (it *infoschemaTable) getRows(ctx sessionctx.Context, cols []*table.Column) (fullRows [][]types.Datum, err error) {
is := it.handle.Get()
dbs := is.AllSchemas()
sort.Sort(schemasSorter(dbs))
switch it.meta.Name.O {
case tableSchemata:
fullRows = dataForSchemata(dbs)
case tableTables:
fullRows, err = dataForTables(ctx, dbs)
case tableColumns:
fullRows = dataForColumns(dbs)
case tableStatistics:
fullRows = dataForStatistics(dbs)
case tableCharacterSets:
fullRows = dataForCharacterSets()
case tableCollations:
fullRows = dataForColltions()
case tableSessionVar:
fullRows, err = dataForSessionVar(ctx)
case tableConstraints:
fullRows = dataForTableConstraints(dbs)
case tableFiles:
case tableProfiling:
if v, ok := ctx.GetSessionVars().GetSystemVar("profiling"); ok && variable.TiDBOptOn(v) {
fullRows = dataForPseudoProfiling()
}
case tablePartitions:
case tableKeyColumm:
fullRows = dataForKeyColumnUsage(dbs)
case tableReferConst:
case tablePlugins, tableTriggers:
case tableUserPrivileges:
fullRows = dataForUserPrivileges(ctx)
case tableEngines:
fullRows = dataForEngines()
case tableViews:
case tableRoutines:
// TODO: Fill the following tables.
case tableSchemaPrivileges:
case tableTablePrivileges:
case tableColumnPrivileges:
case tableParameters:
case tableEvents:
case tableGlobalStatus:
case tableGlobalVariables:
case tableSessionStatus:
case tableOptimizerTrace:
case tableTableSpaces:
case tableCollationCharacterSetApplicability:
fullRows = dataForCollationCharacterSetApplicability()
}
if err != nil {
return nil, errors.Trace(err)
}
if len(cols) == len(it.cols) {
return
}
rows := make([][]types.Datum, len(fullRows))
for i, fullRow := range fullRows {
row := make([]types.Datum, len(cols))
for j, col := range cols {
row[j] = fullRow[col.Offset]
}
rows[i] = row
}
return rows, nil
}
func (it *infoschemaTable) IterRecords(ctx sessionctx.Context, startKey kv.Key, cols []*table.Column,
fn table.RecordIterFunc) error {
if len(startKey) != 0 {
return table.ErrUnsupportedOp
}
rows, err := it.getRows(ctx, cols)
if err != nil {
return errors.Trace(err)
}
for i, row := range rows {
more, err := fn(int64(i), row, cols)
if err != nil {
return errors.Trace(err)
}
if !more {
break
}
}
return nil
}
func (it *infoschemaTable) RowWithCols(ctx sessionctx.Context, h int64, cols []*table.Column) ([]types.Datum, error) {
return nil, table.ErrUnsupportedOp
}
// Row implements table.Table Row interface.
func (it *infoschemaTable) Row(ctx sessionctx.Context, h int64) ([]types.Datum, error) {
return nil, table.ErrUnsupportedOp
}
func (it *infoschemaTable) Cols() []*table.Column {
return it.cols
}
func (it *infoschemaTable) WritableCols() []*table.Column {
return it.cols
}
func (it *infoschemaTable) Indices() []table.Index {
return nil
}
func (it *infoschemaTable) WritableIndices() []table.Index {
return nil
}
func (it *infoschemaTable) DeletableIndices() []table.Index {
return nil
}
func (it *infoschemaTable) RecordPrefix() kv.Key {
return nil
}
func (it *infoschemaTable) IndexPrefix() kv.Key {
return nil
}
func (it *infoschemaTable) FirstKey() kv.Key {
return nil
}
func (it *infoschemaTable) RecordKey(h int64) kv.Key {
return nil
}
func (it *infoschemaTable) AddRecord(ctx sessionctx.Context, r []types.Datum, skipHandleCheck bool) (recordID int64, err error) {
return 0, table.ErrUnsupportedOp
}
func (it *infoschemaTable) RemoveRecord(ctx sessionctx.Context, h int64, r []types.Datum) error {
return table.ErrUnsupportedOp
}
func (it *infoschemaTable) UpdateRecord(ctx sessionctx.Context, h int64, oldData, newData []types.Datum, touched []bool) error {
return table.ErrUnsupportedOp
}
func (it *infoschemaTable) AllocAutoID(ctx sessionctx.Context) (int64, error) {
return 0, table.ErrUnsupportedOp
}
func (it *infoschemaTable) Allocator(ctx sessionctx.Context) autoid.Allocator {
return nil
}
func (it *infoschemaTable) RebaseAutoID(ctx sessionctx.Context, newBase int64, isSetStep bool) error {
return table.ErrUnsupportedOp
}
func (it *infoschemaTable) Meta() *model.TableInfo {
return it.meta
}
// Seek is the first method called for table scan, we lazy initialize it here.
func (it *infoschemaTable) Seek(ctx sessionctx.Context, h int64) (int64, bool, error) {
return 0, false, table.ErrUnsupportedOp
}
func (it *infoschemaTable) Type() table.Type {
return table.VirtualTable
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zhoujin826/tidb.git
git@gitee.com:zhoujin826/tidb.git
zhoujin826
tidb
tidb
v2.0.3

搜索帮助

0d507c66 1850385 C8b1a773 1850385