Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * 3 : * dict_int.c 4 : * Text search dictionary for integers 5 : * 6 : * Copyright (c) 2007-2024, PostgreSQL Global Development Group 7 : * 8 : * IDENTIFICATION 9 : * contrib/dict_int/dict_int.c 10 : * 11 : *------------------------------------------------------------------------- 12 : */ 13 : #include "postgres.h" 14 : 15 : #include "commands/defrem.h" 16 : #include "tsearch/ts_public.h" 17 : 18 2 : PG_MODULE_MAGIC; 19 : 20 : typedef struct 21 : { 22 : int maxlen; 23 : bool rejectlong; 24 : bool absval; 25 : } DictInt; 26 : 27 : 28 4 : PG_FUNCTION_INFO_V1(dintdict_init); 29 4 : PG_FUNCTION_INFO_V1(dintdict_lexize); 30 : 31 : Datum 32 18 : dintdict_init(PG_FUNCTION_ARGS) 33 : { 34 18 : List *dictoptions = (List *) PG_GETARG_POINTER(0); 35 : DictInt *d; 36 : ListCell *l; 37 : 38 18 : d = (DictInt *) palloc0(sizeof(DictInt)); 39 18 : d->maxlen = 6; 40 18 : d->rejectlong = false; 41 18 : d->absval = false; 42 : 43 42 : foreach(l, dictoptions) 44 : { 45 26 : DefElem *defel = (DefElem *) lfirst(l); 46 : 47 26 : if (strcmp(defel->defname, "maxlen") == 0) 48 : { 49 14 : d->maxlen = atoi(defGetString(defel)); 50 : 51 14 : if (d->maxlen < 1) 52 2 : ereport(ERROR, 53 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 54 : errmsg("maxlen value has to be >= 1"))); 55 : } 56 12 : else if (strcmp(defel->defname, "rejectlong") == 0) 57 : { 58 4 : d->rejectlong = defGetBoolean(defel); 59 : } 60 8 : else if (strcmp(defel->defname, "absval") == 0) 61 : { 62 8 : d->absval = defGetBoolean(defel); 63 : } 64 : else 65 : { 66 0 : ereport(ERROR, 67 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 68 : errmsg("unrecognized intdict parameter: \"%s\"", 69 : defel->defname))); 70 : } 71 : } 72 : 73 16 : PG_RETURN_POINTER(d); 74 : } 75 : 76 : Datum 77 114 : dintdict_lexize(PG_FUNCTION_ARGS) 78 : { 79 114 : DictInt *d = (DictInt *) PG_GETARG_POINTER(0); 80 114 : char *in = (char *) PG_GETARG_POINTER(1); 81 114 : int len = PG_GETARG_INT32(2); 82 : char *txt; 83 114 : TSLexeme *res = palloc0(sizeof(TSLexeme) * 2); 84 : 85 114 : res[1].lexeme = NULL; 86 : 87 114 : if (d->absval && (in[0] == '+' || in[0] == '-')) 88 : { 89 10 : len--; 90 10 : txt = pnstrdup(in + 1, len); 91 : } 92 : else 93 104 : txt = pnstrdup(in, len); 94 : 95 114 : if (len > d->maxlen) 96 : { 97 76 : if (d->rejectlong) 98 : { 99 : /* reject by returning void array */ 100 4 : pfree(txt); 101 4 : res[0].lexeme = NULL; 102 : } 103 : else 104 : { 105 : /* trim integer */ 106 72 : txt[d->maxlen] = '\0'; 107 72 : res[0].lexeme = txt; 108 : } 109 : } 110 : else 111 : { 112 38 : res[0].lexeme = txt; 113 : } 114 : 115 114 : PG_RETURN_POINTER(res); 116 : }