Skip to content

Commit

Permalink
[parser] parser: support check constraints field (pingcap#871)
Browse files Browse the repository at this point in the history
  • Loading branch information
AilinKid authored and ti-chi-bot committed Oct 9, 2021
1 parent 634e6d0 commit 07de176
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 14 deletions.
11 changes: 11 additions & 0 deletions parser/ast/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ type ColumnOption struct {
AutoRandomBitLength int
// Enforced is only for Check, default is true.
Enforced bool
// Name is only used for Check Constraint name.
ConstraintName string
}

// Restore implements Node interface.
Expand Down Expand Up @@ -534,6 +536,11 @@ func (n *ColumnOption) Restore(ctx *format.RestoreCtx) error {
ctx.WriteKeyWord("COLLATE ")
ctx.WritePlain(n.StrValue)
case ColumnOptionCheck:
if n.ConstraintName != "" {
ctx.WriteKeyWord("CONSTRAINT ")
ctx.WriteName(n.ConstraintName)
ctx.WritePlain(" ")
}
ctx.WriteKeyWord("CHECK")
ctx.WritePlain("(")
if err := n.Expr.Restore(ctx); err != nil {
Expand Down Expand Up @@ -702,6 +709,10 @@ type Constraint struct {
Expr ExprNode // Used for Check

Enforced bool // Used for Check

InColumn bool // Used for Check

InColumnName string // Used for Check
}

// Restore implements Node interface.
Expand Down
43 changes: 33 additions & 10 deletions parser/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,22 +212,24 @@ type TableInfo struct {
Charset string `json:"charset"`
Collate string `json:"collate"`
// Columns are listed in the order in which they appear in the schema.
Columns []*ColumnInfo `json:"cols"`
Indices []*IndexInfo `json:"index_info"`
ForeignKeys []*FKInfo `json:"fk_info"`
State SchemaState `json:"state"`
Columns []*ColumnInfo `json:"cols"`
Indices []*IndexInfo `json:"index_info"`
Constraints []*ConstraintInfo `json:"constraint_info"`
ForeignKeys []*FKInfo `json:"fk_info"`
State SchemaState `json:"state"`
// PKIsHandle is true when primary key is a single integer column.
PKIsHandle bool `json:"pk_is_handle"`
// IsCommonHandle is true when clustered index feature is
// enabled and the primary key is not a single integer column.
IsCommonHandle bool `json:"is_common_handle"`

Comment string `json:"comment"`
AutoIncID int64 `json:"auto_inc_id"`
AutoIdCache int64 `json:"auto_id_cache"`
AutoRandID int64 `json:"auto_rand_id"`
MaxColumnID int64 `json:"max_col_id"`
MaxIndexID int64 `json:"max_idx_id"`
Comment string `json:"comment"`
AutoIncID int64 `json:"auto_inc_id"`
AutoIdCache int64 `json:"auto_id_cache"`
AutoRandID int64 `json:"auto_rand_id"`
MaxColumnID int64 `json:"max_col_id"`
MaxIndexID int64 `json:"max_idx_id"`
MaxConstraintID int64 `json:"max_cst_id"`
// UpdateTS is used to record the timestamp of updating the table's schema information.
// These changing schema operations don't include 'truncate table' and 'rename table'.
UpdateTS uint64 `json:"update_timestamp"`
Expand Down Expand Up @@ -770,6 +772,27 @@ func (index *IndexInfo) HasPrefixIndex() bool {
return false
}

// ConstraintInfo provides meta data describing check-expression constraint.
type ConstraintInfo struct {
ID int64 `json:"id"`
Name CIStr `json:"constraint_name"`
Table CIStr `json:"tbl_name"` // Table name.
ConstraintCols []CIStr `json:"constraint_cols"` // Depended column names.
Enforced bool `json:"enforced"`
InColumn bool `json:"in_column"` // Indicate whether the constraint is column type check.
ExprString string `json:"expr_string"`
State SchemaState `json:"state"`
}

// Clone clones ConstraintInfo.
func (ci *ConstraintInfo) Clone() *ConstraintInfo {
nci := *ci

nci.ConstraintCols = make([]CIStr, len(ci.ConstraintCols))
copy(nci.ConstraintCols, ci.ConstraintCols)
return &nci
}

// FKInfo provides meta data describing a foreign key constraint.
type FKInfo struct {
ID int64 `json:"id"`
Expand Down
4 changes: 4 additions & 0 deletions parser/parser.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -2577,6 +2577,10 @@ ColumnOption:
Expr: $4,
Enforced: true,
}
// Keep the column type check constraint name.
if $1 != nil {
optionCheck.ConstraintName = $1.(string)
}
switch $6.(int) {
case 0:
$$ = []*ast.ColumnOption{optionCheck, {Tp: ast.ColumnOptionNotNull}}
Expand Down
8 changes: 4 additions & 4 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2822,11 +2822,11 @@ func (s *testParserSuite) TestDDL(c *C) {
{"ALTER TABLE ident ADD ( CONSTRAINT FOREIGN KEY ident ( EXECUTE ( 123 ) ) REFERENCES t ( a ) MATCH SIMPLE ON DELETE CASCADE ON UPDATE SET NULL )", true, "ALTER TABLE `ident` ADD COLUMN (CONSTRAINT `ident` FOREIGN KEY (`EXECUTE`(123)) REFERENCES `t`(`a`) MATCH SIMPLE ON DELETE CASCADE ON UPDATE SET NULL)"},
// for CONSTRAINT cont'd, the following tests are for another aspect of the incompatibility
{"ALTER TABLE t ADD COLUMN a DATE CHECK ( a > 0 ) FIRST", true, "ALTER TABLE `t` ADD COLUMN `a` DATE CHECK(`a`>0) ENFORCED FIRST"},
{"ALTER TABLE t ADD a1 int CONSTRAINT ident CHECK ( a1 > 1 ) REFERENCES b ON DELETE CASCADE ON UPDATE CASCADE;", true, "ALTER TABLE `t` ADD COLUMN `a1` INT CHECK(`a1`>1) ENFORCED REFERENCES `b` ON DELETE CASCADE ON UPDATE CASCADE"},
{"ALTER TABLE t ADD a1 int CONSTRAINT ident CHECK ( a1 > 1 ) REFERENCES b ON DELETE CASCADE ON UPDATE CASCADE;", true, "ALTER TABLE `t` ADD COLUMN `a1` INT CONSTRAINT `ident` CHECK(`a1`>1) ENFORCED REFERENCES `b` ON DELETE CASCADE ON UPDATE CASCADE"},
{"ALTER TABLE t ADD COLUMN a DATE CONSTRAINT CHECK ( a > 0 ) FIRST", true, "ALTER TABLE `t` ADD COLUMN `a` DATE CHECK(`a`>0) ENFORCED FIRST"},
{"ALTER TABLE t ADD a TINYBLOB CONSTRAINT ident CHECK ( 1>2 ) REFERENCES b ON DELETE CASCADE ON UPDATE CASCADE", true, "ALTER TABLE `t` ADD COLUMN `a` TINYBLOB CHECK(1>2) ENFORCED REFERENCES `b` ON DELETE CASCADE ON UPDATE CASCADE"},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident CHECK (a2 > 1) ENFORCED", true, "ALTER TABLE `t` ADD COLUMN `a2` INT CHECK(`a2`>1) ENFORCED"},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident CHECK (a2 > 1) NOT ENFORCED", true, "ALTER TABLE `t` ADD COLUMN `a2` INT CHECK(`a2`>1) NOT ENFORCED"},
{"ALTER TABLE t ADD a TINYBLOB CONSTRAINT ident CHECK ( 1>2 ) REFERENCES b ON DELETE CASCADE ON UPDATE CASCADE", true, "ALTER TABLE `t` ADD COLUMN `a` TINYBLOB CONSTRAINT `ident` CHECK(1>2) ENFORCED REFERENCES `b` ON DELETE CASCADE ON UPDATE CASCADE"},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident CHECK (a2 > 1) ENFORCED", true, "ALTER TABLE `t` ADD COLUMN `a2` INT CONSTRAINT `ident` CHECK(`a2`>1) ENFORCED"},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident CHECK (a2 > 1) NOT ENFORCED", true, "ALTER TABLE `t` ADD COLUMN `a2` INT CONSTRAINT `ident` CHECK(`a2`>1) NOT ENFORCED"},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident primary key REFERENCES b ON DELETE CASCADE ON UPDATE CASCADE;", false, ""},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident primary key (a2))", false, ""},
{"ALTER TABLE t ADD a2 int CONSTRAINT ident unique key (a2))", false, ""},
Expand Down

0 comments on commit 07de176

Please sign in to comment.