LCOV - code coverage report
Current view: top level - contrib/ltree - ltxtquery_op.c (source / functions) Hit Total Coverage
Test: PostgreSQL 11beta1 Lines: 43 45 95.6 %
Date: 2018-06-18 00:19:56 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * txtquery operations with ltree
       3             :  * Teodor Sigaev <teodor@stack.net>
       4             :  * contrib/ltree/ltxtquery_op.c
       5             :  */
       6             : #include "postgres.h"
       7             : 
       8             : #include <ctype.h>
       9             : 
      10             : #include "ltree.h"
      11             : #include "miscadmin.h"
      12             : 
      13           6 : PG_FUNCTION_INFO_V1(ltxtq_exec);
      14           4 : PG_FUNCTION_INFO_V1(ltxtq_rexec);
      15             : 
      16             : /*
      17             :  * check for boolean condition
      18             :  */
      19             : bool
      20       34880 : ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *val))
      21             : {
      22             :     /* since this function recurses, it could be driven to stack overflow */
      23       34880 :     check_stack_depth();
      24             : 
      25       34880 :     if (curitem->type == VAL)
      26       19512 :         return (*chkcond) (checkval, curitem);
      27       15368 :     else if (curitem->val == (int32) '!')
      28             :     {
      29             :         return calcnot ?
      30           6 :             ((ltree_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
      31          12 :             : true;
      32             :     }
      33       15362 :     else if (curitem->val == (int32) '&')
      34             :     {
      35       15358 :         if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
      36        4148 :             return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
      37             :         else
      38       11210 :             return false;
      39             :     }
      40             :     else
      41             :     {                           /* |-operator */
      42           4 :         if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
      43           2 :             return true;
      44             :         else
      45           2 :             return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
      46             :     }
      47             : }
      48             : 
      49             : typedef struct
      50             : {
      51             :     ltree      *node;
      52             :     char       *operand;
      53             : } CHKVAL;
      54             : 
      55             : static bool
      56       16534 : checkcondition_str(void *checkval, ITEM *val)
      57             : {
      58       16534 :     ltree_level *level = LTREE_FIRST(((CHKVAL *) checkval)->node);
      59       16534 :     int         tlen = ((CHKVAL *) checkval)->node->numlevel;
      60       16534 :     char       *op = ((CHKVAL *) checkval)->operand + val->distance;
      61             :     int         (*cmpptr) (const char *, const char *, size_t);
      62             : 
      63       16534 :     cmpptr = (val->flag & LVAR_INCASE) ? ltree_strncasecmp : strncmp;
      64      128182 :     while (tlen > 0)
      65             :     {
      66       98956 :         if (val->flag & LVAR_SUBLEXEME)
      67             :         {
      68           8 :             if (compare_subnode(level, op, val->length, cmpptr, (val->flag & LVAR_ANYEND)))
      69           2 :                 return true;
      70             :         }
      71       98948 :         else if (
      72             :                  (
      73      137272 :                   val->length == level->len ||
      74       54722 :                   (level->len > val->length && (val->flag & LVAR_ANYEND))
      75       60636 :                   ) &&
      76       60636 :                  (*cmpptr) (op, level->name, val->length) == 0)
      77        3840 :             return true;
      78             : 
      79       95114 :         tlen--;
      80       95114 :         level = LEVEL_NEXT(level);
      81             :     }
      82             : 
      83       12692 :     return false;
      84             : }
      85             : 
      86             : Datum
      87       13454 : ltxtq_exec(PG_FUNCTION_ARGS)
      88             : {
      89       13454 :     ltree      *val = PG_GETARG_LTREE_P(0);
      90       13454 :     ltxtquery  *query = PG_GETARG_LTXTQUERY_P(1);
      91             :     CHKVAL      chkval;
      92             :     bool        result;
      93             : 
      94       13454 :     chkval.node = val;
      95       13454 :     chkval.operand = GETOPERAND(query);
      96             : 
      97       13454 :     result = ltree_execute(
      98             :                            GETQUERY(query),
      99             :                            &chkval,
     100             :                            true,
     101             :                            checkcondition_str
     102             :         );
     103             : 
     104       13454 :     PG_FREE_IF_COPY(val, 0);
     105       13454 :     PG_FREE_IF_COPY(query, 1);
     106       13454 :     PG_RETURN_BOOL(result);
     107             : }
     108             : 
     109             : Datum
     110           0 : ltxtq_rexec(PG_FUNCTION_ARGS)
     111             : {
     112           0 :     PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec,
     113             :                                         PG_GETARG_DATUM(1),
     114             :                                         PG_GETARG_DATUM(0)
     115             :                                         ));
     116             : }

Generated by: LCOV version 1.13