mirror of
https://github.com/postgres/postgres.git
synced 2025-12-07 12:02:30 +03:00
The idea is to encourage more the use of these new routines across the tree, as these offer stronger type safety guarantees than palloc(). In an ideal world, palloc() would then act as an internal routine of these flavors, whose footprint in the tree is minimal. The patch sent by the author is very large, and this chunk of changes represents something like 10% of the overall patch submitted. The code compiled is the same before and after this commit, using objdump to do some validation with a difference taken in-between. There are some diffs, which are caused by changes in line numbers because some of the new allocation formulas are shorter, for the following files: trgm_regexp.c, xpath.c and pg_walinspect.c. Author: David Geier <geidav.pg@gmail.com> Discussion: https://postgr.es/m/ad0748d4-3080-436e-b0bc-ac8f86a3466a@gmail.com
120 lines
2.2 KiB
C
120 lines
2.2 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* dict_int.c
|
|
* Text search dictionary for integers
|
|
*
|
|
* Copyright (c) 2007-2025, PostgreSQL Global Development Group
|
|
*
|
|
* IDENTIFICATION
|
|
* contrib/dict_int/dict_int.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include "commands/defrem.h"
|
|
#include "tsearch/ts_public.h"
|
|
|
|
PG_MODULE_MAGIC_EXT(
|
|
.name = "dict_int",
|
|
.version = PG_VERSION
|
|
);
|
|
|
|
typedef struct
|
|
{
|
|
int maxlen;
|
|
bool rejectlong;
|
|
bool absval;
|
|
} DictInt;
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(dintdict_init);
|
|
PG_FUNCTION_INFO_V1(dintdict_lexize);
|
|
|
|
Datum
|
|
dintdict_init(PG_FUNCTION_ARGS)
|
|
{
|
|
List *dictoptions = (List *) PG_GETARG_POINTER(0);
|
|
DictInt *d;
|
|
ListCell *l;
|
|
|
|
d = palloc0_object(DictInt);
|
|
d->maxlen = 6;
|
|
d->rejectlong = false;
|
|
d->absval = false;
|
|
|
|
foreach(l, dictoptions)
|
|
{
|
|
DefElem *defel = (DefElem *) lfirst(l);
|
|
|
|
if (strcmp(defel->defname, "maxlen") == 0)
|
|
{
|
|
d->maxlen = atoi(defGetString(defel));
|
|
|
|
if (d->maxlen < 1)
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
errmsg("maxlen value has to be >= 1")));
|
|
}
|
|
else if (strcmp(defel->defname, "rejectlong") == 0)
|
|
{
|
|
d->rejectlong = defGetBoolean(defel);
|
|
}
|
|
else if (strcmp(defel->defname, "absval") == 0)
|
|
{
|
|
d->absval = defGetBoolean(defel);
|
|
}
|
|
else
|
|
{
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
errmsg("unrecognized intdict parameter: \"%s\"",
|
|
defel->defname)));
|
|
}
|
|
}
|
|
|
|
PG_RETURN_POINTER(d);
|
|
}
|
|
|
|
Datum
|
|
dintdict_lexize(PG_FUNCTION_ARGS)
|
|
{
|
|
DictInt *d = (DictInt *) PG_GETARG_POINTER(0);
|
|
char *in = (char *) PG_GETARG_POINTER(1);
|
|
int len = PG_GETARG_INT32(2);
|
|
char *txt;
|
|
TSLexeme *res = palloc0_array(TSLexeme, 2);
|
|
|
|
res[1].lexeme = NULL;
|
|
|
|
if (d->absval && (in[0] == '+' || in[0] == '-'))
|
|
{
|
|
len--;
|
|
txt = pnstrdup(in + 1, len);
|
|
}
|
|
else
|
|
txt = pnstrdup(in, len);
|
|
|
|
if (len > d->maxlen)
|
|
{
|
|
if (d->rejectlong)
|
|
{
|
|
/* reject by returning void array */
|
|
pfree(txt);
|
|
res[0].lexeme = NULL;
|
|
}
|
|
else
|
|
{
|
|
/* trim integer */
|
|
txt[d->maxlen] = '\0';
|
|
res[0].lexeme = txt;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
res[0].lexeme = txt;
|
|
}
|
|
|
|
PG_RETURN_POINTER(res);
|
|
}
|