github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/infoschema/tables.go (about)

     1  // Copyright 2016 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package infoschema
    15  
    16  import (
    17  	"fmt"
    18  	"sort"
    19  
    20  	"github.com/insionng/yougam/libraries/pingcap/tidb/column"
    21  	"github.com/insionng/yougam/libraries/pingcap/tidb/meta/autoid"
    22  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    23  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    24  	"github.com/insionng/yougam/libraries/pingcap/tidb/table"
    25  	"github.com/insionng/yougam/libraries/pingcap/tidb/table/tables"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/charset"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/util/types"
    28  )
    29  
    30  const (
    31  	tableSchemata      = "SCHEMATA"
    32  	tableTables        = "TABLES"
    33  	tableColumns       = "COLUMNS"
    34  	tableStatistics    = "STATISTICS"
    35  	tableCharacterSets = "CHARACTER_SETS"
    36  	tableCollations    = "COLLATIONS"
    37  	tableFiles         = "FILES"
    38  	catalogVal         = "def"
    39  	tableProfiling     = "PROFILING"
    40  	tablePartitions    = "PARTITIONS"
    41  )
    42  
    43  type columnInfo struct {
    44  	name  string
    45  	tp    byte
    46  	size  int
    47  	flag  uint
    48  	deflt interface{}
    49  	elems []string
    50  }
    51  
    52  func buildColumnInfo(tableName string, col columnInfo) *model.ColumnInfo {
    53  	mCharset := charset.CharsetBin
    54  	mCollation := charset.CharsetBin
    55  	mFlag := mysql.UnsignedFlag
    56  	if col.tp == mysql.TypeVarchar || col.tp == mysql.TypeBlob {
    57  		mCharset = mysql.DefaultCharset
    58  		mCollation = mysql.DefaultCollationName
    59  		mFlag = 0
    60  	}
    61  	fieldType := types.FieldType{
    62  		Charset: mCharset,
    63  		Collate: mCollation,
    64  		Tp:      col.tp,
    65  		Flen:    col.size,
    66  		Flag:    uint(mFlag),
    67  	}
    68  	return &model.ColumnInfo{
    69  		Name:      model.NewCIStr(col.name),
    70  		FieldType: fieldType,
    71  		State:     model.StatePublic,
    72  	}
    73  }
    74  
    75  func buildTableMeta(tableName string, cs []columnInfo) *model.TableInfo {
    76  	cols := make([]*model.ColumnInfo, 0, len(cs))
    77  	for _, c := range cs {
    78  		cols = append(cols, buildColumnInfo(tableName, c))
    79  	}
    80  	for i, col := range cols {
    81  		col.Offset = i
    82  	}
    83  	return &model.TableInfo{
    84  		Name:    model.NewCIStr(tableName),
    85  		Columns: cols,
    86  		State:   model.StatePublic,
    87  	}
    88  }
    89  
    90  var schemataCols = []columnInfo{
    91  	{"CATALOG_NAME", mysql.TypeVarchar, 512, 0, nil, nil},
    92  	{"SCHEMA_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
    93  	{"DEFAULT_CHARACTER_SET_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
    94  	{"DEFAULT_COLLATION_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
    95  	{"SQL_PATH", mysql.TypeVarchar, 512, 0, nil, nil},
    96  }
    97  
    98  var tablesCols = []columnInfo{
    99  	{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
   100  	{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
   101  	{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   102  	{"TABLE_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
   103  	{"ENGINE", mysql.TypeVarchar, 64, 0, nil, nil},
   104  	{"VERSION", mysql.TypeLonglong, 21, 0, nil, nil},
   105  	{"ROW_FORMAT", mysql.TypeVarchar, 10, 0, nil, nil},
   106  	{"TABLE_ROWS", mysql.TypeLonglong, 21, 0, nil, nil},
   107  	{"AVG_ROW_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   108  	{"DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   109  	{"MAX_DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   110  	{"INDEX_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   111  	{"DATA_FREE", mysql.TypeLonglong, 21, 0, nil, nil},
   112  	{"AUTO_INCREMENT", mysql.TypeLonglong, 21, 0, nil, nil},
   113  	{"CREATE_TIME", mysql.TypeDatetime, 19, 0, nil, nil},
   114  	{"UPDATE_TIME", mysql.TypeDatetime, 19, 0, nil, nil},
   115  	{"CHECK_TIME", mysql.TypeDatetime, 19, 0, nil, nil},
   116  	{"TABLE_COLLATION", mysql.TypeVarchar, 32, 0, nil, nil},
   117  	{"CHECK_SUM", mysql.TypeLonglong, 21, 0, nil, nil},
   118  	{"CREATE_OPTIONS", mysql.TypeVarchar, 255, 0, nil, nil},
   119  	{"TABLE_COMMENT", mysql.TypeVarchar, 2048, 0, nil, nil},
   120  }
   121  
   122  var columnsCols = []columnInfo{
   123  	{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
   124  	{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
   125  	{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   126  	{"COLUMN_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   127  	{"ORIGINAL_POSITION", mysql.TypeLonglong, 64, 0, nil, nil},
   128  	{"COLUMN_DEFAULT", mysql.TypeBlob, 196606, 0, nil, nil},
   129  	{"IS_NULLABLE", mysql.TypeVarchar, 3, 0, nil, nil},
   130  	{"DATA_TYPE", mysql.TypeVarchar, 64, 0, nil, nil},
   131  	{"CHARACTER_MAXIMUM_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   132  	{"CHARACTOR_OCTET_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   133  	{"NUMERIC_PRECISION", mysql.TypeLonglong, 21, 0, nil, nil},
   134  	{"NUMERIC_SCALE", mysql.TypeLonglong, 21, 0, nil, nil},
   135  	{"DATETIME_PRECISION", mysql.TypeLonglong, 21, 0, nil, nil},
   136  	{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
   137  	{"COLLATION_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
   138  	{"COLUMN_TYPE", mysql.TypeBlob, 196606, 0, nil, nil},
   139  	{"COLUMN_KEY", mysql.TypeVarchar, 3, 0, nil, nil},
   140  	{"EXTRA", mysql.TypeVarchar, 30, 0, nil, nil},
   141  	{"PRIVILEGES", mysql.TypeVarchar, 80, 0, nil, nil},
   142  	{"COLUMN_COMMENT", mysql.TypeVarchar, 1024, 0, nil, nil},
   143  }
   144  
   145  var statisticsCols = []columnInfo{
   146  	{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
   147  	{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
   148  	{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   149  	{"NON_UNIQUE", mysql.TypeVarchar, 1, 0, nil, nil},
   150  	{"INDEX_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
   151  	{"INDEX_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   152  	{"SEQ_IN_INDEX", mysql.TypeLonglong, 2, 0, nil, nil},
   153  	{"COLUMN_NAME", mysql.TypeVarchar, 21, 0, nil, nil},
   154  	{"COLLATION", mysql.TypeVarchar, 1, 0, nil, nil},
   155  	{"CARDINALITY", mysql.TypeLonglong, 21, 0, nil, nil},
   156  	{"SUB_PART", mysql.TypeLonglong, 3, 0, nil, nil},
   157  	{"PACKED", mysql.TypeVarchar, 10, 0, nil, nil},
   158  	{"NULLABLE", mysql.TypeVarchar, 3, 0, nil, nil},
   159  	{"INDEX_TYPE", mysql.TypeVarchar, 16, 0, nil, nil},
   160  	{"COMMENT", mysql.TypeVarchar, 16, 0, nil, nil},
   161  	{"INDEX_COMMENT", mysql.TypeVarchar, 1024, 0, nil, nil},
   162  }
   163  
   164  var profilingCols = []columnInfo{
   165  	{"QUERY_ID", mysql.TypeLong, 20, 0, nil, nil},
   166  	{"SEQ", mysql.TypeLong, 20, 0, nil, nil},
   167  	{"STATE", mysql.TypeVarchar, 30, 0, nil, nil},
   168  	{"DURATION", mysql.TypeNewDecimal, 9, 0, nil, nil},
   169  	{"CPU_USER", mysql.TypeNewDecimal, 9, 0, nil, nil},
   170  	{"CPU_SYSTEM", mysql.TypeNewDecimal, 9, 0, nil, nil},
   171  	{"CONTEXT_VOLUNTARY", mysql.TypeLong, 20, 0, nil, nil},
   172  	{"CONTEXT_INVOLUNTARY", mysql.TypeLong, 20, 0, nil, nil},
   173  	{"BLOCK_OPS_IN", mysql.TypeLong, 20, 0, nil, nil},
   174  	{"BLOCK_OPS_OUT", mysql.TypeLong, 20, 0, nil, nil},
   175  	{"MESSAGES_SENT", mysql.TypeLong, 20, 0, nil, nil},
   176  	{"MESSAGES_RECEIVED", mysql.TypeLong, 20, 0, nil, nil},
   177  	{"PAGE_FAULTS_MAJOR", mysql.TypeLong, 20, 0, nil, nil},
   178  	{"PAGE_FAULTS_MINOR", mysql.TypeLong, 20, 0, nil, nil},
   179  	{"SWAPS", mysql.TypeLong, 20, 0, nil, nil},
   180  	{"SOURCE_FUNCTION", mysql.TypeVarchar, 30, 0, nil, nil},
   181  	{"SOURCE_FILE", mysql.TypeVarchar, 20, 0, nil, nil},
   182  	{"SOURCE_LINE", mysql.TypeLong, 20, 0, nil, nil},
   183  }
   184  
   185  var charsetCols = []columnInfo{
   186  	{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
   187  	{"DEFAULT_COLLATE_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
   188  	{"DESCRIPTION", mysql.TypeVarchar, 60, 0, nil, nil},
   189  	{"MAXLEN", mysql.TypeLonglong, 3, 0, nil, nil},
   190  }
   191  
   192  var collationsCols = []columnInfo{
   193  	{"COLLATION_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
   194  	{"CHARACTER_SET_NAME", mysql.TypeVarchar, 32, 0, nil, nil},
   195  	{"ID", mysql.TypeLonglong, 11, 0, nil, nil},
   196  	{"IS_DEFAULT", mysql.TypeVarchar, 3, 0, nil, nil},
   197  	{"IS_COMPILED", mysql.TypeVarchar, 3, 0, nil, nil},
   198  	{"SORTLEN", mysql.TypeLonglong, 3, 0, nil, nil},
   199  }
   200  
   201  // See: https://dev.mysql.com/doc/refman/5.7/en/partitions-table.html
   202  var partitionsCols = []columnInfo{
   203  	{"TABLE_CATALOG", mysql.TypeVarchar, 512, 0, nil, nil},
   204  	{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
   205  	{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   206  	{"PARTITION_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   207  	{"SUBPARTITION_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   208  	{"PARTITION_ORDINAL_POSITION", mysql.TypeLonglong, 21, 0, nil, nil},
   209  	{"SUBPARTITION_ORDINAL_POSITION", mysql.TypeLonglong, 21, 0, nil, nil},
   210  	{"PARTITION_METHOD", mysql.TypeVarchar, 18, 0, nil, nil},
   211  	{"SUBPARTITION_METHOD", mysql.TypeVarchar, 12, 0, nil, nil},
   212  	{"PARTITION_EXPRESSION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
   213  	{"SUBPARTITION_EXPRESSION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
   214  	{"PARTITION_DESCRIPTION", mysql.TypeLongBlob, types.UnspecifiedLength, 0, nil, nil},
   215  	{"TABLE_ROWS", mysql.TypeLonglong, 21, 0, nil, nil},
   216  	{"AVG_ROW_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   217  	{"DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   218  	{"MAX_DATA_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   219  	{"INDEX_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   220  	{"DATA_FREE", mysql.TypeLonglong, 21, 0, nil, nil},
   221  	{"CREATE_TIME", mysql.TypeDatetime, 0, 0, nil, nil},
   222  	{"UPDATE_TIME", mysql.TypeDatetime, 0, 0, nil, nil},
   223  	{"CHECK_TIME", mysql.TypeDatetime, 0, 0, nil, nil},
   224  	{"CHECKSUM", mysql.TypeLonglong, 21, 0, nil, nil},
   225  	{"PARTITION_COMMENT", mysql.TypeVarchar, 80, 0, nil, nil},
   226  	{"NODEGROUP", mysql.TypeVarchar, 12, 0, nil, nil},
   227  	{"TABLESPACE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   228  }
   229  
   230  func dataForCharacterSets() (records [][]types.Datum) {
   231  	records = append(records,
   232  		types.MakeDatums("ascii", "ascii_general_ci", "US ASCII", 1),
   233  		types.MakeDatums("binary", "binary", "Binary pseudo charset", 1),
   234  		types.MakeDatums("latin1", "latin1_swedish_ci", "cp1252 West European", 1),
   235  		types.MakeDatums("utf8", "utf8_general_ci", "UTF-8 Unicode", 3),
   236  		types.MakeDatums("utf8mb4", "utf8mb4_general_ci", "UTF-8 Unicode", 4),
   237  	)
   238  	return records
   239  }
   240  
   241  func dataForColltions() (records [][]types.Datum) {
   242  	records = append(records,
   243  		types.MakeDatums("ascii_general_ci", "ascii", 1, "Yes", "Yes", 1),
   244  		types.MakeDatums("binary", "binary", 2, "Yes", "Yes", 1),
   245  		types.MakeDatums("latin1_swedish_ci", "latin1", 3, "Yes", "Yes", 1),
   246  		types.MakeDatums("utf8_general_ci", "utf8", 4, "Yes", "Yes", 1),
   247  		types.MakeDatums("utf8mb4_general_ci", "utf8mb4", 5, "Yes", "Yes", 1),
   248  	)
   249  	return records
   250  }
   251  
   252  var filesCols = []columnInfo{
   253  	{"FILE_ID", mysql.TypeLonglong, 4, 0, nil, nil},
   254  	{"FILE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   255  	{"FILE_TYPE", mysql.TypeVarchar, 20, 0, nil, nil},
   256  	{"TABLESPACE_NAME", mysql.TypeVarchar, 20, 0, nil, nil},
   257  	{"TABLE_CATALOG", mysql.TypeVarchar, 64, 0, nil, nil},
   258  	{"TABLE_SCHEMA", mysql.TypeVarchar, 64, 0, nil, nil},
   259  	{"TABLE_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   260  	{"LOGFILE_GROUP_NAME", mysql.TypeVarchar, 64, 0, nil, nil},
   261  	{"LOGFILE_GROUP_NUMBER", mysql.TypeLonglong, 32, 0, nil, nil},
   262  	{"ENGINE", mysql.TypeVarchar, 64, 0, nil, nil},
   263  	{"FULLTEXT_KEYS", mysql.TypeVarchar, 64, 0, nil, nil},
   264  	{"DELETED_ROWS", mysql.TypeLonglong, 4, 0, nil, nil},
   265  	{"UPDATE_COUNT", mysql.TypeLonglong, 4, 0, nil, nil},
   266  	{"FREE_EXTENTS", mysql.TypeLonglong, 4, 0, nil, nil},
   267  	{"TOTAL_EXTENTS", mysql.TypeLonglong, 4, 0, nil, nil},
   268  	{"EXTENT_SIZE", mysql.TypeLonglong, 4, 0, nil, nil},
   269  	{"INITIAL_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
   270  	{"MAXIMUM_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
   271  	{"AUTOEXTEND_SIZE", mysql.TypeLonglong, 21, 0, nil, nil},
   272  	{"CREATION_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
   273  	{"LAST_UPDATE_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
   274  	{"LAST_ACCESS_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
   275  	{"RECOVER_TIME", mysql.TypeLonglong, 4, 0, nil, nil},
   276  	{"TRANSACTION_COUNTER", mysql.TypeLonglong, 4, 0, nil, nil},
   277  	{"VERSION", mysql.TypeLonglong, 21, 0, nil, nil},
   278  	{"ROW_FORMAT", mysql.TypeVarchar, 21, 0, nil, nil},
   279  	{"TABLE_ROWS", mysql.TypeLonglong, 21, 0, nil, nil},
   280  	{"AVG_ROW_LENGTH", mysql.TypeLonglong, 21, 0, nil, nil},
   281  	{"DATA_FREE", mysql.TypeLonglong, 21, 0, nil, nil},
   282  	{"CREATE_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
   283  	{"UPDATE_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
   284  	{"CHECK_TIME", mysql.TypeDatetime, -1, 0, nil, nil},
   285  	{"CHECKSUM", mysql.TypeLonglong, 21, 0, nil, nil},
   286  	{"STATUS", mysql.TypeVarchar, 20, 0, nil, nil},
   287  	{"EXTRA", mysql.TypeVarchar, 255, 0, nil, nil},
   288  }
   289  
   290  func dataForSchemata(schemas []string) [][]types.Datum {
   291  	sort.Strings(schemas)
   292  	rows := [][]types.Datum{}
   293  	for _, schema := range schemas {
   294  		record := types.MakeDatums(
   295  			catalogVal,                 // CATALOG_NAME
   296  			schema,                     // SCHEMA_NAME
   297  			mysql.DefaultCharset,       // DEFAULT_CHARACTER_SET_NAME
   298  			mysql.DefaultCollationName, // DEFAULT_COLLATION_NAME
   299  			nil,
   300  		)
   301  		rows = append(rows, record)
   302  	}
   303  	return rows
   304  }
   305  
   306  func dataForTables(schemas []*model.DBInfo) [][]types.Datum {
   307  	rows := [][]types.Datum{}
   308  	for _, schema := range schemas {
   309  		for _, table := range schema.Tables {
   310  			record := types.MakeDatums(
   311  				catalogVal,          // TABLE_CATALOG
   312  				schema.Name.O,       // TABLE_SCHEMA
   313  				table.Name.O,        // TABLE_NAME
   314  				"BASE_TABLE",        // TABLE_TYPE
   315  				"InnoDB",            // ENGINE
   316  				uint64(10),          // VERSION
   317  				"Compact",           // ROW_FORMAT
   318  				uint64(0),           // TABLE_ROWS
   319  				uint64(0),           // AVG_ROW_LENGTH
   320  				uint64(16384),       // DATA_LENGTH
   321  				uint64(0),           // MAX_DATA_LENGTH
   322  				uint64(0),           // INDEX_LENGTH
   323  				uint64(0),           // DATA_FREE
   324  				nil,                 // AUTO_INCREMENT
   325  				nil,                 // CREATE_TIME
   326  				nil,                 // UPDATE_TIME
   327  				nil,                 // CHECK_TIME
   328  				"latin1_swedish_ci", // TABLE_COLLATION
   329  				nil,                 // CHECKSUM
   330  				"",                  // CREATE_OPTIONS
   331  				"",                  // TABLE_COMMENT
   332  			)
   333  			rows = append(rows, record)
   334  		}
   335  	}
   336  	return rows
   337  }
   338  
   339  func dataForColumns(schemas []*model.DBInfo) [][]types.Datum {
   340  	rows := [][]types.Datum{}
   341  	for _, schema := range schemas {
   342  		for _, table := range schema.Tables {
   343  			rs := dataForColumnsInTable(schema, table)
   344  			for _, r := range rs {
   345  				rows = append(rows, r)
   346  			}
   347  		}
   348  	}
   349  	return rows
   350  }
   351  
   352  func dataForColumnsInTable(schema *model.DBInfo, table *model.TableInfo) [][]types.Datum {
   353  	rows := [][]types.Datum{}
   354  	for i, col := range table.Columns {
   355  		colLen := col.Flen
   356  		if colLen == types.UnspecifiedLength {
   357  			colLen = mysql.GetDefaultFieldLength(col.Tp)
   358  		}
   359  		decimal := col.Decimal
   360  		if decimal == types.UnspecifiedLength {
   361  			decimal = 0
   362  		}
   363  		columnType := col.FieldType.CompactStr()
   364  		columnDesc := column.NewColDesc(&column.Col{ColumnInfo: *col})
   365  		var columnDefault interface{}
   366  		if columnDesc.DefaultValue != nil {
   367  			columnDefault = fmt.Sprintf("%v", columnDesc.DefaultValue)
   368  		}
   369  		record := types.MakeDatums(
   370  			catalogVal,                           // TABLE_CATALOG
   371  			schema.Name.O,                        // TABLE_SCHEMA
   372  			table.Name.O,                         // TABLE_NAME
   373  			col.Name.O,                           // COLUMN_NAME
   374  			i+1,                                  // ORIGINAL_POSITION
   375  			columnDefault,                        // COLUMN_DEFAULT
   376  			columnDesc.Null,                      // IS_NULLABLE
   377  			types.TypeToStr(col.Tp, col.Charset), // DATA_TYPE
   378  			colLen,                            // CHARACTER_MAXIMUM_LENGTH
   379  			colLen,                            // CHARACTOR_OCTET_LENGTH
   380  			decimal,                           // NUMERIC_PRECISION
   381  			0,                                 // NUMERIC_SCALE
   382  			0,                                 // DATETIME_PRECISION
   383  			col.Charset,                       // CHARACTER_SET_NAME
   384  			col.Collate,                       // COLLATION_NAME
   385  			columnType,                        // COLUMN_TYPE
   386  			columnDesc.Key,                    // COLUMN_KEY
   387  			columnDesc.Extra,                  // EXTRA
   388  			"select,insert,update,references", // PRIVILEGES
   389  			"", // COLUMN_COMMENT
   390  		)
   391  		rows = append(rows, record)
   392  	}
   393  	return rows
   394  }
   395  
   396  func dataForStatistics(schemas []*model.DBInfo) [][]types.Datum {
   397  	rows := [][]types.Datum{}
   398  	for _, schema := range schemas {
   399  		for _, table := range schema.Tables {
   400  			rs := dataForStatisticsInTable(schema, table)
   401  			for _, r := range rs {
   402  				rows = append(rows, r)
   403  			}
   404  		}
   405  	}
   406  	return rows
   407  }
   408  
   409  func dataForStatisticsInTable(schema *model.DBInfo, table *model.TableInfo) [][]types.Datum {
   410  	rows := [][]types.Datum{}
   411  	if table.PKIsHandle {
   412  		for _, col := range table.Columns {
   413  			if mysql.HasPriKeyFlag(col.Flag) {
   414  				record := types.MakeDatums(
   415  					catalogVal,    // TABLE_CATALOG
   416  					schema.Name.O, // TABLE_SCHEMA
   417  					table.Name.O,  // TABLE_NAME
   418  					"0",           // NON_UNIQUE
   419  					schema.Name.O, // INDEX_SCHEMA
   420  					"PRIMARY",     // INDEX_NAME
   421  					1,             // SEQ_IN_INDEX
   422  					col.Name.O,    // COLUMN_NAME
   423  					"A",           // COLLATION
   424  					0,             // CARDINALITY
   425  					nil,           // SUB_PART
   426  					nil,           // PACKED
   427  					"",            // NULLABLE
   428  					"BTREE",       // INDEX_TYPE
   429  					"",            // COMMENT
   430  					"",            // INDEX_COMMENT
   431  				)
   432  				rows = append(rows, record)
   433  			}
   434  		}
   435  	}
   436  	nameToCol := make(map[string]*model.ColumnInfo, len(table.Columns))
   437  	for _, c := range table.Columns {
   438  		nameToCol[c.Name.L] = c
   439  	}
   440  	for _, index := range table.Indices {
   441  		nonUnique := "1"
   442  		if index.Unique {
   443  			nonUnique = "0"
   444  		}
   445  		for i, key := range index.Columns {
   446  			col := nameToCol[key.Name.L]
   447  			nullable := "YES"
   448  			if mysql.HasNotNullFlag(col.Flag) {
   449  				nullable = ""
   450  			}
   451  			record := types.MakeDatums(
   452  				catalogVal,    // TABLE_CATALOG
   453  				schema.Name.O, // TABLE_SCHEMA
   454  				table.Name.O,  // TABLE_NAME
   455  				nonUnique,     // NON_UNIQUE
   456  				schema.Name.O, // INDEX_SCHEMA
   457  				index.Name.O,  // INDEX_NAME
   458  				i+1,           // SEQ_IN_INDEX
   459  				key.Name.O,    // COLUMN_NAME
   460  				"A",           // COLLATION
   461  				0,             // CARDINALITY
   462  				nil,           // SUB_PART
   463  				nil,           // PACKED
   464  				nullable,      // NULLABLE
   465  				"BTREE",       // INDEX_TYPE
   466  				"",            // COMMENT
   467  				"",            // INDEX_COMMENT
   468  			)
   469  			rows = append(rows, record)
   470  		}
   471  	}
   472  	return rows
   473  }
   474  
   475  var tableNameToColumns = map[string]([]columnInfo){
   476  	tableSchemata:      schemataCols,
   477  	tableTables:        tablesCols,
   478  	tableColumns:       columnsCols,
   479  	tableStatistics:    statisticsCols,
   480  	tableCharacterSets: charsetCols,
   481  	tableCollations:    collationsCols,
   482  	tableFiles:         filesCols,
   483  	tableProfiling:     profilingCols,
   484  	tablePartitions:    partitionsCols,
   485  }
   486  
   487  func createMemoryTable(meta *model.TableInfo, alloc autoid.Allocator) (table.Table, error) {
   488  	tbl, _ := tables.MemoryTableFromMeta(alloc, meta)
   489  	return tbl, nil
   490  }