model.go 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  1. // Copyright 2015 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. package model
  14. import (
  15. "encoding/json"
  16. "strconv"
  17. "strings"
  18. "time"
  19. "github.com/pingcap/errors"
  20. "github.com/pingcap/parser/auth"
  21. "github.com/pingcap/parser/mysql"
  22. "github.com/pingcap/parser/types"
  23. )
  24. // SchemaState is the state for schema elements.
  25. type SchemaState byte
  26. const (
  27. // StateNone means this schema element is absent and can't be used.
  28. StateNone SchemaState = iota
  29. // StateDeleteOnly means we can only delete items for this schema element.
  30. StateDeleteOnly
  31. // StateWriteOnly means we can use any write operation on this schema element,
  32. // but outer can't read the changed data.
  33. StateWriteOnly
  34. // StateWriteReorganization means we are re-organizing whole data after write only state.
  35. StateWriteReorganization
  36. // StateDeleteReorganization means we are re-organizing whole data after delete only state.
  37. StateDeleteReorganization
  38. // StatePublic means this schema element is ok for all write and read operations.
  39. StatePublic
  40. // StateReplica means we're waiting tiflash replica to be finished.
  41. StateReplicaOnly
  42. // StateGlobalTxnOnly means we can only use global txn for operator on this schema element
  43. StateGlobalTxnOnly
  44. /*
  45. * Please add the new state at the end to keep the values consistent across versions.
  46. */
  47. )
  48. // String implements fmt.Stringer interface.
  49. func (s SchemaState) String() string {
  50. switch s {
  51. case StateDeleteOnly:
  52. return "delete only"
  53. case StateWriteOnly:
  54. return "write only"
  55. case StateWriteReorganization:
  56. return "write reorganization"
  57. case StateDeleteReorganization:
  58. return "delete reorganization"
  59. case StatePublic:
  60. return "public"
  61. case StateReplicaOnly:
  62. return "replica only"
  63. case StateGlobalTxnOnly:
  64. return "global txn only"
  65. default:
  66. return "none"
  67. }
  68. }
  69. const (
  70. // ColumnInfoVersion0 means the column info version is 0.
  71. ColumnInfoVersion0 = uint64(0)
  72. // ColumnInfoVersion1 means the column info version is 1.
  73. ColumnInfoVersion1 = uint64(1)
  74. // ColumnInfoVersion2 means the column info version is 2.
  75. // This is for v2.1.7 to Compatible with older versions charset problem.
  76. // Old version such as v2.0.8 treat utf8 as utf8mb4, because there is no UTF8 check in v2.0.8.
  77. // After version V2.1.2 (PR#8738) , TiDB add UTF8 check, then the user upgrade from v2.0.8 insert some UTF8MB4 characters will got error.
  78. // This is not compatibility for user. Then we try to fix this in PR #9820, and increase the version number.
  79. ColumnInfoVersion2 = uint64(2)
  80. // CurrLatestColumnInfoVersion means the latest column info in the current TiDB.
  81. CurrLatestColumnInfoVersion = ColumnInfoVersion2
  82. )
  83. // ChangeStateInfo is used for recording the information of schema changing.
  84. type ChangeStateInfo struct {
  85. // DependencyColumnOffset is the changing column offset that the current column depends on when executing modify/change column.
  86. DependencyColumnOffset int `json:"relative_col_offset"`
  87. }
  88. // ColumnInfo provides meta data describing of a table column.
  89. type ColumnInfo struct {
  90. ID int64 `json:"id"`
  91. Name CIStr `json:"name"`
  92. Offset int `json:"offset"`
  93. OriginDefaultValue interface{} `json:"origin_default"`
  94. OriginDefaultValueBit []byte `json:"origin_default_bit"`
  95. DefaultValue interface{} `json:"default"`
  96. DefaultValueBit []byte `json:"default_bit"`
  97. // DefaultIsExpr is indicates the default value string is expr.
  98. DefaultIsExpr bool `json:"default_is_expr"`
  99. GeneratedExprString string `json:"generated_expr_string"`
  100. GeneratedStored bool `json:"generated_stored"`
  101. Dependences map[string]struct{} `json:"dependences"`
  102. types.FieldType `json:"type"`
  103. State SchemaState `json:"state"`
  104. Comment string `json:"comment"`
  105. // A hidden column is used internally(expression index) and are not accessible by users.
  106. Hidden bool `json:"hidden"`
  107. *ChangeStateInfo `json:"change_state_info"`
  108. // Version means the version of the column info.
  109. // Version = 0: For OriginDefaultValue and DefaultValue of timestamp column will stores the default time in system time zone.
  110. // That is a bug if multiple TiDB servers in different system time zone.
  111. // Version = 1: For OriginDefaultValue and DefaultValue of timestamp column will stores the default time in UTC time zone.
  112. // This will fix bug in version 0. For compatibility with version 0, we add version field in column info struct.
  113. Version uint64 `json:"version"`
  114. }
  115. // Clone clones ColumnInfo.
  116. func (c *ColumnInfo) Clone() *ColumnInfo {
  117. nc := *c
  118. return &nc
  119. }
  120. // IsGenerated returns true if the column is generated column.
  121. func (c *ColumnInfo) IsGenerated() bool {
  122. return len(c.GeneratedExprString) != 0
  123. }
  124. // SetOriginalDefaultValue sets the origin default value.
  125. // For mysql.TypeBit type, the default value storage format must be a string.
  126. // Other value such as int must convert to string format first.
  127. // The mysql.TypeBit type supports the null default value.
  128. func (c *ColumnInfo) SetOriginDefaultValue(value interface{}) error {
  129. c.OriginDefaultValue = value
  130. if c.Tp == mysql.TypeBit {
  131. if value == nil {
  132. return nil
  133. }
  134. if v, ok := value.(string); ok {
  135. c.OriginDefaultValueBit = []byte(v)
  136. return nil
  137. }
  138. return types.ErrInvalidDefault.GenWithStackByArgs(c.Name)
  139. }
  140. return nil
  141. }
  142. // GetOriginalDefaultValue gets the origin default value.
  143. func (c *ColumnInfo) GetOriginDefaultValue() interface{} {
  144. if c.Tp == mysql.TypeBit && c.OriginDefaultValueBit != nil {
  145. // If the column type is BIT, both `OriginDefaultValue` and `DefaultValue` of ColumnInfo are corrupted,
  146. // because the content before json.Marshal is INCONSISTENT with the content after json.Unmarshal.
  147. return string(c.OriginDefaultValueBit)
  148. }
  149. return c.OriginDefaultValue
  150. }
  151. // SetDefaultValue sets the default value.
  152. func (c *ColumnInfo) SetDefaultValue(value interface{}) error {
  153. c.DefaultValue = value
  154. if c.Tp == mysql.TypeBit {
  155. // For mysql.TypeBit type, the default value storage format must be a string.
  156. // Other value such as int must convert to string format first.
  157. // The mysql.TypeBit type supports the null default value.
  158. if value == nil {
  159. return nil
  160. }
  161. if v, ok := value.(string); ok {
  162. c.DefaultValueBit = []byte(v)
  163. return nil
  164. }
  165. return types.ErrInvalidDefault.GenWithStackByArgs(c.Name)
  166. }
  167. return nil
  168. }
  169. // GetDefaultValue gets the default value of the column.
  170. // Default value use to stored in DefaultValue field, but now,
  171. // bit type default value will store in DefaultValueBit for fix bit default value decode/encode bug.
  172. func (c *ColumnInfo) GetDefaultValue() interface{} {
  173. if c.Tp == mysql.TypeBit && c.DefaultValueBit != nil {
  174. return string(c.DefaultValueBit)
  175. }
  176. return c.DefaultValue
  177. }
  178. // GetTypeDesc gets the description for column type.
  179. func (c *ColumnInfo) GetTypeDesc() string {
  180. desc := c.FieldType.CompactStr()
  181. if mysql.HasUnsignedFlag(c.Flag) && c.Tp != mysql.TypeBit && c.Tp != mysql.TypeYear {
  182. desc += " unsigned"
  183. }
  184. if mysql.HasZerofillFlag(c.Flag) && c.Tp != mysql.TypeYear {
  185. desc += " zerofill"
  186. }
  187. return desc
  188. }
  189. // FindColumnInfo finds ColumnInfo in cols by name.
  190. func FindColumnInfo(cols []*ColumnInfo, name string) *ColumnInfo {
  191. name = strings.ToLower(name)
  192. for _, col := range cols {
  193. if col.Name.L == name {
  194. return col
  195. }
  196. }
  197. return nil
  198. }
  199. // ExtraHandleID is the column ID of column which we need to append to schema to occupy the handle's position
  200. // for use of execution phase.
  201. const ExtraHandleID = -1
  202. // ExtraPartitionID is the column ID of column which store the partitionID decoded in global index values.
  203. const ExtraPidColID = -2
  204. const (
  205. // TableInfoVersion0 means the table info version is 0.
  206. // Upgrade from v2.1.1 or v2.1.2 to v2.1.3 and later, and then execute a "change/modify column" statement
  207. // that does not specify a charset value for column. Then the following error may be reported:
  208. // ERROR 1105 (HY000): unsupported modify charset from utf8mb4 to utf8.
  209. // To eliminate this error, we will not modify the charset of this column
  210. // when executing a change/modify column statement that does not specify a charset value for column.
  211. // This behavior is not compatible with MySQL.
  212. TableInfoVersion0 = uint16(0)
  213. // TableInfoVersion1 means the table info version is 1.
  214. // When we execute a change/modify column statement that does not specify a charset value for column,
  215. // we set the charset of this column to the charset of table. This behavior is compatible with MySQL.
  216. TableInfoVersion1 = uint16(1)
  217. // TableInfoVersion2 means the table info version is 2.
  218. // This is for v2.1.7 to Compatible with older versions charset problem.
  219. // Old version such as v2.0.8 treat utf8 as utf8mb4, because there is no UTF8 check in v2.0.8.
  220. // After version V2.1.2 (PR#8738) , TiDB add UTF8 check, then the user upgrade from v2.0.8 insert some UTF8MB4 characters will got error.
  221. // This is not compatibility for user. Then we try to fix this in PR #9820, and increase the version number.
  222. TableInfoVersion2 = uint16(2)
  223. // TableInfoVersion3 means the table info version is 3.
  224. // This version aims to deal with upper-cased charset name in TableInfo stored by versions prior to TiDB v2.1.9:
  225. // TiDB always suppose all charsets / collations as lower-cased and try to convert them if they're not.
  226. // However, the convert is missed in some scenarios before v2.1.9, so for all those tables prior to TableInfoVersion3, their
  227. // charsets / collations will be converted to lower-case while loading from the storage.
  228. TableInfoVersion3 = uint16(3)
  229. // TableInfoVersion4 indicates that the auto_increment allocator in TiDB has been separated from
  230. // _tidb_rowid allocator. This version is introduced to preserve the compatibility of old tables:
  231. // the tables with version < TableInfoVersion4 still use a single allocator for auto_increment and _tidb_rowid.
  232. // Also see https://github.com/pingcap/tidb/issues/982.
  233. TableInfoVersion4 = uint16(4)
  234. // CurrLatestTableInfoVersion means the latest table info in the current TiDB.
  235. CurrLatestTableInfoVersion = TableInfoVersion4
  236. )
  237. // ExtraHandleName is the name of ExtraHandle Column.
  238. var ExtraHandleName = NewCIStr("_tidb_rowid")
  239. // ExtraPartitionIdName is the name of ExtraPartitionId Column.
  240. var ExtraPartitionIdName = NewCIStr("_tidb_pid")
  241. // TableInfo provides meta data describing a DB table.
  242. type TableInfo struct {
  243. ID int64 `json:"id"`
  244. Name CIStr `json:"name"`
  245. Charset string `json:"charset"`
  246. Collate string `json:"collate"`
  247. // Columns are listed in the order in which they appear in the schema.
  248. Columns []*ColumnInfo `json:"cols"`
  249. Indices []*IndexInfo `json:"index_info"`
  250. Constraints []*ConstraintInfo `json:"constraint_info"`
  251. ForeignKeys []*FKInfo `json:"fk_info"`
  252. State SchemaState `json:"state"`
  253. // PKIsHandle is true when primary key is a single integer column.
  254. PKIsHandle bool `json:"pk_is_handle"`
  255. // IsCommonHandle is true when clustered index feature is
  256. // enabled and the primary key is not a single integer column.
  257. IsCommonHandle bool `json:"is_common_handle"`
  258. // CommonHandleVersion is the version of the clustered index.
  259. // 0 for the clustered index created == 5.0.0 RC.
  260. // 1 for the clustered index created > 5.0.0 RC.
  261. CommonHandleVersion uint16 `json:"common_handle_version"`
  262. Comment string `json:"comment"`
  263. AutoIncID int64 `json:"auto_inc_id"`
  264. AutoIdCache int64 `json:"auto_id_cache"`
  265. AutoRandID int64 `json:"auto_rand_id"`
  266. MaxColumnID int64 `json:"max_col_id"`
  267. MaxIndexID int64 `json:"max_idx_id"`
  268. MaxConstraintID int64 `json:"max_cst_id"`
  269. // UpdateTS is used to record the timestamp of updating the table's schema information.
  270. // These changing schema operations don't include 'truncate table' and 'rename table'.
  271. UpdateTS uint64 `json:"update_timestamp"`
  272. // OldSchemaID :
  273. // Because auto increment ID has schemaID as prefix,
  274. // We need to save original schemaID to keep autoID unchanged
  275. // while renaming a table from one database to another.
  276. // TODO: Remove it.
  277. // Now it only uses for compatibility with the old version that already uses this field.
  278. OldSchemaID int64 `json:"old_schema_id,omitempty"`
  279. // ShardRowIDBits specify if the implicit row ID is sharded.
  280. ShardRowIDBits uint64
  281. // MaxShardRowIDBits uses to record the max ShardRowIDBits be used so far.
  282. MaxShardRowIDBits uint64 `json:"max_shard_row_id_bits"`
  283. // AutoRandomBits is used to set the bit number to shard automatically when PKIsHandle.
  284. AutoRandomBits uint64 `json:"auto_random_bits"`
  285. // PreSplitRegions specify the pre-split region when create table.
  286. // The pre-split region num is 2^(PreSplitRegions-1).
  287. // And the PreSplitRegions should less than or equal to ShardRowIDBits.
  288. PreSplitRegions uint64 `json:"pre_split_regions"`
  289. Partition *PartitionInfo `json:"partition"`
  290. Compression string `json:"compression"`
  291. View *ViewInfo `json:"view"`
  292. Sequence *SequenceInfo `json:"sequence"`
  293. // Lock represent the table lock info.
  294. Lock *TableLockInfo `json:"Lock"`
  295. // Version means the version of the table info.
  296. Version uint16 `json:"version"`
  297. // TiFlashReplica means the TiFlash replica info.
  298. TiFlashReplica *TiFlashReplicaInfo `json:"tiflash_replica"`
  299. // IsColumnar means the table is column-oriented.
  300. // It's true when the engine of the table is TiFlash only.
  301. IsColumnar bool `json:"is_columnar"`
  302. }
  303. // TableLockInfo provides meta data describing a table lock.
  304. type TableLockInfo struct {
  305. Tp TableLockType
  306. // Use array because there may be multiple sessions holding the same read lock.
  307. Sessions []SessionInfo
  308. State TableLockState
  309. // TS is used to record the timestamp this table lock been locked.
  310. TS uint64
  311. }
  312. // SessionInfo contain the session ID and the server ID.
  313. type SessionInfo struct {
  314. ServerID string
  315. SessionID uint64
  316. }
  317. func (s SessionInfo) String() string {
  318. return "server: " + s.ServerID + "_session: " + strconv.FormatUint(s.SessionID, 10)
  319. }
  320. // TableLockTpInfo is composed by schema ID, table ID and table lock type.
  321. type TableLockTpInfo struct {
  322. SchemaID int64
  323. TableID int64
  324. Tp TableLockType
  325. }
  326. // TableLockState is the state for table lock.
  327. type TableLockState byte
  328. const (
  329. // TableLockStateNone means this table lock is absent.
  330. TableLockStateNone TableLockState = iota
  331. // TableLockStatePreLock means this table lock is pre-lock state. Other session doesn't hold this lock should't do corresponding operation according to the lock type.
  332. TableLockStatePreLock
  333. // TableLockStatePublic means this table lock is public state.
  334. TableLockStatePublic
  335. )
  336. // String implements fmt.Stringer interface.
  337. func (t TableLockState) String() string {
  338. switch t {
  339. case TableLockStatePreLock:
  340. return "pre-lock"
  341. case TableLockStatePublic:
  342. return "public"
  343. default:
  344. return "none"
  345. }
  346. }
  347. // TableLockType is the type of the table lock.
  348. type TableLockType byte
  349. const (
  350. TableLockNone TableLockType = iota
  351. // TableLockRead means the session with this lock can read the table (but not write it).
  352. // Multiple sessions can acquire a READ lock for the table at the same time.
  353. // Other sessions can read the table without explicitly acquiring a READ lock.
  354. TableLockRead
  355. // TableLockReadLocal is not supported.
  356. TableLockReadLocal
  357. // TableLockReadOnly is used to set a table into read-only status,
  358. // when the session exits, it will not release its lock automatically.
  359. TableLockReadOnly
  360. // TableLockWrite means only the session with this lock has write/read permission.
  361. // Only the session that holds the lock can access the table. No other session can access it until the lock is released.
  362. TableLockWrite
  363. // TableLockWriteLocal means the session with this lock has write/read permission, and the other session still has read permission.
  364. TableLockWriteLocal
  365. )
  366. func (t TableLockType) String() string {
  367. switch t {
  368. case TableLockNone:
  369. return "NONE"
  370. case TableLockRead:
  371. return "READ"
  372. case TableLockReadLocal:
  373. return "READ LOCAL"
  374. case TableLockReadOnly:
  375. return "READ ONLY"
  376. case TableLockWriteLocal:
  377. return "WRITE LOCAL"
  378. case TableLockWrite:
  379. return "WRITE"
  380. }
  381. return ""
  382. }
  383. // TiFlashReplicaInfo means the flash replica info.
  384. type TiFlashReplicaInfo struct {
  385. Count uint64
  386. LocationLabels []string
  387. Available bool
  388. AvailablePartitionIDs []int64
  389. }
  390. // IsPartitionAvailable checks whether the partition table replica was available.
  391. func (tr *TiFlashReplicaInfo) IsPartitionAvailable(pid int64) bool {
  392. for _, id := range tr.AvailablePartitionIDs {
  393. if id == pid {
  394. return true
  395. }
  396. }
  397. return false
  398. }
  399. // GetPartitionInfo returns the partition information.
  400. func (t *TableInfo) GetPartitionInfo() *PartitionInfo {
  401. if t.Partition != nil && t.Partition.Enable {
  402. return t.Partition
  403. }
  404. return nil
  405. }
  406. // GetUpdateTime gets the table's updating time.
  407. func (t *TableInfo) GetUpdateTime() time.Time {
  408. return TSConvert2Time(t.UpdateTS)
  409. }
  410. // GetDBID returns the schema ID that is used to create an allocator.
  411. // TODO: Remove it after removing OldSchemaID.
  412. func (t *TableInfo) GetDBID(dbID int64) int64 {
  413. if t.OldSchemaID != 0 {
  414. return t.OldSchemaID
  415. }
  416. return dbID
  417. }
  418. // Clone clones TableInfo.
  419. func (t *TableInfo) Clone() *TableInfo {
  420. nt := *t
  421. nt.Columns = make([]*ColumnInfo, len(t.Columns))
  422. nt.Indices = make([]*IndexInfo, len(t.Indices))
  423. nt.ForeignKeys = make([]*FKInfo, len(t.ForeignKeys))
  424. for i := range t.Columns {
  425. nt.Columns[i] = t.Columns[i].Clone()
  426. }
  427. for i := range t.Indices {
  428. nt.Indices[i] = t.Indices[i].Clone()
  429. }
  430. for i := range t.ForeignKeys {
  431. nt.ForeignKeys[i] = t.ForeignKeys[i].Clone()
  432. }
  433. return &nt
  434. }
  435. // GetPkName will return the pk name if pk exists.
  436. func (t *TableInfo) GetPkName() CIStr {
  437. for _, colInfo := range t.Columns {
  438. if mysql.HasPriKeyFlag(colInfo.Flag) {
  439. return colInfo.Name
  440. }
  441. }
  442. return CIStr{}
  443. }
  444. // GetPkColInfo gets the ColumnInfo of pk if exists.
  445. // Make sure PkIsHandle checked before call this method.
  446. func (t *TableInfo) GetPkColInfo() *ColumnInfo {
  447. for _, colInfo := range t.Columns {
  448. if mysql.HasPriKeyFlag(colInfo.Flag) {
  449. return colInfo
  450. }
  451. }
  452. return nil
  453. }
  454. func (t *TableInfo) GetAutoIncrementColInfo() *ColumnInfo {
  455. for _, colInfo := range t.Columns {
  456. if mysql.HasAutoIncrementFlag(colInfo.Flag) {
  457. return colInfo
  458. }
  459. }
  460. return nil
  461. }
  462. func (t *TableInfo) IsAutoIncColUnsigned() bool {
  463. col := t.GetAutoIncrementColInfo()
  464. if col == nil {
  465. return false
  466. }
  467. return mysql.HasUnsignedFlag(col.Flag)
  468. }
  469. // ContainsAutoRandomBits indicates whether a table contains auto_random column.
  470. func (t *TableInfo) ContainsAutoRandomBits() bool {
  471. return t.AutoRandomBits != 0
  472. }
  473. // IsAutoRandomBitColUnsigned indicates whether the auto_random column is unsigned. Make sure the table contains auto_random before calling this method.
  474. func (t *TableInfo) IsAutoRandomBitColUnsigned() bool {
  475. if !t.PKIsHandle || t.AutoRandomBits == 0 {
  476. return false
  477. }
  478. return mysql.HasUnsignedFlag(t.GetPkColInfo().Flag)
  479. }
  480. // Cols returns the columns of the table in public state.
  481. func (t *TableInfo) Cols() []*ColumnInfo {
  482. publicColumns := make([]*ColumnInfo, len(t.Columns))
  483. maxOffset := -1
  484. for _, col := range t.Columns {
  485. if col.State != StatePublic {
  486. continue
  487. }
  488. publicColumns[col.Offset] = col
  489. if maxOffset < col.Offset {
  490. maxOffset = col.Offset
  491. }
  492. }
  493. return publicColumns[0 : maxOffset+1]
  494. }
  495. // FindIndexByName finds index by name.
  496. func (t *TableInfo) FindIndexByName(idxName string) *IndexInfo {
  497. for _, idx := range t.Indices {
  498. if idx.Name.L == idxName {
  499. return idx
  500. }
  501. }
  502. return nil
  503. }
  504. // IsLocked checks whether the table was locked.
  505. func (t *TableInfo) IsLocked() bool {
  506. return t.Lock != nil && len(t.Lock.Sessions) > 0
  507. }
  508. // NewExtraHandleColInfo mocks a column info for extra handle column.
  509. func NewExtraHandleColInfo() *ColumnInfo {
  510. colInfo := &ColumnInfo{
  511. ID: ExtraHandleID,
  512. Name: ExtraHandleName,
  513. }
  514. colInfo.Flag = mysql.PriKeyFlag | mysql.NotNullFlag
  515. colInfo.Tp = mysql.TypeLonglong
  516. colInfo.Flen, colInfo.Decimal = mysql.GetDefaultFieldLengthAndDecimal(mysql.TypeLonglong)
  517. return colInfo
  518. }
  519. // NewExtraPartitionIDColInfo mocks a column info for extra partition id column.
  520. func NewExtraPartitionIDColInfo() *ColumnInfo {
  521. colInfo := &ColumnInfo{
  522. ID: ExtraPidColID,
  523. Name: ExtraPartitionIdName,
  524. }
  525. colInfo.Tp = mysql.TypeLonglong
  526. colInfo.Flen, colInfo.Decimal = mysql.GetDefaultFieldLengthAndDecimal(mysql.TypeLonglong)
  527. return colInfo
  528. }
  529. // ColumnIsInIndex checks whether c is included in any indices of t.
  530. func (t *TableInfo) ColumnIsInIndex(c *ColumnInfo) bool {
  531. for _, index := range t.Indices {
  532. for _, column := range index.Columns {
  533. if column.Name.L == c.Name.L {
  534. return true
  535. }
  536. }
  537. }
  538. return false
  539. }
  540. // IsView checks if TableInfo is a view.
  541. func (t *TableInfo) IsView() bool {
  542. return t.View != nil
  543. }
  544. // IsSequence checks if TableInfo is a sequence.
  545. func (t *TableInfo) IsSequence() bool {
  546. return t.Sequence != nil
  547. }
  548. // IsBaseTable checks to see the table is neither a view or a sequence.
  549. func (t *TableInfo) IsBaseTable() bool {
  550. return t.Sequence == nil && t.View == nil
  551. }
  552. // ViewAlgorithm is VIEW's SQL AlGORITHM characteristic.
  553. // See https://dev.mysql.com/doc/refman/5.7/en/view-algorithms.html
  554. type ViewAlgorithm int
  555. const (
  556. AlgorithmUndefined ViewAlgorithm = iota
  557. AlgorithmMerge
  558. AlgorithmTemptable
  559. )
  560. func (v *ViewAlgorithm) String() string {
  561. switch *v {
  562. case AlgorithmMerge:
  563. return "MERGE"
  564. case AlgorithmTemptable:
  565. return "TEMPTABLE"
  566. case AlgorithmUndefined:
  567. return "UNDEFINED"
  568. default:
  569. return "UNDEFINED"
  570. }
  571. }
  572. // ViewSecurity is VIEW's SQL SECURITY characteristic.
  573. // See https://dev.mysql.com/doc/refman/5.7/en/create-view.html
  574. type ViewSecurity int
  575. const (
  576. SecurityDefiner ViewSecurity = iota
  577. SecurityInvoker
  578. )
  579. func (v *ViewSecurity) String() string {
  580. switch *v {
  581. case SecurityInvoker:
  582. return "INVOKER"
  583. case SecurityDefiner:
  584. return "DEFINER"
  585. default:
  586. return "DEFINER"
  587. }
  588. }
  589. // ViewCheckOption is VIEW's WITH CHECK OPTION clause part.
  590. // See https://dev.mysql.com/doc/refman/5.7/en/view-check-option.html
  591. type ViewCheckOption int
  592. const (
  593. CheckOptionLocal ViewCheckOption = iota
  594. CheckOptionCascaded
  595. )
  596. func (v *ViewCheckOption) String() string {
  597. switch *v {
  598. case CheckOptionLocal:
  599. return "LOCAL"
  600. case CheckOptionCascaded:
  601. return "CASCADED"
  602. default:
  603. return "CASCADED"
  604. }
  605. }
  606. // ViewInfo provides meta data describing a DB view.
  607. type ViewInfo struct {
  608. Algorithm ViewAlgorithm `json:"view_algorithm"`
  609. Definer *auth.UserIdentity `json:"view_definer"`
  610. Security ViewSecurity `json:"view_security"`
  611. SelectStmt string `json:"view_select"`
  612. CheckOption ViewCheckOption `json:"view_checkoption"`
  613. Cols []CIStr `json:"view_cols"`
  614. }
  615. const (
  616. DefaultSequenceCacheBool = true
  617. DefaultSequenceCycleBool = false
  618. DefaultSequenceOrderBool = false
  619. DefaultSequenceCacheValue = int64(1000)
  620. DefaultSequenceIncrementValue = int64(1)
  621. DefaultPositiveSequenceStartValue = int64(1)
  622. DefaultNegativeSequenceStartValue = int64(-1)
  623. DefaultPositiveSequenceMinValue = int64(1)
  624. DefaultPositiveSequenceMaxValue = int64(9223372036854775806)
  625. DefaultNegativeSequenceMaxValue = int64(-1)
  626. DefaultNegativeSequenceMinValue = int64(-9223372036854775807)
  627. )
  628. // SequenceInfo provide meta data describing a DB sequence.
  629. type SequenceInfo struct {
  630. Start int64 `json:"sequence_start"`
  631. Cache bool `json:"sequence_cache"`
  632. Cycle bool `json:"sequence_cycle"`
  633. MinValue int64 `json:"sequence_min_value"`
  634. MaxValue int64 `json:"sequence_max_value"`
  635. Increment int64 `json:"sequence_increment"`
  636. CacheValue int64 `json:"sequence_cache_value"`
  637. Comment string `json:"sequence_comment"`
  638. }
  639. // PartitionType is the type for PartitionInfo
  640. type PartitionType int
  641. // Partition types.
  642. const (
  643. PartitionTypeRange PartitionType = 1
  644. PartitionTypeHash PartitionType = 2
  645. PartitionTypeList PartitionType = 3
  646. PartitionTypeKey PartitionType = 4
  647. PartitionTypeSystemTime PartitionType = 5
  648. )
  649. func (p PartitionType) String() string {
  650. switch p {
  651. case PartitionTypeRange:
  652. return "RANGE"
  653. case PartitionTypeHash:
  654. return "HASH"
  655. case PartitionTypeList:
  656. return "LIST"
  657. case PartitionTypeKey:
  658. return "KEY"
  659. case PartitionTypeSystemTime:
  660. return "SYSTEM_TIME"
  661. default:
  662. return ""
  663. }
  664. }
  665. // PartitionInfo provides table partition info.
  666. type PartitionInfo struct {
  667. Type PartitionType `json:"type"`
  668. Expr string `json:"expr"`
  669. Columns []CIStr `json:"columns"`
  670. // User may already creates table with partition but table partition is not
  671. // yet supported back then. When Enable is true, write/read need use tid
  672. // rather than pid.
  673. Enable bool `json:"enable"`
  674. Definitions []PartitionDefinition `json:"definitions"`
  675. // AddingDefinitions is filled when adding a partition that is in the mid state.
  676. AddingDefinitions []PartitionDefinition `json:"adding_definitions"`
  677. // DroppingDefinitions is filled when dropping a partition that is in the mid state.
  678. DroppingDefinitions []PartitionDefinition `json:"dropping_definitions"`
  679. States []PartitionState `json:"states"`
  680. Num uint64 `json:"num"`
  681. }
  682. // GetNameByID gets the partition name by ID.
  683. func (pi *PartitionInfo) GetNameByID(id int64) string {
  684. definitions := pi.Definitions
  685. // do not convert this loop to `for _, def := range definitions`.
  686. // see https://github.com/pingcap/parser/pull/1072 for the benchmark.
  687. for i := range definitions {
  688. if id == definitions[i].ID {
  689. return definitions[i].Name.L
  690. }
  691. }
  692. return ""
  693. }
  694. func (pi *PartitionInfo) GetStateByID(id int64) SchemaState {
  695. for _, pstate := range pi.States {
  696. if pstate.ID == id {
  697. return pstate.State
  698. }
  699. }
  700. return StatePublic
  701. }
  702. func (pi *PartitionInfo) SetStateByID(id int64, state SchemaState) {
  703. newState := PartitionState{ID: id, State: state}
  704. for i, pstate := range pi.States {
  705. if pstate.ID == id {
  706. pi.States[i] = newState
  707. return
  708. }
  709. }
  710. if pi.States == nil {
  711. pi.States = make([]PartitionState, 0, 1)
  712. }
  713. pi.States = append(pi.States, newState)
  714. }
  715. func (pi *PartitionInfo) GCPartitionStates() {
  716. if len(pi.States) < 1 {
  717. return
  718. }
  719. newStates := make([]PartitionState, 0, len(pi.Definitions))
  720. for _, state := range pi.States {
  721. found := false
  722. for _, def := range pi.Definitions {
  723. if def.ID == state.ID {
  724. found = true
  725. break
  726. }
  727. }
  728. if found {
  729. newStates = append(newStates, state)
  730. }
  731. }
  732. pi.States = newStates
  733. }
  734. type PartitionState struct {
  735. ID int64 `json:"id"`
  736. State SchemaState `json:"state"`
  737. }
  738. // PartitionDefinition defines a single partition.
  739. type PartitionDefinition struct {
  740. ID int64 `json:"id"`
  741. Name CIStr `json:"name"`
  742. LessThan []string `json:"less_than"`
  743. InValues [][]string `json:"in_values"`
  744. Comment string `json:"comment,omitempty"`
  745. }
  746. // Clone clones ConstraintInfo.
  747. func (ci *PartitionDefinition) Clone() PartitionDefinition {
  748. nci := *ci
  749. nci.LessThan = make([]string, len(ci.LessThan))
  750. copy(nci.LessThan, ci.LessThan)
  751. return nci
  752. }
  753. // FindPartitionDefinitionByName finds PartitionDefinition by name.
  754. func (t *TableInfo) FindPartitionDefinitionByName(partitionDefinitionName string) *PartitionDefinition {
  755. lowConstrName := strings.ToLower(partitionDefinitionName)
  756. definitions := t.Partition.Definitions
  757. for i := range definitions {
  758. if definitions[i].Name.L == lowConstrName {
  759. return &t.Partition.Definitions[i]
  760. }
  761. }
  762. return nil
  763. }
  764. // IndexColumn provides index column info.
  765. type IndexColumn struct {
  766. Name CIStr `json:"name"` // Index name
  767. Offset int `json:"offset"` // Index offset
  768. // Length of prefix when using column prefix
  769. // for indexing;
  770. // UnspecifedLength if not using prefix indexing
  771. Length int `json:"length"`
  772. }
  773. // Clone clones IndexColumn.
  774. func (i *IndexColumn) Clone() *IndexColumn {
  775. ni := *i
  776. return &ni
  777. }
  778. // PrimaryKeyType is the type of primary key.
  779. // Available values are 'clustered', 'nonclustered', and ''(default).
  780. type PrimaryKeyType int8
  781. func (p PrimaryKeyType) String() string {
  782. switch p {
  783. case PrimaryKeyTypeClustered:
  784. return "CLUSTERED"
  785. case PrimaryKeyTypeNonClustered:
  786. return "NONCLUSTERED"
  787. default:
  788. return ""
  789. }
  790. }
  791. const (
  792. PrimaryKeyTypeDefault PrimaryKeyType = iota
  793. PrimaryKeyTypeClustered
  794. PrimaryKeyTypeNonClustered
  795. )
  796. // IndexType is the type of index
  797. type IndexType int
  798. // String implements Stringer interface.
  799. func (t IndexType) String() string {
  800. switch t {
  801. case IndexTypeBtree:
  802. return "BTREE"
  803. case IndexTypeHash:
  804. return "HASH"
  805. case IndexTypeRtree:
  806. return "RTREE"
  807. default:
  808. return ""
  809. }
  810. }
  811. // IndexTypes
  812. const (
  813. IndexTypeInvalid IndexType = iota
  814. IndexTypeBtree
  815. IndexTypeHash
  816. IndexTypeRtree
  817. )
  818. // IndexInfo provides meta data describing a DB index.
  819. // It corresponds to the statement `CREATE INDEX Name ON Table (Column);`
  820. // See https://dev.mysql.com/doc/refman/5.7/en/create-index.html
  821. type IndexInfo struct {
  822. ID int64 `json:"id"`
  823. Name CIStr `json:"idx_name"` // Index name.
  824. Table CIStr `json:"tbl_name"` // Table name.
  825. Columns []*IndexColumn `json:"idx_cols"` // Index columns.
  826. State SchemaState `json:"state"`
  827. Comment string `json:"comment"` // Comment
  828. Tp IndexType `json:"index_type"` // Index type: Btree, Hash or Rtree
  829. Unique bool `json:"is_unique"` // Whether the index is unique.
  830. Primary bool `json:"is_primary"` // Whether the index is primary key.
  831. Invisible bool `json:"is_invisible"` // Whether the index is invisible.
  832. Global bool `json:"is_global"` // Whether the index is global.
  833. }
  834. // Clone clones IndexInfo.
  835. func (index *IndexInfo) Clone() *IndexInfo {
  836. ni := *index
  837. ni.Columns = make([]*IndexColumn, len(index.Columns))
  838. for i := range index.Columns {
  839. ni.Columns[i] = index.Columns[i].Clone()
  840. }
  841. return &ni
  842. }
  843. // HasPrefixIndex returns whether any columns of this index uses prefix length.
  844. func (index *IndexInfo) HasPrefixIndex() bool {
  845. for _, ic := range index.Columns {
  846. if ic.Length != types.UnspecifiedLength {
  847. return true
  848. }
  849. }
  850. return false
  851. }
  852. // ConstraintInfo provides meta data describing check-expression constraint.
  853. type ConstraintInfo struct {
  854. ID int64 `json:"id"`
  855. Name CIStr `json:"constraint_name"`
  856. Table CIStr `json:"tbl_name"` // Table name.
  857. ConstraintCols []CIStr `json:"constraint_cols"` // Depended column names.
  858. Enforced bool `json:"enforced"`
  859. InColumn bool `json:"in_column"` // Indicate whether the constraint is column type check.
  860. ExprString string `json:"expr_string"`
  861. State SchemaState `json:"state"`
  862. }
  863. // Clone clones ConstraintInfo.
  864. func (ci *ConstraintInfo) Clone() *ConstraintInfo {
  865. nci := *ci
  866. nci.ConstraintCols = make([]CIStr, len(ci.ConstraintCols))
  867. copy(nci.ConstraintCols, ci.ConstraintCols)
  868. return &nci
  869. }
  870. // FindConstraintInfoByName finds constraintInfo by name.
  871. func (t *TableInfo) FindConstraintInfoByName(constrName string) *ConstraintInfo {
  872. lowConstrName := strings.ToLower(constrName)
  873. for _, chk := range t.Constraints {
  874. if chk.Name.L == lowConstrName {
  875. return chk
  876. }
  877. }
  878. return nil
  879. }
  880. // FKInfo provides meta data describing a foreign key constraint.
  881. type FKInfo struct {
  882. ID int64 `json:"id"`
  883. Name CIStr `json:"fk_name"`
  884. RefTable CIStr `json:"ref_table"`
  885. RefCols []CIStr `json:"ref_cols"`
  886. Cols []CIStr `json:"cols"`
  887. OnDelete int `json:"on_delete"`
  888. OnUpdate int `json:"on_update"`
  889. State SchemaState `json:"state"`
  890. }
  891. // Clone clones FKInfo.
  892. func (fk *FKInfo) Clone() *FKInfo {
  893. nfk := *fk
  894. nfk.RefCols = make([]CIStr, len(fk.RefCols))
  895. nfk.Cols = make([]CIStr, len(fk.Cols))
  896. copy(nfk.RefCols, fk.RefCols)
  897. copy(nfk.Cols, fk.Cols)
  898. return &nfk
  899. }
  900. // DBInfo provides meta data describing a DB.
  901. type DBInfo struct {
  902. ID int64 `json:"id"` // Database ID
  903. Name CIStr `json:"db_name"` // DB name.
  904. Charset string `json:"charset"`
  905. Collate string `json:"collate"`
  906. Tables []*TableInfo `json:"-"` // Tables in the DB.
  907. State SchemaState `json:"state"`
  908. }
  909. // Clone clones DBInfo.
  910. func (db *DBInfo) Clone() *DBInfo {
  911. newInfo := *db
  912. newInfo.Tables = make([]*TableInfo, len(db.Tables))
  913. for i := range db.Tables {
  914. newInfo.Tables[i] = db.Tables[i].Clone()
  915. }
  916. return &newInfo
  917. }
  918. // Copy shallow copies DBInfo.
  919. func (db *DBInfo) Copy() *DBInfo {
  920. newInfo := *db
  921. newInfo.Tables = make([]*TableInfo, len(db.Tables))
  922. copy(newInfo.Tables, db.Tables)
  923. return &newInfo
  924. }
  925. // CIStr is case insensitive string.
  926. type CIStr struct {
  927. O string `json:"O"` // Original string.
  928. L string `json:"L"` // Lower case string.
  929. }
  930. // String implements fmt.Stringer interface.
  931. func (cis CIStr) String() string {
  932. return cis.O
  933. }
  934. // NewCIStr creates a new CIStr.
  935. func NewCIStr(s string) (cs CIStr) {
  936. cs.O = s
  937. cs.L = strings.ToLower(s)
  938. return
  939. }
  940. // UnmarshalJSON implements the user defined unmarshal method.
  941. // CIStr can be unmarshaled from a single string, so PartitionDefinition.Name
  942. // in this change https://github.com/pingcap/tidb/pull/6460/files would be
  943. // compatible during TiDB upgrading.
  944. func (cis *CIStr) UnmarshalJSON(b []byte) error {
  945. type T CIStr
  946. if err := json.Unmarshal(b, (*T)(cis)); err == nil {
  947. return nil
  948. }
  949. // Unmarshal CIStr from a single string.
  950. err := json.Unmarshal(b, &cis.O)
  951. if err != nil {
  952. return errors.Trace(err)
  953. }
  954. cis.L = strings.ToLower(cis.O)
  955. return nil
  956. }
  957. // TableColumnID is composed by table ID and column ID.
  958. type TableColumnID struct {
  959. TableID int64
  960. ColumnID int64
  961. }