postgresql/contrib/ltree/ltxtquery_op.c
Alvaro Herrera c9d2977519 Clean up newlines following left parentheses
We used to strategically place newlines after some function call left
parentheses to make pgindent move the argument list a few chars to the
left, so that the whole line would fit under 80 chars.  However,
pgindent no longer does that, so the newlines just made the code
vertically longer for no reason.  Remove those newlines, and reflow some
of those lines for some extra naturality.

Reviewed-by: Michael Paquier, Tom Lane
Discussion: https://postgr.es/m/20200129200401.GA6303@alvherre.pgsql
2020-01-30 13:42:14 -03:00

112 lines
2.5 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"
#include "miscadmin.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))
{
/* since this function recurses, it could be driven to stack overflow */
check_stack_depth();
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);
}
}
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_P(0);
ltxtquery *query = PG_GETARG_LTXTQUERY_P(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)
));
}