Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "postgres.h"
00007
00008 #include <ctype.h>
00009
00010 #include "ltree.h"
00011
00012 PG_FUNCTION_INFO_V1(ltxtq_exec);
00013 PG_FUNCTION_INFO_V1(ltxtq_rexec);
00014
00015
00016
00017
00018 bool
00019 ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *val))
00020 {
00021 if (curitem->type == VAL)
00022 return (*chkcond) (checkval, curitem);
00023 else if (curitem->val == (int32) '!')
00024 {
00025 return (calcnot) ?
00026 ((ltree_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
00027 : true;
00028 }
00029 else if (curitem->val == (int32) '&')
00030 {
00031 if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
00032 return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
00033 else
00034 return false;
00035 }
00036 else
00037 {
00038 if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
00039 return true;
00040 else
00041 return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
00042 }
00043 }
00044
00045 typedef struct
00046 {
00047 ltree *node;
00048 char *operand;
00049 } CHKVAL;
00050
00051 static bool
00052 checkcondition_str(void *checkval, ITEM *val)
00053 {
00054 ltree_level *level = LTREE_FIRST(((CHKVAL *) checkval)->node);
00055 int tlen = ((CHKVAL *) checkval)->node->numlevel;
00056 char *op = ((CHKVAL *) checkval)->operand + val->distance;
00057 int (*cmpptr) (const char *, const char *, size_t);
00058
00059 cmpptr = (val->flag & LVAR_INCASE) ? ltree_strncasecmp : strncmp;
00060 while (tlen > 0)
00061 {
00062 if (val->flag & LVAR_SUBLEXEME)
00063 {
00064 if (compare_subnode(level, op, val->length, cmpptr, (val->flag & LVAR_ANYEND)))
00065 return true;
00066 }
00067 else if (
00068 (
00069 val->length == level->len ||
00070 (level->len > val->length && (val->flag & LVAR_ANYEND))
00071 ) &&
00072 (*cmpptr) (op, level->name, val->length) == 0)
00073 return true;
00074
00075 tlen--;
00076 level = LEVEL_NEXT(level);
00077 }
00078
00079 return false;
00080 }
00081
00082 Datum
00083 ltxtq_exec(PG_FUNCTION_ARGS)
00084 {
00085 ltree *val = PG_GETARG_LTREE(0);
00086 ltxtquery *query = PG_GETARG_LTXTQUERY(1);
00087 CHKVAL chkval;
00088 bool result;
00089
00090 chkval.node = val;
00091 chkval.operand = GETOPERAND(query);
00092
00093 result = ltree_execute(
00094 GETQUERY(query),
00095 &chkval,
00096 true,
00097 checkcondition_str
00098 );
00099
00100 PG_FREE_IF_COPY(val, 0);
00101 PG_FREE_IF_COPY(query, 1);
00102 PG_RETURN_BOOL(result);
00103 }
00104
00105 Datum
00106 ltxtq_rexec(PG_FUNCTION_ARGS)
00107 {
00108 PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec,
00109 PG_GETARG_DATUM(1),
00110 PG_GETARG_DATUM(0)
00111 ));
00112 }