148 lines
4.7 KiB
Go
148 lines
4.7 KiB
Go
// Copyright 2024 PingCAP, 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 agreed to 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 model
|
|
|
|
import (
|
|
"github.com/pingcap/tidb/pkg/parser/model"
|
|
"github.com/pingcap/tidb/pkg/parser/types"
|
|
)
|
|
|
|
// IndexInfo provides meta data describing a DB index.
|
|
// It corresponds to the statement `CREATE INDEX Name ON Table (Column);`
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/create-index.html
|
|
type IndexInfo struct {
|
|
ID int64 `json:"id"`
|
|
Name model.CIStr `json:"idx_name"` // Index name.
|
|
Table model.CIStr `json:"tbl_name"` // Table name.
|
|
Columns []*IndexColumn `json:"idx_cols"` // Index columns.
|
|
State SchemaState `json:"state"`
|
|
BackfillState BackfillState `json:"backfill_state"`
|
|
Comment string `json:"comment"` // Comment
|
|
Tp model.IndexType `json:"index_type"` // Index type: Btree, Hash or Rtree
|
|
Unique bool `json:"is_unique"` // Whether the index is unique.
|
|
Primary bool `json:"is_primary"` // Whether the index is primary key.
|
|
Invisible bool `json:"is_invisible"` // Whether the index is invisible.
|
|
Global bool `json:"is_global"` // Whether the index is global.
|
|
MVIndex bool `json:"mv_index"` // Whether the index is multivalued index.
|
|
}
|
|
|
|
// Clone clones IndexInfo.
|
|
func (index *IndexInfo) Clone() *IndexInfo {
|
|
if index == nil {
|
|
return nil
|
|
}
|
|
ni := *index
|
|
ni.Columns = make([]*IndexColumn, len(index.Columns))
|
|
for i := range index.Columns {
|
|
ni.Columns[i] = index.Columns[i].Clone()
|
|
}
|
|
return &ni
|
|
}
|
|
|
|
// HasPrefixIndex returns whether any columns of this index uses prefix length.
|
|
func (index *IndexInfo) HasPrefixIndex() bool {
|
|
for _, ic := range index.Columns {
|
|
if ic.Length != types.UnspecifiedLength {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HasColumnInIndexColumns checks whether the index contains the column with the specified ID.
|
|
func (index *IndexInfo) HasColumnInIndexColumns(tblInfo *TableInfo, colID int64) bool {
|
|
for _, ic := range index.Columns {
|
|
if tblInfo.Columns[ic.Offset].ID == colID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// FindColumnByName finds the index column with the specified name.
|
|
func (index *IndexInfo) FindColumnByName(nameL string) *IndexColumn {
|
|
_, ret := FindIndexColumnByName(index.Columns, nameL)
|
|
return ret
|
|
}
|
|
|
|
// IsPublic checks if the index state is public
|
|
func (index *IndexInfo) IsPublic() bool {
|
|
return index.State == StatePublic
|
|
}
|
|
|
|
// FindIndexByColumns find IndexInfo in indices which is cover the specified columns.
|
|
func FindIndexByColumns(tbInfo *TableInfo, indices []*IndexInfo, cols ...model.CIStr) *IndexInfo {
|
|
for _, index := range indices {
|
|
if IsIndexPrefixCovered(tbInfo, index, cols...) {
|
|
return index
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IsIndexPrefixCovered checks the index's columns beginning with the cols.
|
|
func IsIndexPrefixCovered(tbInfo *TableInfo, index *IndexInfo, cols ...model.CIStr) bool {
|
|
if len(index.Columns) < len(cols) {
|
|
return false
|
|
}
|
|
for i := range cols {
|
|
if cols[i].L != index.Columns[i].Name.L ||
|
|
index.Columns[i].Offset >= len(tbInfo.Columns) {
|
|
return false
|
|
}
|
|
colInfo := tbInfo.Columns[index.Columns[i].Offset]
|
|
if index.Columns[i].Length != types.UnspecifiedLength && index.Columns[i].Length < colInfo.GetFlen() {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// FindIndexInfoByID finds IndexInfo in indices by id.
|
|
func FindIndexInfoByID(indices []*IndexInfo, id int64) *IndexInfo {
|
|
for _, idx := range indices {
|
|
if idx.ID == id {
|
|
return idx
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IndexColumn provides index column info.
|
|
type IndexColumn struct {
|
|
Name model.CIStr `json:"name"` // Index name
|
|
Offset int `json:"offset"` // Index offset
|
|
// Length of prefix when using column prefix
|
|
// for indexing;
|
|
// UnspecifedLength if not using prefix indexing
|
|
Length int `json:"length"`
|
|
}
|
|
|
|
// Clone clones IndexColumn.
|
|
func (i *IndexColumn) Clone() *IndexColumn {
|
|
ni := *i
|
|
return &ni
|
|
}
|
|
|
|
// FindIndexColumnByName finds IndexColumn by name. When IndexColumn is not found, returns (-1, nil).
|
|
func FindIndexColumnByName(indexCols []*IndexColumn, nameL string) (int, *IndexColumn) {
|
|
for i, ic := range indexCols {
|
|
if ic.Name.L == nameL {
|
|
return i, ic
|
|
}
|
|
}
|
|
return -1, nil
|
|
}
|