mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
b8b2e3b2de
The latter was already the dominant use, and it's preferable because in C the convention is that intXX means XX bits. Therefore, allowing mixed use of int2, int4, int8, int16, int32 is obviously confusing. Remove the typedefs for int2 and int4 for now. They don't seem to be widely used outside of the PostgreSQL source tree, and the few uses can probably be cleaned up by the time this ships.
114 lines
2.4 KiB
C
114 lines
2.4 KiB
C
/*
|
|
* txtquery operations with ltree
|
|
* Teodor Sigaev <teodor@stack.net>
|
|
* contrib/ltree/ltxtquery_op.c
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "ltree.h"
|
|
|
|
PG_FUNCTION_INFO_V1(ltxtq_exec);
|
|
PG_FUNCTION_INFO_V1(ltxtq_rexec);
|
|
|
|
/*
|
|
* check for boolean condition
|
|
*/
|
|
bool
|
|
ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *val))
|
|
{
|
|
if (curitem->type == VAL)
|
|
return (*chkcond) (checkval, curitem);
|
|
else if (curitem->val == (int32) '!')
|
|
{
|
|
return (calcnot) ?
|
|
((ltree_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
|
|
: true;
|
|
}
|
|
else if (curitem->val == (int32) '&')
|
|
{
|
|
if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
|
|
return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
{ /* |-operator */
|
|
if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
|
|
return true;
|
|
else
|
|
return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
ltree *node;
|
|
char *operand;
|
|
} CHKVAL;
|
|
|
|
static bool
|
|
checkcondition_str(void *checkval, ITEM *val)
|
|
{
|
|
ltree_level *level = LTREE_FIRST(((CHKVAL *) checkval)->node);
|
|
int tlen = ((CHKVAL *) checkval)->node->numlevel;
|
|
char *op = ((CHKVAL *) checkval)->operand + val->distance;
|
|
int (*cmpptr) (const char *, const char *, size_t);
|
|
|
|
cmpptr = (val->flag & LVAR_INCASE) ? ltree_strncasecmp : strncmp;
|
|
while (tlen > 0)
|
|
{
|
|
if (val->flag & LVAR_SUBLEXEME)
|
|
{
|
|
if (compare_subnode(level, op, val->length, cmpptr, (val->flag & LVAR_ANYEND)))
|
|
return true;
|
|
}
|
|
else if (
|
|
(
|
|
val->length == level->len ||
|
|
(level->len > val->length && (val->flag & LVAR_ANYEND))
|
|
) &&
|
|
(*cmpptr) (op, level->name, val->length) == 0)
|
|
return true;
|
|
|
|
tlen--;
|
|
level = LEVEL_NEXT(level);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Datum
|
|
ltxtq_exec(PG_FUNCTION_ARGS)
|
|
{
|
|
ltree *val = PG_GETARG_LTREE(0);
|
|
ltxtquery *query = PG_GETARG_LTXTQUERY(1);
|
|
CHKVAL chkval;
|
|
bool result;
|
|
|
|
chkval.node = val;
|
|
chkval.operand = GETOPERAND(query);
|
|
|
|
result = ltree_execute(
|
|
GETQUERY(query),
|
|
&chkval,
|
|
true,
|
|
checkcondition_str
|
|
);
|
|
|
|
PG_FREE_IF_COPY(val, 0);
|
|
PG_FREE_IF_COPY(query, 1);
|
|
PG_RETURN_BOOL(result);
|
|
}
|
|
|
|
Datum
|
|
ltxtq_rexec(PG_FUNCTION_ARGS)
|
|
{
|
|
PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec,
|
|
PG_GETARG_DATUM(1),
|
|
PG_GETARG_DATUM(0)
|
|
));
|
|
}
|