forked from pingcap/tidb
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.go
169 lines (152 loc) · 5.71 KB
/
index.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// 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"
)
// DistanceMetric is the distance metric used by the vector index.
// `DistanceMetric` is actually vector functions in ast package. Use `DistanceMetric` to avoid cycle dependency
type DistanceMetric string
// Note: tipb.VectorDistanceMetric's enum names must be aligned with these constant values.
const (
DistanceMetricL2 DistanceMetric = "L2"
// DistanceMetricCosine is cosine distance.
DistanceMetricCosine DistanceMetric = "COSINE"
// DistanceMetricInnerProduct is inner product.
DistanceMetricInnerProduct DistanceMetric = "INNER_PRODUCT"
)
// VectorIndexInfo is the information of vector index of a column.
type VectorIndexInfo struct {
// Dimension is the dimension of the vector.
Dimension uint64 `json:"dimension"` // Set to 0 when initially parsed from comment. Will be assigned to flen later.
// DistanceMetric is the distance metric used by the index.
DistanceMetric DistanceMetric `json:"distance_metric"`
}
// 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.
VectorInfo *VectorIndexInfo `json:"vector_index"` // VectorInfo is the vector index information.
}
// 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
}