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