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