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