Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * 3 : * dict_simple.c 4 : * Simple dictionary: just lowercase and check for stopword 5 : * 6 : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group 7 : * 8 : * 9 : * IDENTIFICATION 10 : * src/backend/tsearch/dict_simple.c 11 : * 12 : *------------------------------------------------------------------------- 13 : */ 14 : #include "postgres.h" 15 : 16 : #include "catalog/pg_collation_d.h" 17 : #include "commands/defrem.h" 18 : #include "tsearch/ts_public.h" 19 : #include "utils/fmgrprotos.h" 20 : #include "utils/formatting.h" 21 : 22 : 23 : typedef struct 24 : { 25 : StopList stoplist; 26 : bool accept; 27 : } DictSimple; 28 : 29 : 30 : Datum 31 70 : dsimple_init(PG_FUNCTION_ARGS) 32 : { 33 70 : List *dictoptions = (List *) PG_GETARG_POINTER(0); 34 70 : DictSimple *d = (DictSimple *) palloc0(sizeof(DictSimple)); 35 70 : bool stoploaded = false, 36 70 : acceptloaded = false; 37 : ListCell *l; 38 : 39 70 : d->accept = true; /* default */ 40 : 41 70 : foreach(l, dictoptions) 42 : { 43 0 : DefElem *defel = (DefElem *) lfirst(l); 44 : 45 0 : if (strcmp(defel->defname, "stopwords") == 0) 46 : { 47 0 : if (stoploaded) 48 0 : ereport(ERROR, 49 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 50 : errmsg("multiple StopWords parameters"))); 51 0 : readstoplist(defGetString(defel), &d->stoplist, str_tolower); 52 0 : stoploaded = true; 53 : } 54 0 : else if (strcmp(defel->defname, "accept") == 0) 55 : { 56 0 : if (acceptloaded) 57 0 : ereport(ERROR, 58 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 59 : errmsg("multiple Accept parameters"))); 60 0 : d->accept = defGetBoolean(defel); 61 0 : acceptloaded = true; 62 : } 63 : else 64 : { 65 0 : ereport(ERROR, 66 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 67 : errmsg("unrecognized simple dictionary parameter: \"%s\"", 68 : defel->defname))); 69 : } 70 : } 71 : 72 70 : PG_RETURN_POINTER(d); 73 : } 74 : 75 : Datum 76 3698 : dsimple_lexize(PG_FUNCTION_ARGS) 77 : { 78 3698 : DictSimple *d = (DictSimple *) PG_GETARG_POINTER(0); 79 3698 : char *in = (char *) PG_GETARG_POINTER(1); 80 3698 : int32 len = PG_GETARG_INT32(2); 81 : char *txt; 82 : TSLexeme *res; 83 : 84 3698 : txt = str_tolower(in, len, DEFAULT_COLLATION_OID); 85 : 86 3698 : if (*txt == '\0' || searchstoplist(&(d->stoplist), txt)) 87 : { 88 : /* reject as stopword */ 89 0 : pfree(txt); 90 0 : res = palloc0(sizeof(TSLexeme) * 2); 91 0 : PG_RETURN_POINTER(res); 92 : } 93 3698 : else if (d->accept) 94 : { 95 : /* accept */ 96 3698 : res = palloc0(sizeof(TSLexeme) * 2); 97 3698 : res[0].lexeme = txt; 98 3698 : PG_RETURN_POINTER(res); 99 : } 100 : else 101 : { 102 : /* report as unrecognized */ 103 0 : pfree(txt); 104 0 : PG_RETURN_POINTER(NULL); 105 : } 106 : }