зеркало из https://github.com/github/vitess-gh.git
448 строки
14 KiB
Go
448 строки
14 KiB
Go
|
/*
|
||
|
Copyright 2017 Google 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 agreedto 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 mysql
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/youtube/vitess/go/sqltypes"
|
||
|
|
||
|
querypb "github.com/youtube/vitess/go/vt/proto/query"
|
||
|
)
|
||
|
|
||
|
// This file provides a few utility variables and methods, mostly for tests.
|
||
|
// The assumptions made about the types of fields and data returned
|
||
|
// by MySQl are validated in schema_test.go. This way all tests
|
||
|
// can use these variables and methods to simulate a MySQL server
|
||
|
// (using fakesqldb/ package for instance) and still be guaranteed correct
|
||
|
// data.
|
||
|
|
||
|
// DescribeTableFields contains the fields returned by a
|
||
|
// 'describe <table>' command. They are validated by the testDescribeTable
|
||
|
// test.
|
||
|
var DescribeTableFields = []*querypb.Field{
|
||
|
{
|
||
|
Name: "Field",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "COLUMNS",
|
||
|
OrgTable: "COLUMNS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COLUMN_NAME",
|
||
|
ColumnLength: 192,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Type",
|
||
|
Type: querypb.Type_TEXT,
|
||
|
Table: "COLUMNS",
|
||
|
OrgTable: "COLUMNS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COLUMN_TYPE",
|
||
|
ColumnLength: 589815,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_BLOB_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Null",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "COLUMNS",
|
||
|
OrgTable: "COLUMNS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "IS_NULLABLE",
|
||
|
ColumnLength: 9,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Key",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "COLUMNS",
|
||
|
OrgTable: "COLUMNS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COLUMN_KEY",
|
||
|
ColumnLength: 9,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Default",
|
||
|
Type: querypb.Type_TEXT,
|
||
|
Table: "COLUMNS",
|
||
|
OrgTable: "COLUMNS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COLUMN_DEFAULT",
|
||
|
ColumnLength: 589815,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_BLOB_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Extra",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "COLUMNS",
|
||
|
OrgTable: "COLUMNS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "EXTRA",
|
||
|
ColumnLength: 90,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// DescribeTableRow returns a row for a 'describe table' command.
|
||
|
// 'name' is the name of the field.
|
||
|
// 'type' is the type of the field. Something like:
|
||
|
// 'int(11)' for 'int'
|
||
|
// 'int(10) unsigned' for 'int unsigned'
|
||
|
// 'bigint(20)' for 'bigint'
|
||
|
// 'bigint(20) unsigned' for 'bigint unsigned'
|
||
|
// 'varchar(128)'
|
||
|
// 'null' is true if the field can be NULL.
|
||
|
// 'key' is either:
|
||
|
// - 'PRI' if part of the primary key. If not:
|
||
|
// - 'UNI' if part of a unique index. If not:
|
||
|
// - 'MUL' if part of a non-unique index. If not:
|
||
|
// - empty if part of no key / index.
|
||
|
// 'def' is the default value for the field. Empty if NULL default.
|
||
|
func DescribeTableRow(name string, typ string, null bool, key string, def string) []sqltypes.Value {
|
||
|
nullStr := "NO"
|
||
|
if null {
|
||
|
nullStr = "YES"
|
||
|
}
|
||
|
defCell := sqltypes.NULL
|
||
|
if def != "" {
|
||
|
defCell = sqltypes.MakeTrusted(sqltypes.Text, []byte(def))
|
||
|
}
|
||
|
return []sqltypes.Value{
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(name)),
|
||
|
sqltypes.MakeTrusted(sqltypes.Text, []byte(typ)),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(nullStr)),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(key)),
|
||
|
defCell,
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte("")), //extra
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ShowIndexFromTableFields contains the fields returned by a 'show
|
||
|
// index from <table>' command. They are validated by the
|
||
|
// testShowIndexFromTable test.
|
||
|
var ShowIndexFromTableFields = []*querypb.Field{
|
||
|
{
|
||
|
Name: "Table",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "TABLE_NAME",
|
||
|
ColumnLength: 192,
|
||
|
Charset: CharacterSetUtf8,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Non_unique",
|
||
|
Type: querypb.Type_INT64,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "NON_UNIQUE",
|
||
|
ColumnLength: 1,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Key_name",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "INDEX_NAME",
|
||
|
ColumnLength: 192,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Seq_in_index",
|
||
|
Type: querypb.Type_INT64,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "SEQ_IN_INDEX",
|
||
|
ColumnLength: 2,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Column_name",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COLUMN_NAME",
|
||
|
ColumnLength: 192,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Collation",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COLLATION",
|
||
|
ColumnLength: 3,
|
||
|
Charset: 33,
|
||
|
},
|
||
|
{
|
||
|
Name: "Cardinality",
|
||
|
Type: querypb.Type_INT64,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "CARDINALITY",
|
||
|
ColumnLength: 21,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Sub_part",
|
||
|
Type: querypb.Type_INT64,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "SUB_PART",
|
||
|
ColumnLength: 3,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Packed",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "PACKED",
|
||
|
ColumnLength: 30,
|
||
|
Charset: 33,
|
||
|
},
|
||
|
{
|
||
|
Name: "Null",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "NULLABLE",
|
||
|
ColumnLength: 9,
|
||
|
Charset: 33,
|
||
|
Flags: 1,
|
||
|
},
|
||
|
{
|
||
|
Name: "Index_type",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "INDEX_TYPE",
|
||
|
ColumnLength: 48,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "Comment",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "COMMENT",
|
||
|
ColumnLength: 48,
|
||
|
Charset: 33,
|
||
|
},
|
||
|
{
|
||
|
Name: "Index_comment",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "STATISTICS",
|
||
|
OrgTable: "STATISTICS",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "INDEX_COMMENT",
|
||
|
ColumnLength: 3072,
|
||
|
Charset: 33,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// ShowIndexFromTableRow returns the fields from a 'show index from table'
|
||
|
// command.
|
||
|
// 'table' is the table name.
|
||
|
// 'unique' is true for unique indexes, false for non-unique indexes.
|
||
|
// 'keyName' is 'PRIMARY' for PKs, otherwise the name of the index.
|
||
|
// 'seqInIndex' is starting at 1 for first key in index.
|
||
|
// 'columnName' is the name of the column this index applies to.
|
||
|
// 'nullable' is true if this column can be null.
|
||
|
func ShowIndexFromTableRow(table string, unique bool, keyName string, seqInIndex int, columnName string, nullable bool) []sqltypes.Value {
|
||
|
nonUnique := "1"
|
||
|
if unique {
|
||
|
nonUnique = "0"
|
||
|
}
|
||
|
nullableStr := ""
|
||
|
if nullable {
|
||
|
nullableStr = "YES"
|
||
|
}
|
||
|
return []sqltypes.Value{
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(table)),
|
||
|
sqltypes.MakeTrusted(sqltypes.Int64, []byte(nonUnique)),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(keyName)),
|
||
|
sqltypes.MakeTrusted(sqltypes.Int64, []byte(fmt.Sprintf("%v", seqInIndex))),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(columnName)),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte("A")), // Collation
|
||
|
sqltypes.MakeTrusted(sqltypes.Int64, []byte("0")), // Cardinality
|
||
|
sqltypes.NULL, // Sub_part
|
||
|
sqltypes.NULL, // Packed
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(nullableStr)),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte("BTREE")), // Index_type
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte("")), // Comment
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte("")), // Index_comment
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// BaseShowTables is the base query used in further methods.
|
||
|
const BaseShowTables = "SELECT table_name, table_type, unix_timestamp(create_time), table_comment, table_rows, data_length, index_length, data_free, max_data_length FROM information_schema.tables WHERE table_schema = database()"
|
||
|
|
||
|
// BaseShowTablesForTable specializes BaseShowTables for a single table.
|
||
|
func BaseShowTablesForTable(table string) string {
|
||
|
return fmt.Sprintf("%s and table_name = '%s'", BaseShowTables, table)
|
||
|
}
|
||
|
|
||
|
// BaseShowTablesFields contains the fields returned by a BaseShowTables or a BaseShowTablesForTable command.
|
||
|
// They are validated by the
|
||
|
// testBaseShowTables test.
|
||
|
var BaseShowTablesFields = []*querypb.Field{
|
||
|
{
|
||
|
Name: "table_name",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "TABLE_NAME",
|
||
|
ColumnLength: 192,
|
||
|
Charset: CharacterSetUtf8,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "table_type",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "TABLE_TYPE",
|
||
|
ColumnLength: 192,
|
||
|
Charset: CharacterSetUtf8,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "unix_timestamp(create_time)",
|
||
|
Type: querypb.Type_INT64,
|
||
|
ColumnLength: 11,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_BINARY_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "table_comment",
|
||
|
Type: querypb.Type_VARCHAR,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "TABLE_COMMENT",
|
||
|
ColumnLength: 6144,
|
||
|
Charset: CharacterSetUtf8,
|
||
|
Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "table_rows",
|
||
|
Type: querypb.Type_UINT64,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "TABLE_ROWS",
|
||
|
ColumnLength: 21,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_UNSIGNED_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "data_length",
|
||
|
Type: querypb.Type_UINT64,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "DATA_LENGTH",
|
||
|
ColumnLength: 21,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_UNSIGNED_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "index_length",
|
||
|
Type: querypb.Type_UINT64,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "INDEX_LENGTH",
|
||
|
ColumnLength: 21,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_UNSIGNED_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "data_free",
|
||
|
Type: querypb.Type_UINT64,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "DATA_FREE",
|
||
|
ColumnLength: 21,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_UNSIGNED_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
{
|
||
|
Name: "max_data_length",
|
||
|
Type: querypb.Type_UINT64,
|
||
|
Table: "tables",
|
||
|
OrgTable: "TABLES",
|
||
|
Database: "information_schema",
|
||
|
OrgName: "MAX_DATA_LENGTH",
|
||
|
ColumnLength: 21,
|
||
|
Charset: CharacterSetBinary,
|
||
|
Flags: uint32(querypb.MySqlFlag_UNSIGNED_FLAG | querypb.MySqlFlag_NUM_FLAG),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// BaseShowTablesRow returns the fields from a BaseShowTables or
|
||
|
// BaseShowTablesForTable command.
|
||
|
func BaseShowTablesRow(tableName string, isView bool, comment string) []sqltypes.Value {
|
||
|
tableType := "BASE TABLE"
|
||
|
if isView {
|
||
|
tableType = "VIEW"
|
||
|
}
|
||
|
return []sqltypes.Value{
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(tableName)),
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(tableType)),
|
||
|
sqltypes.MakeTrusted(sqltypes.Int64, []byte("1427325875")), // unix_timestamp(create_time)
|
||
|
sqltypes.MakeTrusted(sqltypes.VarChar, []byte(comment)),
|
||
|
sqltypes.MakeTrusted(sqltypes.Uint64, []byte("0")), // table_rows
|
||
|
sqltypes.MakeTrusted(sqltypes.Uint64, []byte("0")), // data_length
|
||
|
sqltypes.MakeTrusted(sqltypes.Uint64, []byte("0")), // index_length
|
||
|
sqltypes.MakeTrusted(sqltypes.Uint64, []byte("0")), // data_free
|
||
|
sqltypes.MakeTrusted(sqltypes.Uint64, []byte("0")), // max_data_length
|
||
|
}
|
||
|
}
|