Skip to content

Commit

Permalink
ddl: expose getPrimaryKey() as a public method of model.TableInfo (#3…
Browse files Browse the repository at this point in the history
  • Loading branch information
crelax committed Jun 20, 2022
1 parent cd731af commit cd690e3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 49 deletions.
50 changes: 1 addition & 49 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1628,61 +1628,13 @@ func checkInvisibleIndexOnPK(tblInfo *model.TableInfo) error {
if tblInfo.PKIsHandle {
return nil
}
pk := getPrimaryKey(tblInfo)
pk := tblInfo.GetPrimaryKey()
if pk != nil && pk.Invisible {
return dbterror.ErrPKIndexCantBeInvisible
}
return nil
}

// getPrimaryKey extract the primary key in a table and return `IndexInfo`
// The returned primary key could be explicit or implicit.
// If there is no explicit primary key in table,
// the first UNIQUE INDEX on NOT NULL columns will be the implicit primary key.
// For more information about implicit primary key, see
// https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
func getPrimaryKey(tblInfo *model.TableInfo) *model.IndexInfo {
var implicitPK *model.IndexInfo

for _, key := range tblInfo.Indices {
if key.Primary {
// table has explicit primary key
return key
}
// The case index without any columns should never happen, but still do a check here
if len(key.Columns) == 0 {
continue
}
// find the first unique key with NOT NULL columns
if implicitPK == nil && key.Unique {
// ensure all columns in unique key have NOT NULL flag
allColNotNull := true
skip := false
for _, idxCol := range key.Columns {
col := model.FindColumnInfo(tblInfo.Cols(), idxCol.Name.L)
// This index has a column in DeleteOnly state,
// or it is expression index (it defined on a hidden column),
// it can not be implicit PK, go to next index iterator
if col == nil || col.Hidden {
skip = true
break
}
if !mysql.HasNotNullFlag(col.GetFlag()) {
allColNotNull = false
break
}
}
if skip {
continue
}
if allColNotNull {
implicitPK = key
}
}
}
return implicitPK
}

func setTableAutoRandomBits(ctx sessionctx.Context, tbInfo *model.TableInfo, colDefs []*ast.ColumnDef) error {
pkColName := tbInfo.GetPkName()
for _, col := range colDefs {
Expand Down
48 changes: 48 additions & 0 deletions parser/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,54 @@ func NewExtraPhysTblIDColInfo() *ColumnInfo {
return colInfo
}

// GetPrimaryKey extract the primary key in a table and return `IndexInfo`
// The returned primary key could be explicit or implicit.
// If there is no explicit primary key in table,
// the first UNIQUE INDEX on NOT NULL columns will be the implicit primary key.
// For more information about implicit primary key, see
// https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
func (t *TableInfo) GetPrimaryKey() *IndexInfo {
var implicitPK *IndexInfo

for _, key := range t.Indices {
if key.Primary {
// table has explicit primary key
return key
}
// The case index without any columns should never happen, but still do a check here
if len(key.Columns) == 0 {
continue
}
// find the first unique key with NOT NULL columns
if implicitPK == nil && key.Unique {
// ensure all columns in unique key have NOT NULL flag
allColNotNull := true
skip := false
for _, idxCol := range key.Columns {
col := FindColumnInfo(t.Cols(), idxCol.Name.L)
// This index has a column in DeleteOnly state,
// or it is expression index (it defined on a hidden column),
// it can not be implicit PK, go to next index iterator
if col == nil || col.Hidden {
skip = true
break
}
if !mysql.HasNotNullFlag(col.GetFlag()) {
allColNotNull = false
break
}
}
if skip {
continue
}
if allColNotNull {
implicitPK = key
}
}
}
return implicitPK
}

// ColumnIsInIndex checks whether c is included in any indices of t.
func (t *TableInfo) ColumnIsInIndex(c *ColumnInfo) bool {
for _, index := range t.Indices {
Expand Down

0 comments on commit cd690e3

Please sign in to comment.