From 4a0cc220886bfa55f23368b164178973b4920e5c Mon Sep 17 00:00:00 2001 From: Eric Lam Date: Fri, 17 Jan 2025 11:46:47 +0000 Subject: [PATCH] create index check duplicate index with same parts (#21257) bug fix mo can create duplicate fulltext index on same column Approved by: @ouyuanning, @badboynt1, @aressu1985, @heni02, @aunjgr --- pkg/sql/plan/build_ddl.go | 34 ++++++++++++++++--- .../cases/fulltext/fulltext.result | 6 ++++ test/distributed/cases/fulltext/fulltext.sql | 3 ++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/pkg/sql/plan/build_ddl.go b/pkg/sql/plan/build_ddl.go index 97e2f6dd440c3..906fe14faa343 100644 --- a/pkg/sql/plan/build_ddl.go +++ b/pkg/sql/plan/build_ddl.go @@ -1455,7 +1455,7 @@ func buildTableDefs(stmt *tree.CreateTable, ctx CompilerContext, createTable *pl } } if len(fullTextIndexInfos) != 0 { - err = buildFullTextIndexTable(createTable, fullTextIndexInfos, colMap, pkeyName, ctx) + err = buildFullTextIndexTable(createTable, fullTextIndexInfos, colMap, nil, pkeyName, ctx) if err != nil { return err } @@ -1530,11 +1530,37 @@ func getRefAction(typ tree.ReferenceOptionType) plan.ForeignKeyDef_RefAction { } // buildFullTextIndexTable create a secondary table with schema (doc_id, word, pos) cluster by (word) -func buildFullTextIndexTable(createTable *plan.CreateTable, indexInfos []*tree.FullTextIndex, colMap map[string]*ColDef, pkeyName string, ctx CompilerContext) error { +func buildFullTextIndexTable(createTable *plan.CreateTable, indexInfos []*tree.FullTextIndex, colMap map[string]*ColDef, existedIndexes []*plan.IndexDef, pkeyName string, ctx CompilerContext) error { if pkeyName == "" || pkeyName == catalog.FakePrimaryKeyColName { return moerr.NewInternalErrorNoCtx("primary key cannot be empty for fulltext index") } + // check duplicate index + if len(existedIndexes) > 0 { + for _, existedIndex := range existedIndexes { + if existedIndex.IndexAlgo == "fulltext" { + for _, indexInfo := range indexInfos { + if len(indexInfo.KeyParts) != len(existedIndex.Parts) { + continue + } + n := 0 + for _, keyPart := range indexInfo.KeyParts { + for _, ePart := range existedIndex.Parts { + if ePart == keyPart.ColName.ColName() { + n++ + break + } + } + } + + if n == len(indexInfo.KeyParts) { + return moerr.NewNotSupported(ctx.GetContext(), "Fulltext index are not allowed to use the same column") + } + } + } + } + } + for _, indexInfo := range indexInfos { // fulltext only support char, varchar and text for _, keyPart := range indexInfo.KeyParts { @@ -2929,7 +2955,7 @@ func buildCreateIndex(stmt *tree.CreateIndex, ctx CompilerContext) (*Plan, error createIndex.TableExist = true } if ftIdx != nil { - if err := buildFullTextIndexTable(indexInfo, []*tree.FullTextIndex{ftIdx}, colMap, oriPriKeyName, ctx); err != nil { + if err := buildFullTextIndexTable(indexInfo, []*tree.FullTextIndex{ftIdx}, colMap, tableDef.Indexes, oriPriKeyName, ctx); err != nil { return nil, err } createIndex.TableExist = true @@ -3391,7 +3417,7 @@ func buildAlterTableInplace(stmt *tree.AlterTable, ctx CompilerContext) (*Plan, oriPriKeyName := getTablePriKeyName(tableDef.Pkey) indexInfo := &plan.CreateTable{TableDef: &TableDef{}} - if err = buildFullTextIndexTable(indexInfo, []*tree.FullTextIndex{def}, colMap, oriPriKeyName, ctx); err != nil { + if err = buildFullTextIndexTable(indexInfo, []*tree.FullTextIndex{def}, colMap, tableDef.Indexes, oriPriKeyName, ctx); err != nil { return nil, err } diff --git a/test/distributed/cases/fulltext/fulltext.result b/test/distributed/cases/fulltext/fulltext.result index d16c45a9a9e53..ce65941b48c71 100644 --- a/test/distributed/cases/fulltext/fulltext.result +++ b/test/distributed/cases/fulltext/fulltext.result @@ -9,6 +9,8 @@ insert into src values (0, 'color is red', 't1'), (1, 'car is yellow', 'crazy ca (9, 'NOT INCLUDED BODY', NULL), (10, NULL, NULL); create fulltext index ftidx on src (body, title); +create fulltext index ftidx02 on src (body, title); +not supported: Fulltext index are not allowed to use the same column select * from src where match(body) against('red'); not supported: MATCH() AGAINST() function cannot be replaced by FULLTEXT INDEX and full table scan with fulltext search is not supported yet. select * from src where match(body,title) against('+]]]'); @@ -18,6 +20,10 @@ SQL parser error: You have an error in your SQL syntax; check the manual that co select match(body) against('red') from src; not supported: MATCH() AGAINST() function cannot be replaced by FULLTEXT INDEX and full table scan with fulltext search is not supported yet. alter table src add fulltext index ftidx2 (body); +create fulltext index ftidx03 on src (body); +not supported: Fulltext index are not allowed to use the same column +create fulltext index ftidx03 on src (body, title); +not supported: Fulltext index are not allowed to use the same column select * from src where match(body, title) against('red'); id body title 0 color is red t1 diff --git a/test/distributed/cases/fulltext/fulltext.sql b/test/distributed/cases/fulltext/fulltext.sql index 8a3ae0b6b07d7..088cdd314c86f 100644 --- a/test/distributed/cases/fulltext/fulltext.sql +++ b/test/distributed/cases/fulltext/fulltext.sql @@ -16,6 +16,7 @@ insert into src values (0, 'color is red', 't1'), (1, 'car is yellow', 'crazy ca create fulltext index ftidx on src (body, title); -- check fulltext_match with index error +create fulltext index ftidx02 on src (body, title); select * from src where match(body) against('red'); select * from src where match(body,title) against('+]]]'); select * from src where match(body,title) against('+I'm'); @@ -24,6 +25,8 @@ select match(body) against('red') from src; -- add index for body column alter table src add fulltext index ftidx2 (body); +create fulltext index ftidx03 on src (body); +create fulltext index ftidx03 on src (body, title); -- match in WHERE clause select * from src where match(body, title) against('red');