0001-Fix-error-when-process-duplicate-token-in-tsearch.patch
application/octet-stream
Filename: 0001-Fix-error-when-process-duplicate-token-in-tsearch.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Fix error when process duplicate token in tsearch
| File | + | − |
|---|---|---|
| src/backend/commands/tsearchcmds.c | 33 | 52 |
| src/test/regress/expected/tsdicts.out | 5 | 0 |
| src/test/regress/sql/tsdicts.sql | 7 | 0 |
From 8e4ae9249c70ca5b142962664b621af416de903e Mon Sep 17 00:00:00 2001
From: Yongtao Huang <yongtah2022@gmail.com>
Date: Sun, 28 Jan 2024 01:13:14 +0800
Subject: [PATCH] Fix error when process duplicate token in tsearch
Author: Tender Wang <tndrwang@gmail.com>
---
src/backend/commands/tsearchcmds.c | 85 ++++++++++++++---------------------
src/test/regress/expected/tsdicts.out | 5 +++
src/test/regress/sql/tsdicts.sql | 7 +++
3 files changed, 45 insertions(+), 52 deletions(-)
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 0767172..0e82695 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -1194,20 +1194,19 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
/*
* Translate a list of token type names to an array of token type numbers
*/
-static int *
-getTokenTypes(Oid prsId, List *tokennames)
+static List *
+getTokenTypes(Oid prsId, AlterTSConfigurationStmt *stmt)
{
TSParserCacheEntry *prs = lookup_ts_parser_cache(prsId);
LexDescr *list;
- int *res,
- i,
- ntoken;
+ List *res = NIL;
+ int ntoken;
ListCell *tn;
+ List *tokennames = stmt->tokentype;
ntoken = list_length(tokennames);
if (ntoken == 0)
- return NULL;
- res = (int *) palloc(sizeof(int) * ntoken);
+ return NIL;
if (!OidIsValid(prs->lextypeOid))
elog(ERROR, "method lextype isn't defined for text search parser %u",
@@ -1217,7 +1216,6 @@ getTokenTypes(Oid prsId, List *tokennames)
list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
(Datum) 0));
- i = 0;
foreach(tn, tokennames)
{
String *val = lfirst_node(String, tn);
@@ -1229,18 +1227,26 @@ getTokenTypes(Oid prsId, List *tokennames)
{
if (strcmp(strVal(val), list[j].alias) == 0)
{
- res[i] = list[j].lexid;
+ res = list_append_unique_int(res, list[j].lexid);
found = true;
break;
}
j++;
}
if (!found)
- ereport(ERROR,
+ {
+ if (!stmt->missing_ok)
+ ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("token type \"%s\" does not exist",
- strVal(val))));
- i++;
+ errmsg("token type \"%s\" does not exist",
+ strVal(val))));
+ else
+ {
+ ereport(NOTICE,
+ (errmsg("token type \"%s\" does not exist, skipping",
+ strVal(val))));
+ }
+ }
}
return res;
@@ -1261,8 +1267,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
int i;
int j;
Oid prsId;
- int *tokens,
- ntoken;
+ List *tokens = NIL;
+ int ntoken;
Oid *dictIds;
int ndict;
ListCell *c;
@@ -1272,15 +1278,15 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
cfgId = tsform->oid;
prsId = tsform->cfgparser;
- tokens = getTokenTypes(prsId, stmt->tokentype);
- ntoken = list_length(stmt->tokentype);
+ tokens = getTokenTypes(prsId, stmt);
+ ntoken = list_length(tokens);
if (stmt->override)
{
/*
* delete maps for tokens if they exist and command was ALTER
*/
- for (i = 0; i < ntoken; i++)
+ foreach(c, tokens)
{
ScanKeyInit(&skey[0],
Anum_pg_ts_config_map_mapcfg,
@@ -1289,7 +1295,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
ScanKeyInit(&skey[1],
Anum_pg_ts_config_map_maptokentype,
BTEqualStrategyNumber, F_INT4EQ,
- Int32GetDatum(tokens[i]));
+ Int32GetDatum(lfirst_int(c)));
scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
NULL, 2, skey);
@@ -1346,9 +1352,9 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
{
bool tokmatch = false;
- for (j = 0; j < ntoken; j++)
+ foreach(c, tokens)
{
- if (cfgmap->maptokentype == tokens[j])
+ if (cfgmap->maptokentype == lfirst_int(c))
{
tokmatch = true;
break;
@@ -1401,7 +1407,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
/*
* Insertion of new entries
*/
- for (i = 0; i < ntoken; i++)
+ foreach(c, tokens)
{
for (j = 0; j < ndict; j++)
{
@@ -1411,7 +1417,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
slot[slotCount]->tts_tupleDescriptor->natts * sizeof(bool));
slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
- slot[slotCount]->tts_values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
+ slot[slotCount]->tts_values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(lfirst_int(c));
slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
@@ -1455,23 +1461,18 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
ScanKeyData skey[2];
SysScanDesc scan;
HeapTuple maptup;
- int i;
Oid prsId;
- int *tokens;
+ List *tokens = NIL;
ListCell *c;
tsform = (Form_pg_ts_config) GETSTRUCT(tup);
cfgId = tsform->oid;
prsId = tsform->cfgparser;
- tokens = getTokenTypes(prsId, stmt->tokentype);
+ tokens = getTokenTypes(prsId, stmt);
- i = 0;
- foreach(c, stmt->tokentype)
+ foreach(c, tokens)
{
- String *val = lfirst_node(String, c);
- bool found = false;
-
ScanKeyInit(&skey[0],
Anum_pg_ts_config_map_mapcfg,
BTEqualStrategyNumber, F_OIDEQ,
@@ -1479,7 +1480,7 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
ScanKeyInit(&skey[1],
Anum_pg_ts_config_map_maptokentype,
BTEqualStrategyNumber, F_INT4EQ,
- Int32GetDatum(tokens[i]));
+ Int32GetDatum(lfirst_int(c)));
scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
NULL, 2, skey);
@@ -1487,29 +1488,9 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
while (HeapTupleIsValid((maptup = systable_getnext(scan))))
{
CatalogTupleDelete(relMap, &maptup->t_self);
- found = true;
}
systable_endscan(scan);
-
- if (!found)
- {
- if (!stmt->missing_ok)
- {
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("mapping for token type \"%s\" does not exist",
- strVal(val))));
- }
- else
- {
- ereport(NOTICE,
- (errmsg("mapping for token type \"%s\" does not exist, skipping",
- strVal(val))));
- }
- }
-
- i++;
}
EventTriggerCollectAlterTSConfig(stmt, cfgId, NULL, 0);
diff --git a/src/test/regress/expected/tsdicts.out b/src/test/regress/expected/tsdicts.out
index c804293..af69197 100644
--- a/src/test/regress/expected/tsdicts.out
+++ b/src/test/regress/expected/tsdicts.out
@@ -687,3 +687,8 @@ CREATE TEXT SEARCH DICTIONARY tsdict_case
"AffFile" = ispell_sample
);
ERROR: unrecognized Ispell parameter: "DictFile"
+-- test duplicate token type
+CREATE TEXT SEARCH CONFIGURATION dup_ispell_tst (COPY=english);
+ALTER TEXT SEARCH CONFIGURATION dup_ispell_tst ALTER MAPPING FOR word, word WITH ispell;
+ALTER TEXT SEARCH CONFIGURATION dup_ispell_tst DROP MAPPING IF EXISTS FOR hello;
+NOTICE: token type "hello" does not exist, skipping
diff --git a/src/test/regress/sql/tsdicts.sql b/src/test/regress/sql/tsdicts.sql
index ddc6c7f..d4302ab 100644
--- a/src/test/regress/sql/tsdicts.sql
+++ b/src/test/regress/sql/tsdicts.sql
@@ -251,3 +251,10 @@ CREATE TEXT SEARCH DICTIONARY tsdict_case
"DictFile" = ispell_sample,
"AffFile" = ispell_sample
);
+
+-- test duplicate token type
+CREATE TEXT SEARCH CONFIGURATION dup_ispell_tst (COPY=english);
+
+ALTER TEXT SEARCH CONFIGURATION dup_ispell_tst ALTER MAPPING FOR word, word WITH ispell;
+
+ALTER TEXT SEARCH CONFIGURATION dup_ispell_tst DROP MAPPING IF EXISTS FOR hello;
--
1.8.3.1