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