You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

641 lines
14 KiB

  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 ast
  14. import (
  15. "github.com/pingcap/tidb/model"
  16. "github.com/pingcap/tidb/util/types"
  17. )
  18. var (
  19. _ DDLNode = &AlterTableStmt{}
  20. _ DDLNode = &CreateDatabaseStmt{}
  21. _ DDLNode = &CreateIndexStmt{}
  22. _ DDLNode = &CreateTableStmt{}
  23. _ DDLNode = &DropDatabaseStmt{}
  24. _ DDLNode = &DropIndexStmt{}
  25. _ DDLNode = &DropTableStmt{}
  26. _ DDLNode = &TruncateTableStmt{}
  27. _ Node = &AlterTableSpec{}
  28. _ Node = &ColumnDef{}
  29. _ Node = &ColumnOption{}
  30. _ Node = &ColumnPosition{}
  31. _ Node = &Constraint{}
  32. _ Node = &IndexColName{}
  33. _ Node = &ReferenceDef{}
  34. )
  35. // CharsetOpt is used for parsing charset option from SQL.
  36. type CharsetOpt struct {
  37. Chs string
  38. Col string
  39. }
  40. // DatabaseOptionType is the type for database options.
  41. type DatabaseOptionType int
  42. // Database option types.
  43. const (
  44. DatabaseOptionNone DatabaseOptionType = iota
  45. DatabaseOptionCharset
  46. DatabaseOptionCollate
  47. )
  48. // DatabaseOption represents database option.
  49. type DatabaseOption struct {
  50. Tp DatabaseOptionType
  51. Value string
  52. }
  53. // CreateDatabaseStmt is a statement to create a database.
  54. // See: https://dev.mysql.com/doc/refman/5.7/en/create-database.html
  55. type CreateDatabaseStmt struct {
  56. ddlNode
  57. IfNotExists bool
  58. Name string
  59. Options []*DatabaseOption
  60. }
  61. // Accept implements Node Accept interface.
  62. func (n *CreateDatabaseStmt) Accept(v Visitor) (Node, bool) {
  63. newNode, skipChildren := v.Enter(n)
  64. if skipChildren {
  65. return v.Leave(newNode)
  66. }
  67. n = newNode.(*CreateDatabaseStmt)
  68. return v.Leave(n)
  69. }
  70. // DropDatabaseStmt is a statement to drop a database and all tables in the database.
  71. // See: https://dev.mysql.com/doc/refman/5.7/en/drop-database.html
  72. type DropDatabaseStmt struct {
  73. ddlNode
  74. IfExists bool
  75. Name string
  76. }
  77. // Accept implements Node Accept interface.
  78. func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) {
  79. newNode, skipChildren := v.Enter(n)
  80. if skipChildren {
  81. return v.Leave(newNode)
  82. }
  83. n = newNode.(*DropDatabaseStmt)
  84. return v.Leave(n)
  85. }
  86. // IndexColName is used for parsing index column name from SQL.
  87. type IndexColName struct {
  88. node
  89. Column *ColumnName
  90. Length int
  91. }
  92. // Accept implements Node Accept interface.
  93. func (n *IndexColName) Accept(v Visitor) (Node, bool) {
  94. newNode, skipChildren := v.Enter(n)
  95. if skipChildren {
  96. return v.Leave(newNode)
  97. }
  98. n = newNode.(*IndexColName)
  99. node, ok := n.Column.Accept(v)
  100. if !ok {
  101. return n, false
  102. }
  103. n.Column = node.(*ColumnName)
  104. return v.Leave(n)
  105. }
  106. // ReferenceDef is used for parsing foreign key reference option from SQL.
  107. // See: http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html
  108. type ReferenceDef struct {
  109. node
  110. Table *TableName
  111. IndexColNames []*IndexColName
  112. }
  113. // Accept implements Node Accept interface.
  114. func (n *ReferenceDef) Accept(v Visitor) (Node, bool) {
  115. newNode, skipChildren := v.Enter(n)
  116. if skipChildren {
  117. return v.Leave(newNode)
  118. }
  119. n = newNode.(*ReferenceDef)
  120. node, ok := n.Table.Accept(v)
  121. if !ok {
  122. return n, false
  123. }
  124. n.Table = node.(*TableName)
  125. for i, val := range n.IndexColNames {
  126. node, ok = val.Accept(v)
  127. if !ok {
  128. return n, false
  129. }
  130. n.IndexColNames[i] = node.(*IndexColName)
  131. }
  132. return v.Leave(n)
  133. }
  134. // ColumnOptionType is the type for ColumnOption.
  135. type ColumnOptionType int
  136. // ColumnOption types.
  137. const (
  138. ColumnOptionNoOption ColumnOptionType = iota
  139. ColumnOptionPrimaryKey
  140. ColumnOptionNotNull
  141. ColumnOptionAutoIncrement
  142. ColumnOptionDefaultValue
  143. ColumnOptionUniq
  144. ColumnOptionIndex
  145. ColumnOptionUniqIndex
  146. ColumnOptionKey
  147. ColumnOptionUniqKey
  148. ColumnOptionNull
  149. ColumnOptionOnUpdate // For Timestamp and Datetime only.
  150. ColumnOptionFulltext
  151. ColumnOptionComment
  152. )
  153. // ColumnOption is used for parsing column constraint info from SQL.
  154. type ColumnOption struct {
  155. node
  156. Tp ColumnOptionType
  157. // The value For Default or On Update.
  158. Expr ExprNode
  159. }
  160. // Accept implements Node Accept interface.
  161. func (n *ColumnOption) Accept(v Visitor) (Node, bool) {
  162. newNode, skipChildren := v.Enter(n)
  163. if skipChildren {
  164. return v.Leave(newNode)
  165. }
  166. n = newNode.(*ColumnOption)
  167. if n.Expr != nil {
  168. node, ok := n.Expr.Accept(v)
  169. if !ok {
  170. return n, false
  171. }
  172. n.Expr = node.(ExprNode)
  173. }
  174. return v.Leave(n)
  175. }
  176. // IndexOption is the index options.
  177. // KEY_BLOCK_SIZE [=] value
  178. // | index_type
  179. // | WITH PARSER parser_name
  180. // | COMMENT 'string'
  181. // See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
  182. type IndexOption struct {
  183. node
  184. KeyBlockSize uint64
  185. Tp model.IndexType
  186. Comment string
  187. }
  188. // Accept implements Node Accept interface.
  189. func (n *IndexOption) Accept(v Visitor) (Node, bool) {
  190. newNode, skipChildren := v.Enter(n)
  191. if skipChildren {
  192. return v.Leave(newNode)
  193. }
  194. n = newNode.(*IndexOption)
  195. return v.Leave(n)
  196. }
  197. // ConstraintType is the type for Constraint.
  198. type ConstraintType int
  199. // ConstraintTypes
  200. const (
  201. ConstraintNoConstraint ConstraintType = iota
  202. ConstraintPrimaryKey
  203. ConstraintKey
  204. ConstraintIndex
  205. ConstraintUniq
  206. ConstraintUniqKey
  207. ConstraintUniqIndex
  208. ConstraintForeignKey
  209. ConstraintFulltext
  210. )
  211. // Constraint is constraint for table definition.
  212. type Constraint struct {
  213. node
  214. Tp ConstraintType
  215. Name string
  216. // Used for PRIMARY KEY, UNIQUE, ......
  217. Keys []*IndexColName
  218. // Used for foreign key.
  219. Refer *ReferenceDef
  220. // Index Options
  221. Option *IndexOption
  222. }
  223. // Accept implements Node Accept interface.
  224. func (n *Constraint) Accept(v Visitor) (Node, bool) {
  225. newNode, skipChildren := v.Enter(n)
  226. if skipChildren {
  227. return v.Leave(newNode)
  228. }
  229. n = newNode.(*Constraint)
  230. for i, val := range n.Keys {
  231. node, ok := val.Accept(v)
  232. if !ok {
  233. return n, false
  234. }
  235. n.Keys[i] = node.(*IndexColName)
  236. }
  237. if n.Refer != nil {
  238. node, ok := n.Refer.Accept(v)
  239. if !ok {
  240. return n, false
  241. }
  242. n.Refer = node.(*ReferenceDef)
  243. }
  244. if n.Option != nil {
  245. node, ok := n.Option.Accept(v)
  246. if !ok {
  247. return n, false
  248. }
  249. n.Option = node.(*IndexOption)
  250. }
  251. return v.Leave(n)
  252. }
  253. // ColumnDef is used for parsing column definition from SQL.
  254. type ColumnDef struct {
  255. node
  256. Name *ColumnName
  257. Tp *types.FieldType
  258. Options []*ColumnOption
  259. }
  260. // Accept implements Node Accept interface.
  261. func (n *ColumnDef) Accept(v Visitor) (Node, bool) {
  262. newNode, skipChildren := v.Enter(n)
  263. if skipChildren {
  264. return v.Leave(newNode)
  265. }
  266. n = newNode.(*ColumnDef)
  267. node, ok := n.Name.Accept(v)
  268. if !ok {
  269. return n, false
  270. }
  271. n.Name = node.(*ColumnName)
  272. for i, val := range n.Options {
  273. node, ok := val.Accept(v)
  274. if !ok {
  275. return n, false
  276. }
  277. n.Options[i] = node.(*ColumnOption)
  278. }
  279. return v.Leave(n)
  280. }
  281. // CreateTableStmt is a statement to create a table.
  282. // See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html
  283. type CreateTableStmt struct {
  284. ddlNode
  285. IfNotExists bool
  286. Table *TableName
  287. Cols []*ColumnDef
  288. Constraints []*Constraint
  289. Options []*TableOption
  290. }
  291. // Accept implements Node Accept interface.
  292. func (n *CreateTableStmt) Accept(v Visitor) (Node, bool) {
  293. newNode, skipChildren := v.Enter(n)
  294. if skipChildren {
  295. return v.Leave(newNode)
  296. }
  297. n = newNode.(*CreateTableStmt)
  298. node, ok := n.Table.Accept(v)
  299. if !ok {
  300. return n, false
  301. }
  302. n.Table = node.(*TableName)
  303. for i, val := range n.Cols {
  304. node, ok = val.Accept(v)
  305. if !ok {
  306. return n, false
  307. }
  308. n.Cols[i] = node.(*ColumnDef)
  309. }
  310. for i, val := range n.Constraints {
  311. node, ok = val.Accept(v)
  312. if !ok {
  313. return n, false
  314. }
  315. n.Constraints[i] = node.(*Constraint)
  316. }
  317. return v.Leave(n)
  318. }
  319. // DropTableStmt is a statement to drop one or more tables.
  320. // See: https://dev.mysql.com/doc/refman/5.7/en/drop-table.html
  321. type DropTableStmt struct {
  322. ddlNode
  323. IfExists bool
  324. Tables []*TableName
  325. }
  326. // Accept implements Node Accept interface.
  327. func (n *DropTableStmt) Accept(v Visitor) (Node, bool) {
  328. newNode, skipChildren := v.Enter(n)
  329. if skipChildren {
  330. return v.Leave(newNode)
  331. }
  332. n = newNode.(*DropTableStmt)
  333. for i, val := range n.Tables {
  334. node, ok := val.Accept(v)
  335. if !ok {
  336. return n, false
  337. }
  338. n.Tables[i] = node.(*TableName)
  339. }
  340. return v.Leave(n)
  341. }
  342. // CreateIndexStmt is a statement to create an index.
  343. // See: https://dev.mysql.com/doc/refman/5.7/en/create-index.html
  344. type CreateIndexStmt struct {
  345. ddlNode
  346. IndexName string
  347. Table *TableName
  348. Unique bool
  349. IndexColNames []*IndexColName
  350. }
  351. // Accept implements Node Accept interface.
  352. func (n *CreateIndexStmt) Accept(v Visitor) (Node, bool) {
  353. newNode, skipChildren := v.Enter(n)
  354. if skipChildren {
  355. return v.Leave(newNode)
  356. }
  357. n = newNode.(*CreateIndexStmt)
  358. node, ok := n.Table.Accept(v)
  359. if !ok {
  360. return n, false
  361. }
  362. n.Table = node.(*TableName)
  363. for i, val := range n.IndexColNames {
  364. node, ok = val.Accept(v)
  365. if !ok {
  366. return n, false
  367. }
  368. n.IndexColNames[i] = node.(*IndexColName)
  369. }
  370. return v.Leave(n)
  371. }
  372. // DropIndexStmt is a statement to drop the index.
  373. // See: https://dev.mysql.com/doc/refman/5.7/en/drop-index.html
  374. type DropIndexStmt struct {
  375. ddlNode
  376. IfExists bool
  377. IndexName string
  378. Table *TableName
  379. }
  380. // Accept implements Node Accept interface.
  381. func (n *DropIndexStmt) Accept(v Visitor) (Node, bool) {
  382. newNode, skipChildren := v.Enter(n)
  383. if skipChildren {
  384. return v.Leave(newNode)
  385. }
  386. n = newNode.(*DropIndexStmt)
  387. node, ok := n.Table.Accept(v)
  388. if !ok {
  389. return n, false
  390. }
  391. n.Table = node.(*TableName)
  392. return v.Leave(n)
  393. }
  394. // TableOptionType is the type for TableOption
  395. type TableOptionType int
  396. // TableOption types.
  397. const (
  398. TableOptionNone TableOptionType = iota
  399. TableOptionEngine
  400. TableOptionCharset
  401. TableOptionCollate
  402. TableOptionAutoIncrement
  403. TableOptionComment
  404. TableOptionAvgRowLength
  405. TableOptionCheckSum
  406. TableOptionCompression
  407. TableOptionConnection
  408. TableOptionPassword
  409. TableOptionKeyBlockSize
  410. TableOptionMaxRows
  411. TableOptionMinRows
  412. TableOptionDelayKeyWrite
  413. TableOptionRowFormat
  414. )
  415. // RowFormat types
  416. const (
  417. RowFormatDefault uint64 = iota + 1
  418. RowFormatDynamic
  419. RowFormatFixed
  420. RowFormatCompressed
  421. RowFormatRedundant
  422. RowFormatCompact
  423. )
  424. // TableOption is used for parsing table option from SQL.
  425. type TableOption struct {
  426. Tp TableOptionType
  427. StrValue string
  428. UintValue uint64
  429. }
  430. // ColumnPositionType is the type for ColumnPosition.
  431. type ColumnPositionType int
  432. // ColumnPosition Types
  433. const (
  434. ColumnPositionNone ColumnPositionType = iota
  435. ColumnPositionFirst
  436. ColumnPositionAfter
  437. )
  438. // ColumnPosition represent the position of the newly added column
  439. type ColumnPosition struct {
  440. node
  441. // ColumnPositionNone | ColumnPositionFirst | ColumnPositionAfter
  442. Tp ColumnPositionType
  443. // RelativeColumn is the column the newly added column after if type is ColumnPositionAfter
  444. RelativeColumn *ColumnName
  445. }
  446. // Accept implements Node Accept interface.
  447. func (n *ColumnPosition) Accept(v Visitor) (Node, bool) {
  448. newNode, skipChildren := v.Enter(n)
  449. if skipChildren {
  450. return v.Leave(newNode)
  451. }
  452. n = newNode.(*ColumnPosition)
  453. if n.RelativeColumn != nil {
  454. node, ok := n.RelativeColumn.Accept(v)
  455. if !ok {
  456. return n, false
  457. }
  458. n.RelativeColumn = node.(*ColumnName)
  459. }
  460. return v.Leave(n)
  461. }
  462. // AlterTableType is the type for AlterTableSpec.
  463. type AlterTableType int
  464. // AlterTable types.
  465. const (
  466. AlterTableOption AlterTableType = iota + 1
  467. AlterTableAddColumn
  468. AlterTableAddConstraint
  469. AlterTableDropColumn
  470. AlterTableDropPrimaryKey
  471. AlterTableDropIndex
  472. AlterTableDropForeignKey
  473. // TODO: Add more actions
  474. )
  475. // AlterTableSpec represents alter table specification.
  476. type AlterTableSpec struct {
  477. node
  478. Tp AlterTableType
  479. Name string
  480. Constraint *Constraint
  481. Options []*TableOption
  482. Column *ColumnDef
  483. DropColumn *ColumnName
  484. Position *ColumnPosition
  485. }
  486. // Accept implements Node Accept interface.
  487. func (n *AlterTableSpec) Accept(v Visitor) (Node, bool) {
  488. newNode, skipChildren := v.Enter(n)
  489. if skipChildren {
  490. return v.Leave(newNode)
  491. }
  492. n = newNode.(*AlterTableSpec)
  493. if n.Constraint != nil {
  494. node, ok := n.Constraint.Accept(v)
  495. if !ok {
  496. return n, false
  497. }
  498. n.Constraint = node.(*Constraint)
  499. }
  500. if n.Column != nil {
  501. node, ok := n.Column.Accept(v)
  502. if !ok {
  503. return n, false
  504. }
  505. n.Column = node.(*ColumnDef)
  506. }
  507. if n.DropColumn != nil {
  508. node, ok := n.DropColumn.Accept(v)
  509. if !ok {
  510. return n, false
  511. }
  512. n.DropColumn = node.(*ColumnName)
  513. }
  514. if n.Position != nil {
  515. node, ok := n.Position.Accept(v)
  516. if !ok {
  517. return n, false
  518. }
  519. n.Position = node.(*ColumnPosition)
  520. }
  521. return v.Leave(n)
  522. }
  523. // AlterTableStmt is a statement to change the structure of a table.
  524. // See: https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
  525. type AlterTableStmt struct {
  526. ddlNode
  527. Table *TableName
  528. Specs []*AlterTableSpec
  529. }
  530. // Accept implements Node Accept interface.
  531. func (n *AlterTableStmt) Accept(v Visitor) (Node, bool) {
  532. newNode, skipChildren := v.Enter(n)
  533. if skipChildren {
  534. return v.Leave(newNode)
  535. }
  536. n = newNode.(*AlterTableStmt)
  537. node, ok := n.Table.Accept(v)
  538. if !ok {
  539. return n, false
  540. }
  541. n.Table = node.(*TableName)
  542. for i, val := range n.Specs {
  543. node, ok = val.Accept(v)
  544. if !ok {
  545. return n, false
  546. }
  547. n.Specs[i] = node.(*AlterTableSpec)
  548. }
  549. return v.Leave(n)
  550. }
  551. // TruncateTableStmt is a statement to empty a table completely.
  552. // See: https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html
  553. type TruncateTableStmt struct {
  554. ddlNode
  555. Table *TableName
  556. }
  557. // Accept implements Node Accept interface.
  558. func (n *TruncateTableStmt) Accept(v Visitor) (Node, bool) {
  559. newNode, skipChildren := v.Enter(n)
  560. if skipChildren {
  561. return v.Leave(newNode)
  562. }
  563. n = newNode.(*TruncateTableStmt)
  564. node, ok := n.Table.Accept(v)
  565. if !ok {
  566. return n, false
  567. }
  568. n.Table = node.(*TableName)
  569. return v.Leave(n)
  570. }