LCOV - code coverage report
Current view: top level - contrib/ltree - ltxtquery_op.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 41 43 95.3 %
Date: 2024-11-21 08:14:44 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       51488 : 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       51488 :     check_stack_depth();
      24             : 
      25       51488 :     if (curitem->type == VAL)
      26       29404 :         return (*chkcond) (checkval, curitem);
      27       22084 :     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       22078 :     else if (curitem->val == (int32) '&')
      34             :     {
      35       22074 :         if (ltree_execute(curitem + curitem->left, checkval, calcnot, chkcond))
      36        7324 :             return ltree_execute(curitem + 1, checkval, calcnot, chkcond);
      37             :         else
      38       14750 :             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       21526 : checkcondition_str(void *checkval, ITEM *val)
      57             : {
      58       21526 :     ltree_level *level = LTREE_FIRST(((CHKVAL *) checkval)->node);
      59       21526 :     int         tlen = ((CHKVAL *) checkval)->node->numlevel;
      60       21526 :     char       *op = ((CHKVAL *) checkval)->operand + val->distance;
      61             :     int         (*cmpptr) (const char *, const char *, size_t);
      62             : 
      63       21526 :     cmpptr = (val->flag & LVAR_INCASE) ? ltree_strncasecmp : strncmp;
      64      144610 :     while (tlen > 0)
      65             :     {
      66      128384 :         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      128376 :         else if ((val->length == level->len ||
      72      128388 :                   (level->len > val->length && (val->flag & LVAR_ANYEND))) &&
      73       78212 :                  (*cmpptr) (op, level->name, val->length) == 0)
      74        5298 :             return true;
      75             : 
      76      123084 :         tlen--;
      77      123084 :         level = LEVEL_NEXT(level);
      78             :     }
      79             : 
      80       16226 :     return false;
      81             : }
      82             : 
      83             : Datum
      84       17360 : ltxtq_exec(PG_FUNCTION_ARGS)
      85             : {
      86       17360 :     ltree      *val = PG_GETARG_LTREE_P(0);
      87       17360 :     ltxtquery  *query = PG_GETARG_LTXTQUERY_P(1);
      88             :     CHKVAL      chkval;
      89             :     bool        result;
      90             : 
      91       17360 :     chkval.node = val;
      92       17360 :     chkval.operand = GETOPERAND(query);
      93             : 
      94       17360 :     result = ltree_execute(GETQUERY(query),
      95             :                            &chkval,
      96             :                            true,
      97             :                            checkcondition_str);
      98             : 
      99       17360 :     PG_FREE_IF_COPY(val, 0);
     100       17360 :     PG_FREE_IF_COPY(query, 1);
     101       17360 :     PG_RETURN_BOOL(result);
     102             : }
     103             : 
     104             : Datum
     105           0 : ltxtq_rexec(PG_FUNCTION_ARGS)
     106             : {
     107           0 :     PG_RETURN_DATUM(DirectFunctionCall2(ltxtq_exec,
     108             :                                         PG_GETARG_DATUM(1),
     109             :                                         PG_GETARG_DATUM(0)
     110             :                                         ));
     111             : }

Generated by: LCOV version 1.14