Skip to content

Commit 351445e

Browse files
authored
*: Support building FULLTEXT index (#60720)
ref #1793
1 parent c489679 commit 351445e

33 files changed

+754
-102
lines changed

DEPS.bzl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5919,13 +5919,13 @@ def go_deps():
59195919
name = "com_github_pingcap_tipb",
59205920
build_file_proto_mode = "disable_global",
59215921
importpath = "github.com/pingcap/tipb",
5922-
sha256 = "756470e7747a804ac9ba74c96b7b79174a1ef986d2c8aab416b163c2f721d893",
5923-
strip_prefix = "github.com/pingcap/[email protected]20250331100511-d2c561dad347",
5922+
sha256 = "5bffa36fa7e42bca9b6de7ba2536f64f5482be1104c838dda78b9beff550942d",
5923+
strip_prefix = "github.com/pingcap/[email protected]20250401143359-775c2379cbc7",
59245924
urls = [
5925-
"http://bazel-cache.pingcap.net:8080/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250331100511-d2c561dad347.zip",
5926-
"http://ats.apps.svc/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250331100511-d2c561dad347.zip",
5927-
"https://cache.hawkingrei.com/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250331100511-d2c561dad347.zip",
5928-
"https://storage.googleapis.com/pingcapmirror/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250331100511-d2c561dad347.zip",
5925+
"http://bazel-cache.pingcap.net:8080/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250401143359-775c2379cbc7.zip",
5926+
"http://ats.apps.svc/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250401143359-775c2379cbc7.zip",
5927+
"https://cache.hawkingrei.com/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250401143359-775c2379cbc7.zip",
5928+
"https://storage.googleapis.com/pingcapmirror/gomod/github.com/pingcap/tipb/com_github_pingcap_tipb-v0.0.0-20250401143359-775c2379cbc7.zip",
59295929
],
59305930
)
59315931
go_repository(

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ require (
9292
github.com/pingcap/log v1.1.1-0.20241212030209-7e3ff8601a2a
9393
github.com/pingcap/sysutil v1.0.1-0.20240311050922-ae81ee01f3a5
9494
github.com/pingcap/tidb/pkg/parser v0.0.0-20211011031125-9b13dc409c5e
95-
github.com/pingcap/tipb v0.0.0-20250331100511-d2c561dad347
95+
github.com/pingcap/tipb v0.0.0-20250401143359-775c2379cbc7
9696
github.com/prometheus/client_golang v1.22.0
9797
github.com/prometheus/client_model v0.6.2
9898
github.com/prometheus/common v0.63.0
@@ -316,7 +316,7 @@ require (
316316
google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect
317317
google.golang.org/protobuf v1.36.6
318318
gopkg.in/inf.v0 v0.9.1 // indirect
319-
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
319+
gopkg.in/natefinch/lumberjack.v2 v2.2.1
320320
gopkg.in/yaml.v3 v3.0.1 // indirect
321321
k8s.io/apimachinery v0.29.11 // indirect
322322
k8s.io/klog/v2 v2.120.1 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,8 @@ github.com/pingcap/log v1.1.1-0.20241212030209-7e3ff8601a2a h1:WIhmJBlNGmnCWH6TL
689689
github.com/pingcap/log v1.1.1-0.20241212030209-7e3ff8601a2a/go.mod h1:ORfBOFp1eteu2odzsyaxI+b8TzJwgjwyQcGhI+9SfEA=
690690
github.com/pingcap/sysutil v1.0.1-0.20240311050922-ae81ee01f3a5 h1:T4pXRhBflzDeAhmOQHNPRRogMYxP13V7BkYw3ZsoSfE=
691691
github.com/pingcap/sysutil v1.0.1-0.20240311050922-ae81ee01f3a5/go.mod h1:rlimy0GcTvjiJqvD5mXTRr8O2eNZPBrcUgiWVYp9530=
692-
github.com/pingcap/tipb v0.0.0-20250331100511-d2c561dad347 h1:PAeUQaG0EEugM2fVlMPYPzrJPOY5uvvi082VJKMadCQ=
693-
github.com/pingcap/tipb v0.0.0-20250331100511-d2c561dad347/go.mod h1:zrnYy8vReNODg8G0OiYaX9OK+kpq+rK1jHmvd1DnIWw=
692+
github.com/pingcap/tipb v0.0.0-20250401143359-775c2379cbc7 h1:iRRoPMrpj4jkIzhMT+yabc98bhGeUzAFSjh5HUOn5Yg=
693+
github.com/pingcap/tipb v0.0.0-20250401143359-775c2379cbc7/go.mod h1:zrnYy8vReNODg8G0OiYaX9OK+kpq+rK1jHmvd1DnIWw=
694694
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
695695
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
696696
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=

pkg/ddl/cancel_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,19 @@ var allTestCase = []testCancelJob{
7474
{"alter table t drop index v_idx_2", false, model.StateWriteOnly, true, false, []string{"alter table t add vector index v_idx_2((VEC_COSINE_DISTANCE(v2))) USING HNSW"}},
7575
{"alter table t drop index v_idx_3", false, model.StateDeleteOnly, false, true, []string{"alter table t add vector index v_idx_3((VEC_COSINE_DISTANCE(v2))) USING HNSW"}},
7676
{"alter table t drop index v_idx_4", false, model.StateDeleteReorganization, false, true, []string{"alter table t add vector index v_idx_4((VEC_COSINE_DISTANCE(v2))) USING HNSW"}},
77+
// Drop full text index
78+
{"alter table t drop index fts_idx_2", false, model.StateWriteOnly, true, false, []string{"alter table t add fulltext index fts_idx_2(ctxt)"}},
79+
{"alter table t drop index fts_idx_3", false, model.StateDeleteOnly, false, true, []string{"alter table t add fulltext index fts_idx_3(ctxt)"}},
80+
{"alter table t drop index fts_idx_4", false, model.StateDeleteReorganization, false, true, []string{"alter table t add fulltext index fts_idx_4(ctxt)"}},
7781
// Add vector index
7882
{"alter table t add vector index v_idx((VEC_COSINE_DISTANCE(v2))) USING HNSW", true, model.StateNone, true, false, nil},
7983
{"alter table t add vector index v_idx((VEC_COSINE_DISTANCE(v2))) USING HNSW", true, model.StateDeleteOnly, true, true, nil},
8084
{"alter table t add vector index v_idx((VEC_COSINE_DISTANCE(v2))) USING HNSW", true, model.StateWriteOnly, true, true, nil},
85+
// Add full text index
86+
{"alter table t add fulltext index fts_idx(ctxt)", true, model.StateNone, true, false, nil},
87+
{"alter table t add fulltext index fts_idx(ctxt)", true, model.StateDeleteOnly, true, true, nil},
88+
{"alter table t add fulltext index fts_idx(ctxt)", true, model.StateWriteOnly, true, true, nil},
89+
{"alter table t add fulltext index fts_idx_x(ctxt)", false, model.StatePublic, false, true, nil},
8190
// Add columnar index
8291
{"alter table t add columnar index c_idx(c1) USING INVERTED", true, model.StateNone, true, false, nil},
8392
{"alter table t add columnar index c_idx(c2) USING INVERTED", true, model.StateDeleteOnly, true, true, nil},
@@ -257,7 +266,7 @@ func TestCancelVariousJobs(t *testing.T) {
257266
partition p4 values less than (7096)
258267
);`)
259268
tk.MustExec(`create table t (
260-
c1 int, c2 int, c3 int, c11 tinyint, v2 vector(3), index fk_c1(c1)
269+
c1 int, c2 int, c3 int, c11 tinyint, v2 vector(3), index fk_c1(c1), ctxt TEXT
261270
);`)
262271
tk.MustExec("alter table t set tiflash replica 2 location labels 'a','b';")
263272

pkg/ddl/create_table.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,11 +1301,6 @@ func BuildTableInfo(
13011301
}
13021302
}
13031303

1304-
if constr.Tp == ast.ConstraintFulltext {
1305-
ctx.AppendWarning(dbterror.ErrTableCantHandleFt.FastGenByArgs())
1306-
continue
1307-
}
1308-
13091304
var (
13101305
indexName = constr.Name
13111306
primary, unique bool
@@ -1326,6 +1321,8 @@ func BuildTableInfo(
13261321
columnarIndexType = model.ColumnarIndexTypeVector
13271322
case ast.IndexTypeInverted:
13281323
columnarIndexType = model.ColumnarIndexTypeInverted
1324+
case ast.IndexTypeFulltext:
1325+
columnarIndexType = model.ColumnarIndexTypeFulltext
13291326
default:
13301327
return nil, dbterror.ErrUnsupportedIndexType.GenWithStackByArgs(constr.Option.Tp)
13311328
}

pkg/ddl/executor.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,8 +1814,6 @@ func (e *executor) AlterTable(ctx context.Context, sctx sessionctx.Context, stmt
18141814
err = e.CreateForeignKey(sctx, ident, ast.NewCIStr(constr.Name), spec.Constraint.Keys, spec.Constraint.Refer)
18151815
case ast.ConstraintPrimaryKey:
18161816
err = e.CreatePrimaryKey(sctx, ident, ast.NewCIStr(constr.Name), spec.Constraint.Keys, constr.Option)
1817-
case ast.ConstraintFulltext:
1818-
sctx.GetSessionVars().StmtCtx.AppendWarning(dbterror.ErrTableCantHandleFt)
18191817
case ast.ConstraintCheck:
18201818
if !vardef.EnableCheckConstraint.Load() {
18211819
sctx.GetSessionVars().StmtCtx.AppendWarning(errCheckConstraintIsOff)
@@ -4015,7 +4013,7 @@ func checkIndexLengthWithNewCharset(tblInfo *model.TableInfo, toCharset, toColla
40154013
}
40164014

40174015
for _, indexInfo := range tblInfo.Indices {
4018-
err := checkIndexPrefixLength(columns, indexInfo.Columns)
4016+
err := checkIndexPrefixLength(columns, indexInfo.Columns, indexInfo.GetColumnarIndexType())
40194017
if err != nil {
40204018
return err
40214019
}
@@ -4738,7 +4736,7 @@ func checkTableTypeForColumnarIndex(tblInfo *model.TableInfo) error {
47384736
return dbterror.ErrUnsupportedAddColumnarIndex.FastGenByArgs("unsupported partition table")
47394737
}
47404738
if tblInfo.TiFlashReplica == nil || tblInfo.TiFlashReplica.Count == 0 {
4741-
return dbterror.ErrUnsupportedAddColumnarIndex.FastGenByArgs("unsupported empty TiFlash replica, the replica is nil")
4739+
return dbterror.ErrUnsupportedAddColumnarIndex.FastGenByArgs("columnar replica must exist to create vector index, columnar index or fulltext index")
47424740
}
47434741

47444742
return nil
@@ -4762,6 +4760,8 @@ func (e *executor) createColumnarIndex(ctx sessionctx.Context, ti ast.Ident, ind
47624760
columnarIndexType = model.ColumnarIndexTypeInverted
47634761
case ast.IndexTypeVector:
47644762
columnarIndexType = model.ColumnarIndexTypeVector
4763+
case ast.IndexTypeFulltext:
4764+
columnarIndexType = model.ColumnarIndexTypeFulltext
47654765
default:
47664766
return dbterror.ErrUnsupportedIndexType.GenWithStackByArgs(indexOption.Tp)
47674767
}
@@ -4783,6 +4783,10 @@ func (e *executor) createColumnarIndex(ctx sessionctx.Context, ti ast.Ident, ind
47834783
if _, funcExpr, err = buildVectorInfoWithCheck(indexPartSpecifications, tblInfo); err != nil {
47844784
return errors.Trace(err)
47854785
}
4786+
case model.ColumnarIndexTypeFulltext:
4787+
if _, err = buildFullTextInfoWithCheck(indexPartSpecifications, indexOption, tblInfo); err != nil {
4788+
return errors.Trace(err)
4789+
}
47864790
}
47874791

47884792
// Check before the job is put to the queue.
@@ -4879,8 +4883,8 @@ func (e *executor) createIndex(ctx sessionctx.Context, ti ast.Ident, keyType ast
48794883
indexPartSpecifications []*ast.IndexPartSpecification, indexOption *ast.IndexOption, ifNotExists bool) error {
48804884
// not support Spatial and FullText index
48814885
switch keyType {
4882-
case ast.IndexKeyTypeFullText, ast.IndexKeyTypeSpatial:
4883-
return dbterror.ErrUnsupportedIndexType.GenWithStack("FULLTEXT and SPATIAL index is not supported")
4886+
case ast.IndexKeyTypeSpatial:
4887+
return dbterror.ErrUnsupportedIndexType.GenWithStack("SPATIAL index is not supported")
48844888
case ast.IndexKeyTypeColumnar:
48854889
return e.createColumnarIndex(ctx, ti, indexName, indexPartSpecifications, indexOption, ifNotExists)
48864890
}

pkg/ddl/index.go

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,15 @@ func buildIndexColumns(ctx *metabuild.Context, columns []*model.ColumnInfo, inde
110110
if columnarIndexType == model.ColumnarIndexTypeInverted && !types.IsTypeStoredAsInteger(col.FieldType.GetType()) {
111111
return nil, false, dbterror.ErrUnsupportedAddColumnarIndex.FastGenByArgs(fmt.Sprintf("only support integer type, but this is type: %s", col.FieldType.String()))
112112
}
113+
if columnarIndexType == model.ColumnarIndexTypeFulltext && !types.IsString(col.FieldType.GetType()) {
114+
return nil, false, dbterror.ErrUnsupportedAddColumnarIndex.FastGenByArgs(fmt.Sprintf("only support string type, but this is type: %s", col.FieldType.String()))
115+
}
113116

114117
// return error in strict sql mode
115-
if err := checkIndexColumn(col, ip.Length, ctx != nil && (!ctx.GetSQLMode().HasStrictMode() || ctx.SuppressTooLongIndexErr()), columnarIndexType); err != nil {
116-
return nil, false, err
118+
if columnarIndexType == model.ColumnarIndexTypeNA {
119+
if err := checkIndexColumn(col, ip.Length, ctx != nil && (!ctx.GetSQLMode().HasStrictMode() || ctx.SuppressTooLongIndexErr())); err != nil {
120+
return nil, false, err
121+
}
117122
}
118123
if col.FieldType.IsArray() {
119124
if mvIndex {
@@ -127,7 +132,7 @@ func buildIndexColumns(ctx *metabuild.Context, columns []*model.ColumnInfo, inde
127132
indexColLen == col.FieldType.GetFlen() {
128133
indexColLen = types.UnspecifiedLength
129134
}
130-
indexColumnLength, err := getIndexColumnLength(col, indexColLen)
135+
indexColumnLength, err := getIndexColumnLength(col, indexColLen, columnarIndexType)
131136
if err != nil {
132137
return nil, false, err
133138
}
@@ -142,7 +147,7 @@ func buildIndexColumns(ctx *metabuild.Context, columns []*model.ColumnInfo, inde
142147
return nil, false, dbterror.ErrTooLongKey.GenWithStackByArgs(sumLength, maxIndexLength)
143148
}
144149
// truncate index length and produce warning message in non-restrict sql mode.
145-
colLenPerUint, err := getIndexColumnLength(col, 1)
150+
colLenPerUint, err := getIndexColumnLength(col, 1, columnarIndexType)
146151
if err != nil {
147152
return nil, false, err
148153
}
@@ -181,8 +186,8 @@ func CheckPKOnGeneratedColumn(tblInfo *model.TableInfo, indexPartSpecifications
181186
return lastCol, nil
182187
}
183188

184-
func checkIndexPrefixLength(columns []*model.ColumnInfo, idxColumns []*model.IndexColumn) error {
185-
idxLen, err := indexColumnsLen(columns, idxColumns)
189+
func checkIndexPrefixLength(columns []*model.ColumnInfo, idxColumns []*model.IndexColumn, columnarIndexType model.ColumnarIndexType) error {
190+
idxLen, err := indexColumnsLen(columns, idxColumns, columnarIndexType)
186191
if err != nil {
187192
return err
188193
}
@@ -192,15 +197,15 @@ func checkIndexPrefixLength(columns []*model.ColumnInfo, idxColumns []*model.Ind
192197
return nil
193198
}
194199

195-
func indexColumnsLen(cols []*model.ColumnInfo, idxCols []*model.IndexColumn) (colLen int, err error) {
200+
func indexColumnsLen(cols []*model.ColumnInfo, idxCols []*model.IndexColumn, columnarIndexType model.ColumnarIndexType) (colLen int, err error) {
196201
for _, idxCol := range idxCols {
197202
col := model.FindColumnInfo(cols, idxCol.Name.L)
198203
if col == nil {
199204
err = dbterror.ErrKeyColumnDoesNotExits.GenWithStack("column does not exist: %s", idxCol.Name.L)
200205
return
201206
}
202207
var l int
203-
l, err = getIndexColumnLength(col, idxCol.Length)
208+
l, err = getIndexColumnLength(col, idxCol.Length, columnarIndexType)
204209
if err != nil {
205210
return
206211
}
@@ -209,7 +214,8 @@ func indexColumnsLen(cols []*model.ColumnInfo, idxCols []*model.IndexColumn) (co
209214
return
210215
}
211216

212-
func checkIndexColumn(col *model.ColumnInfo, indexColumnLen int, suppressTooLongKeyErr bool, columnarIndexType model.ColumnarIndexType) error {
217+
// checkIndexColumn will be run for all non-columnar indexes.
218+
func checkIndexColumn(col *model.ColumnInfo, indexColumnLen int, suppressTooLongKeyErr bool) error {
213219
if col.GetFlen() == 0 && (types.IsTypeChar(col.FieldType.GetType()) || types.IsTypeVarchar(col.FieldType.GetType())) {
214220
if col.Hidden {
215221
return errors.Trace(dbterror.ErrWrongKeyColumnFunctionalIndex.GenWithStackByArgs(col.GeneratedExprString))
@@ -225,14 +231,8 @@ func checkIndexColumn(col *model.ColumnInfo, indexColumnLen int, suppressTooLong
225231
return errors.Trace(dbterror.ErrJSONUsedAsKey.GenWithStackByArgs(col.Name.O))
226232
}
227233

228-
// Vector column cannot index, for now.
229234
if col.FieldType.GetType() == mysql.TypeTiDBVectorFloat32 {
230-
if col.Hidden {
231-
return errors.Errorf("Cannot create an expression index on a function that returns a VECTOR value")
232-
}
233-
if columnarIndexType != model.ColumnarIndexTypeVector {
234-
return dbterror.ErrUnsupportedAddColumnarIndex.FastGenByArgs("unsupported adding a non-vector index on a vector column")
235-
}
235+
return dbterror.ErrUnsupportedAddColumnarIndex.FastGen("only VECTOR INDEX can be added to vector column")
236236
}
237237

238238
// Length must be specified and non-zero for BLOB and TEXT column indexes.
@@ -283,7 +283,14 @@ func checkIndexColumn(col *model.ColumnInfo, indexColumnLen int, suppressTooLong
283283
}
284284

285285
// getIndexColumnLength calculate the bytes number required in an index column.
286-
func getIndexColumnLength(col *model.ColumnInfo, colLen int) (int, error) {
286+
func getIndexColumnLength(col *model.ColumnInfo, colLen int, columnarIndexType model.ColumnarIndexType) (int, error) {
287+
if columnarIndexType != model.ColumnarIndexTypeNA {
288+
// Columnar index does not actually create KV index, so it has length of 0.
289+
// however 0 may cause some issues in other calculations, so we use 1 here.
290+
// 1 is also minimal enough anyway.
291+
return 1, nil
292+
}
293+
287294
length := types.UnspecifiedLength
288295
if colLen != types.UnspecifiedLength {
289296
length = colLen
@@ -292,11 +299,6 @@ func getIndexColumnLength(col *model.ColumnInfo, colLen int) (int, error) {
292299
}
293300

294301
switch col.GetType() {
295-
case mysql.TypeTiDBVectorFloat32:
296-
// Vector Index does not actually create KV index, so it has length of 0.
297-
// however 0 may cause some issues in other calculations, so we use 1 here.
298-
// 1 is also minimal enough anyway.
299-
return 1, nil
300302
case mysql.TypeBit:
301303
return (length + 7) >> 3, nil
302304
case mysql.TypeVarchar, mysql.TypeString, mysql.TypeVarString, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeBlob, mysql.TypeLongBlob:
@@ -363,6 +365,12 @@ func BuildIndexInfo(
363365
return nil, errors.Trace(err)
364366
}
365367
idxInfo.InvertedInfo = invertedInfo
368+
case model.ColumnarIndexTypeFulltext:
369+
ftsInfo, err := buildFullTextInfoWithCheck(indexPartSpecifications, indexOption, tblInfo)
370+
if err != nil {
371+
return nil, errors.Trace(err)
372+
}
373+
idxInfo.FullTextInfo = ftsInfo
366374
}
367375

368376
var err error
@@ -484,6 +492,50 @@ func buildInvertedInfoWithCheck(indexPartSpecifications []*ast.IndexPartSpecific
484492
return model.FieldTypeToInvertedIndexInfo(colInfo.FieldType, colInfo.ID), nil
485493
}
486494

495+
func buildFullTextInfoWithCheck(indexPartSpecifications []*ast.IndexPartSpecification, indexOption *ast.IndexOption,
496+
tblInfo *model.TableInfo) (*model.FullTextIndexInfo, error) {
497+
if len(indexPartSpecifications) != 1 {
498+
return nil, dbterror.ErrUnsupportedAddColumnarIndex.FastGen("FULLTEXT index only support one column")
499+
}
500+
idxPart := indexPartSpecifications[0]
501+
if idxPart.Column == nil {
502+
return nil, dbterror.ErrUnsupportedAddColumnarIndex.FastGen("FULLTEXT index only support one column")
503+
}
504+
if idxPart.Length != types.UnspecifiedLength {
505+
return nil, dbterror.ErrUnsupportedAddColumnarIndex.FastGen("FULLTEXT index does not support prefix length")
506+
}
507+
if idxPart.Desc {
508+
return nil, dbterror.ErrUnsupportedAddColumnarIndex.FastGen("FULLTEXT index does not support DESC order")
509+
}
510+
// The Default parser is STANDARD
511+
parser := model.FullTextParserTypeStandardV1
512+
if indexOption != nil && indexOption.ParserName.L != "" {
513+
parser = model.GetFullTextParserTypeBySQLName(indexOption.ParserName.L)
514+
if parser == model.FullTextParserTypeInvalid {
515+
// Actually indexOption must be valid. It is already checked in preprocessor.
516+
return nil, dbterror.ErrUnsupportedAddColumnarIndex.FastGen("fulltext index must specify a valid parser")
517+
}
518+
}
519+
colInfo := findColumnByName(idxPart.Column.Name.L, tblInfo)
520+
if colInfo == nil {
521+
return nil, infoschema.ErrColumnNotExists.GenWithStackByArgs(idxPart.Column.Name.L, tblInfo.Name)
522+
}
523+
for _, idx := range tblInfo.Indices {
524+
if idx.FullTextInfo == nil {
525+
continue
526+
}
527+
if idxCol := idx.FindColumnByName(colInfo.Name.L); idxCol == nil {
528+
continue
529+
}
530+
return nil, dbterror.ErrDupKeyName.GenWithStack(
531+
fmt.Sprintf("fulltext index '%s' already exist on column %s",
532+
idx.Name, colInfo.Name))
533+
}
534+
return &model.FullTextIndexInfo{
535+
ParserType: parser,
536+
}, nil
537+
}
538+
487539
// AddIndexColumnFlag aligns the column flags of columns in TableInfo to IndexInfo.
488540
func AddIndexColumnFlag(tblInfo *model.TableInfo, indexInfo *model.IndexInfo) {
489541
if indexInfo.Primary {

pkg/ddl/index_modify_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,7 @@ func TestAddVectorIndexSimple(t *testing.T) {
12741274
// for TiFlash replica
12751275
tk.MustExec("create table t (a int, b vector, c vector(3), d vector(4));")
12761276
tk.MustContainErrMsg("alter table t add vector index idx((VEC_COSINE_DISTANCE(b))) USING HNSW COMMENT 'b comment';",
1277-
"unsupported empty TiFlash replica, the replica is nil")
1277+
"columnar replica must exist")
12781278
tk.MustExec("alter table t set tiflash replica 2 location labels 'a','b';")
12791279
tk.MustContainErrMsg("alter table t add key idx(a) USING HNSW;", "[ddl:8200]'USING HNSW' can be only used for VECTOR INDEX")
12801280
// for a wrong column
@@ -1458,7 +1458,7 @@ func TestAddColumnarIndexSimple(t *testing.T) {
14581458
// for TiFlash replica
14591459
tk.MustExec("create table t (a int, b vector(4), c int, d char(4));")
14601460
tk.MustContainErrMsg("alter table t add columnar index idx(a) USING INVERTED COMMENT 'b comment';",
1461-
"unsupported empty TiFlash replica, the replica is nil")
1461+
"columnar replica must exist")
14621462
tk.MustExec("alter table t set tiflash replica 2 location labels 'a','b';")
14631463
tk.MustContainErrMsg("alter table t add key idx(d) USING INVERTED;", "[ddl:8200]'USING INVERTED' can be only used for COLUMNAR INDEX")
14641464
// for a wrong column

0 commit comments

Comments
 (0)