LCOV - differential code coverage report
Current view: top level - contrib/intarray - _int_bool.c (source / functions) Coverage Total Hit UBC CBC
Current: c38de3ae6098ccf1904109f2e550eb4777f66024 vs e352ac8c5c90ed6ce792f044c22145578542a330 Lines: 93.6 % 296 277 19 277
Current Date: 2026-11-05 14:14:01 +0100 Functions: 91.7 % 24 22 2 22
Baseline: lcov-20261105-baseline Branches: 74.6 % 209 156 53 156
Baseline Date: 2026-11-05 14:14:01 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 2 2 2
(30,360] days: 85.2 % 27 23 4 23
(360..) days: 94.4 % 267 252 15 252
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 91.3 % 23 21 2 21
Branch coverage date bins:
(7,30] days: 66.7 % 6 4 2 4
(30,360] days: 63.6 % 22 14 8 14
(360..) days: 76.2 % 181 138 43 138

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * contrib/intarray/_int_bool.c
                                  3                 :                :  */
                                  4                 :                : #include "postgres.h"
                                  5                 :                : 
                                  6                 :                : #include "_int.h"
                                  7                 :                : #include "miscadmin.h"
                                  8                 :                : 
 8548 bruce@momjian.us            9                 :CBC           2 : PG_FUNCTION_INFO_V1(bqarr_in);
                                 10                 :              2 : PG_FUNCTION_INFO_V1(bqarr_out);
                                 11                 :              2 : PG_FUNCTION_INFO_V1(boolop);
                                 12                 :              1 : PG_FUNCTION_INFO_V1(rboolop);
                                 13                 :              1 : PG_FUNCTION_INFO_V1(querytree);
                                 14                 :                : 
                                 15                 :                : 
                                 16                 :                : /* parser's states */
                                 17                 :                : #define WAITOPERAND 1
                                 18                 :                : #define WAITENDOPERAND  2
                                 19                 :                : #define WAITOPERATOR    3
                                 20                 :                : 
                                 21                 :                : /*
                                 22                 :                :  * node of query tree, also used
                                 23                 :                :  * for storing polish notation in parser
                                 24                 :                :  */
                                 25                 :                : typedef struct NODE
                                 26                 :                : {
                                 27                 :                :     int32       type;
                                 28                 :                :     int32       val;
                                 29                 :                :     struct NODE *next;
                                 30                 :                : } NODE;
                                 31                 :                : 
                                 32                 :                : typedef struct
                                 33                 :                : {
                                 34                 :                :     char       *buf;
                                 35                 :                :     int32       state;
                                 36                 :                :     int32       count;
                                 37                 :                :     struct Node *escontext;
                                 38                 :                :     /* reverse polish notation in list (for temporary usage) */
                                 39                 :                :     NODE       *str;
                                 40                 :                :     /* number in str */
                                 41                 :                :     int32       num;
                                 42                 :                : } WORKSTATE;
                                 43                 :                : 
                                 44                 :                : /*
                                 45                 :                :  * get token from query string
                                 46                 :                :  */
                                 47                 :                : static int32
 5246 peter_e@gmx.net            48                 :         131688 : gettoken(WORKSTATE *state, int32 *val)
                                 49                 :                : {
                                 50                 :                :     char        nnn[16];
                                 51                 :                :     int         innn;
                                 52                 :                : 
 7712 tgl@sss.pgh.pa.us          53                 :         131688 :     *val = 0;                   /* default result */
                                 54                 :                : 
 5761                            55                 :         131688 :     innn = 0;
                                 56                 :                :     while (1)
                                 57                 :                :     {
                                 58         [ -  + ]:         164904 :         if (innn >= sizeof(nnn))
 5761 tgl@sss.pgh.pa.us          59                 :UBC           0 :             return ERR;         /* buffer overrun => syntax error */
 8548 bruce@momjian.us           60   [ +  +  +  - ]:CBC      164904 :         switch (state->state)
                                 61                 :                :         {
                                 62                 :          65905 :             case WAITOPERAND:
 5761 tgl@sss.pgh.pa.us          63                 :          65905 :                 innn = 0;
 8548 bruce@momjian.us           64   [ +  +  +  + ]:          65905 :                 if ((*(state->buf) >= '0' && *(state->buf) <= '9') ||
                                 65         [ +  + ]:          32909 :                     *(state->buf) == '-')
                                 66                 :                :                 {
                                 67                 :          32997 :                     state->state = WAITENDOPERAND;
 5761 tgl@sss.pgh.pa.us          68                 :          32997 :                     nnn[innn++] = *(state->buf);
                                 69                 :                :                 }
 8548 bruce@momjian.us           70         [ +  + ]:          32908 :                 else if (*(state->buf) == '!')
                                 71                 :                :                 {
                                 72                 :             55 :                     (state->buf)++;
 5246 peter_e@gmx.net            73                 :             55 :                     *val = (int32) '!';
 8548 bruce@momjian.us           74                 :             55 :                     return OPR;
                                 75                 :                :                 }
                                 76         [ +  + ]:          32853 :                 else if (*(state->buf) == '(')
                                 77                 :                :                 {
                                 78                 :          32819 :                     state->count++;
                                 79                 :          32819 :                     (state->buf)++;
                                 80                 :          32819 :                     return OPEN;
                                 81                 :                :                 }
                                 82         [ +  + ]:             34 :                 else if (*(state->buf) != ' ')
                                 83                 :              2 :                     return ERR;
                                 84                 :          33029 :                 break;
                                 85                 :          33153 :             case WAITENDOPERAND:
                                 86   [ +  +  +  + ]:          33153 :                 if (*(state->buf) >= '0' && *(state->buf) <= '9')
                                 87                 :                :                 {
 5761 tgl@sss.pgh.pa.us          88                 :            156 :                     nnn[innn++] = *(state->buf);
                                 89                 :                :                 }
                                 90                 :                :                 else
                                 91                 :                :                 {
                                 92                 :                :                     long        lval;
                                 93                 :                :                     char       *endptr;
                                 94                 :                : 
                                 95                 :          32997 :                     nnn[innn] = '\0';
                                 96                 :          32997 :                     errno = 0;
   16                            97                 :          32997 :                     lval = strtol(nnn, &endptr, 10);
 5246 peter_e@gmx.net            98                 :          32997 :                     *val = (int32) lval;
   16 tgl@sss.pgh.pa.us          99   [ +  -  +  +  :          32997 :                     if (errno != 0 || *endptr != '\0' || (long) *val != lval)
                                              -  + ]
 5761                           100                 :              1 :                         return ERR;
 8548 bruce@momjian.us          101                 :          32996 :                     state->state = WAITOPERATOR;
                                102         [ -  + ]:          32858 :                     return (state->count && *(state->buf) == '\0')
                                103         [ +  + ]:          65854 :                         ? ERR : VAL;
                                104                 :                :                 }
                                105                 :            156 :                 break;
                                106                 :          65846 :             case WAITOPERATOR:
                                107   [ +  +  +  + ]:          65846 :                 if (*(state->buf) == '&' || *(state->buf) == '|')
                                108                 :                :                 {
                                109                 :          32904 :                     state->state = WAITOPERAND;
 5246 peter_e@gmx.net           110                 :          32904 :                     *val = (int32) *(state->buf);
 8548 bruce@momjian.us          111                 :          32904 :                     (state->buf)++;
                                112                 :          32904 :                     return OPR;
                                113                 :                :                 }
                                114         [ +  + ]:          32942 :                 else if (*(state->buf) == ')')
                                115                 :                :                 {
                                116                 :          32819 :                     (state->buf)++;
                                117                 :          32819 :                     state->count--;
                                118         [ -  + ]:          32819 :                     return (state->count < 0) ? ERR : CLOSE;
                                119                 :                :                 }
                                120         [ +  + ]:            123 :                 else if (*(state->buf) == '\0')
                                121                 :             90 :                     return (state->count) ? ERR : END;
                                122         [ +  + ]:             33 :                 else if (*(state->buf) != ' ')
                                123                 :              2 :                     return ERR;
                                124                 :             31 :                 break;
 8548 bruce@momjian.us          125                 :UBC           0 :             default:
                                126                 :              0 :                 return ERR;
                                127                 :                :                 break;
                                128                 :                :         }
 8548 bruce@momjian.us          129                 :CBC       33216 :         (state->buf)++;
                                130                 :                :     }
                                131                 :                : }
                                132                 :                : 
                                133                 :                : /*
                                134                 :                :  * push new one in polish notation reverse view
                                135                 :                :  */
                                136                 :                : static void
 5246 peter_e@gmx.net           137                 :          65955 : pushquery(WORKSTATE *state, int32 type, int32 val)
                                138                 :                : {
  335 michael@paquier.xyz       139                 :          65955 :     NODE       *tmp = palloc_object(NODE);
                                140                 :                : 
 8548 bruce@momjian.us          141                 :          65955 :     tmp->type = type;
                                142                 :          65955 :     tmp->val = val;
                                143                 :          65955 :     tmp->next = state->str;
                                144                 :          65955 :     state->str = tmp;
                                145                 :          65955 :     state->num++;
                                146                 :          65955 : }
                                147                 :                : 
                                148                 :                : #define STACKDEPTH  16
                                149                 :                : 
                                150                 :                : /*
                                151                 :                :  * make polish notation of query
                                152                 :                :  */
                                153                 :                : static int32
 6356                           154                 :          32914 : makepol(WORKSTATE *state)
                                155                 :                : {
                                156                 :                :     int32       val,
                                157                 :                :                 type;
                                158                 :                :     int32       stack[STACKDEPTH];
 5246 peter_e@gmx.net           159                 :          32914 :     int32       lenstack = 0;
                                160                 :                : 
                                161                 :                :     /* since this function recurses, it could be driven to stack overflow */
 5779 tgl@sss.pgh.pa.us         162                 :          32914 :     check_stack_depth();
                                163                 :                : 
 8548 bruce@momjian.us          164         [ +  + ]:         131688 :     while ((type = gettoken(state, &val)) != END)
                                165                 :                :     {
                                166   [ +  +  +  +  :         131598 :         switch (type)
                                                 + ]
                                167                 :                :         {
                                168                 :          32996 :             case VAL:
                                169                 :          32996 :                 pushquery(state, type, val);
 5246 peter_e@gmx.net           170   [ +  +  +  + ]:          49484 :                 while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
                                171         [ +  + ]:             97 :                                     stack[lenstack - 1] == (int32) '!'))
                                172                 :                :                 {
 8548 bruce@momjian.us          173                 :          16488 :                     lenstack--;
                                174                 :          16488 :                     pushquery(state, OPR, stack[lenstack]);
                                175                 :                :                 }
                                176                 :          32996 :                 break;
                                177                 :          32959 :             case OPR:
 5246 peter_e@gmx.net           178   [ +  +  +  + ]:          32959 :                 if (lenstack && val == (int32) '|')
 8548 bruce@momjian.us          179                 :              3 :                     pushquery(state, OPR, val);
                                180                 :                :                 else
                                181                 :                :                 {
                                182         [ -  + ]:          32956 :                     if (lenstack == STACKDEPTH)
 1408 andrew@dunslane.net       183         [ #  # ]:UBC           0 :                         ereturn(state->escontext, ERR,
                                184                 :                :                                 (errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
                                185                 :                :                                  errmsg("statement too complex")));
 8548 bruce@momjian.us          186                 :CBC       32956 :                     stack[lenstack] = val;
                                187                 :          32956 :                     lenstack++;
                                188                 :                :                 }
                                189                 :          32959 :                 break;
                                190                 :          32819 :             case OPEN:
                                191         [ -  + ]:          32819 :                 if (makepol(state) == ERR)
 8548 bruce@momjian.us          192                 :UBC           0 :                     return ERR;
 5246 peter_e@gmx.net           193   [ +  +  +  + ]:CBC       49232 :                 while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
                                194         [ +  + ]:             20 :                                     stack[lenstack - 1] == (int32) '!'))
                                195                 :                :                 {
 8548 bruce@momjian.us          196                 :          16413 :                     lenstack--;
                                197                 :          16413 :                     pushquery(state, OPR, stack[lenstack]);
                                198                 :                :                 }
                                199                 :          32819 :                 break;
                                200                 :          32819 :             case CLOSE:
                                201         [ +  + ]:          32840 :                 while (lenstack)
                                202                 :                :                 {
                                203                 :             21 :                     lenstack--;
                                204                 :             21 :                     pushquery(state, OPR, stack[lenstack]);
                                205                 :                :                 };
                                206                 :          32819 :                 return END;
                                207                 :                :                 break;
                                208                 :              5 :             case ERR:
                                209                 :                :             default:
 1408 andrew@dunslane.net       210         [ +  + ]:              5 :                 ereturn(state->escontext, ERR,
                                211                 :                :                         (errcode(ERRCODE_SYNTAX_ERROR),
                                212                 :                :                          errmsg("syntax error")));
                                213                 :                :         }
                                214                 :                :     }
                                215                 :                : 
 8548 bruce@momjian.us          216         [ +  + ]:            124 :     while (lenstack)
                                217                 :                :     {
                                218                 :             34 :         lenstack--;
                                219                 :             34 :         pushquery(state, OPR, stack[lenstack]);
                                220                 :                :     };
                                221                 :             90 :     return END;
                                222                 :                : }
                                223                 :                : 
                                224                 :                : typedef struct
                                225                 :                : {
                                226                 :                :     int32      *arrb;
                                227                 :                :     int32      *arre;
                                228                 :                : } CHKVAL;
                                229                 :                : 
                                230                 :                : /*
                                231                 :                :  * is there value 'val' in (sorted) array or not ?
                                232                 :                :  */
                                233                 :                : static bool
 2411 akorotkov@postgresql      234                 :         314649 : checkcondition_arr(void *checkval, ITEM *item, void *options)
                                235                 :                : {
 5246 peter_e@gmx.net           236                 :         314649 :     int32      *StopLow = ((CHKVAL *) checkval)->arrb;
                                237                 :         314649 :     int32      *StopHigh = ((CHKVAL *) checkval)->arre;
                                238                 :                :     int32      *StopMiddle;
                                239                 :                : 
                                240                 :                :     /* Loop invariant: StopLow <= val < StopHigh */
                                241                 :                : 
 8548 bruce@momjian.us          242         [ +  + ]:        1129023 :     while (StopLow < StopHigh)
                                243                 :                :     {
                                244                 :         827025 :         StopMiddle = StopLow + (StopHigh - StopLow) / 2;
 7491 teodor@sigaev.ru          245         [ +  + ]:         827025 :         if (*StopMiddle == item->val)
 3367 peter_e@gmx.net           246                 :          12651 :             return true;
 7491 teodor@sigaev.ru          247         [ +  + ]:         814374 :         else if (*StopMiddle < item->val)
 8548 bruce@momjian.us          248                 :         238199 :             StopLow = StopMiddle + 1;
                                249                 :                :         else
                                250                 :         576175 :             StopHigh = StopMiddle;
                                251                 :                :     }
                                252                 :         301998 :     return false;
                                253                 :                : }
                                254                 :                : 
                                255                 :                : static bool
 2411 akorotkov@postgresql      256                 :          44732 : checkcondition_bit(void *checkval, ITEM *item, void *siglen)
                                257                 :                : {
 2366 tgl@sss.pgh.pa.us         258                 :          44732 :     return GETBIT(checkval, HASHVAL(item->val, (int) (intptr_t) siglen));
                                259                 :                : }
                                260                 :                : 
                                261                 :                : /*
                                262                 :                :  * evaluate boolean expression, using chkcond() to test the primitive cases
                                263                 :                :  */
                                264                 :                : static bool
 2411 akorotkov@postgresql      265                 :         884034 : execute(ITEM *curitem, void *checkval, void *options, bool calcnot,
                                266                 :                :         bool (*chkcond) (void *checkval, ITEM *item, void *options))
                                267                 :                : {
                                268                 :                :     /* since this function recurses, it could be driven to stack overflow */
 5779 tgl@sss.pgh.pa.us         269                 :         884034 :     check_stack_depth();
                                270                 :                : 
 8548 bruce@momjian.us          271         [ +  + ]:         884034 :     if (curitem->type == VAL)
 2411 akorotkov@postgresql      272                 :         388422 :         return (*chkcond) (checkval, curitem, options);
 5246 peter_e@gmx.net           273         [ +  + ]:         495612 :     else if (curitem->val == (int32) '!')
                                274                 :                :     {
                                275                 :                :         return calcnot ?
 2411 akorotkov@postgresql      276                 :         153511 :             ((execute(curitem - 1, checkval, options, calcnot, chkcond)) ? false : true)
 8548 bruce@momjian.us          277   [ +  +  +  + ]:         361938 :             : true;
                                278                 :                :     }
 5246 peter_e@gmx.net           279         [ +  + ]:         287185 :     else if (curitem->val == (int32) '&')
                                280                 :                :     {
 2411 akorotkov@postgresql      281         [ +  + ]:         153306 :         if (execute(curitem + curitem->left, checkval, options, calcnot, chkcond))
                                282                 :          85603 :             return execute(curitem - 1, checkval, options, calcnot, chkcond);
                                283                 :                :         else
 8548 bruce@momjian.us          284                 :          67703 :             return false;
                                285                 :                :     }
                                286                 :                :     else
                                287                 :                :     {                           /* |-operator */
 2411 akorotkov@postgresql      288         [ +  + ]:         133879 :         if (execute(curitem + curitem->left, checkval, options, calcnot, chkcond))
 8548 bruce@momjian.us          289                 :           6820 :             return true;
                                290                 :                :         else
 2411 akorotkov@postgresql      291                 :         127059 :             return execute(curitem - 1, checkval, options, calcnot, chkcond);
                                292                 :                :     }
                                293                 :                : }
                                294                 :                : 
                                295                 :                : /*
                                296                 :                :  * signconsistent & execconsistent called by *_consistent
                                297                 :                :  */
                                298                 :                : bool
                                299                 :          51018 : signconsistent(QUERYTYPE *query, BITVECP sign, int siglen, bool calcnot)
                                300                 :                : {
 5779 tgl@sss.pgh.pa.us         301                 :         102036 :     return execute(GETQUERY(query) + query->size - 1,
  707 peter@eisentraut.org      302                 :          51018 :                    sign, (void *) (intptr_t) siglen, calcnot,
                                303                 :                :                    checkcondition_bit);
                                304                 :                : }
                                305                 :                : 
                                306                 :                : /* Array must be sorted! */
                                307                 :                : bool
 6356 bruce@momjian.us          308                 :          82741 : execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot)
                                309                 :                : {
                                310                 :                :     CHKVAL      chkval;
                                311                 :                : 
 7656 tgl@sss.pgh.pa.us         312   [ -  +  -  -  :          82741 :     CHECKARRVALID(array);
                                              -  - ]
 8548 bruce@momjian.us          313         [ -  + ]:          82741 :     chkval.arrb = ARRPTR(array);
                                314                 :          82741 :     chkval.arre = chkval.arrb + ARRNELEMS(array);
 5779 tgl@sss.pgh.pa.us         315                 :          82741 :     return execute(GETQUERY(query) + query->size - 1,
                                316                 :                :                    &chkval, NULL, calcnot,
                                317                 :                :                    checkcondition_arr);
                                318                 :                : }
                                319                 :                : 
                                320                 :                : typedef struct
                                321                 :                : {
                                322                 :                :     ITEM       *first;
                                323                 :                :     bool       *mapped_check;
                                324                 :                : } GinChkVal;
                                325                 :                : 
                                326                 :                : static bool
 2411 akorotkov@postgresql      327                 :          29041 : checkcondition_gin(void *checkval, ITEM *item, void *options)
                                328                 :                : {
 7337 bruce@momjian.us          329                 :          29041 :     GinChkVal  *gcv = (GinChkVal *) checkval;
                                330                 :                : 
                                331                 :          29041 :     return gcv->mapped_check[item - gcv->first];
                                332                 :                : }
                                333                 :                : 
                                334                 :                : bool
 5779 tgl@sss.pgh.pa.us         335                 :          14919 : gin_bool_consistent(QUERYTYPE *query, bool *check)
                                336                 :                : {
                                337                 :                :     GinChkVal   gcv;
 7337 bruce@momjian.us          338                 :          14919 :     ITEM       *items = GETQUERY(query);
                                339                 :                :     int         i,
                                340                 :          14919 :                 j = 0;
                                341                 :                : 
 5779 tgl@sss.pgh.pa.us         342         [ -  + ]:          14919 :     if (query->size <= 0)
 3368 peter_e@gmx.net           343                 :UBC           0 :         return false;
                                344                 :                : 
                                345                 :                :     /*
                                346                 :                :      * Set up data for checkcondition_gin.  This must agree with the query
                                347                 :                :      * extraction code in ginint4_queryextract.
                                348                 :                :      */
 7491 teodor@sigaev.ru          349                 :CBC       14919 :     gcv.first = items;
  335 michael@paquier.xyz       350                 :          14919 :     gcv.mapped_check = palloc_array(bool, query->size);
 7337 bruce@momjian.us          351         [ +  + ]:          82333 :     for (i = 0; i < query->size; i++)
                                352                 :                :     {
                                353         [ +  + ]:          67414 :         if (items[i].type == VAL)
                                354                 :          31016 :             gcv.mapped_check[i] = check[j++];
                                355                 :                :     }
                                356                 :                : 
 5779 tgl@sss.pgh.pa.us         357                 :          14919 :     return execute(GETQUERY(query) + query->size - 1,
                                358                 :                :                    &gcv, NULL, true,
                                359                 :                :                    checkcondition_gin);
                                360                 :                : }
                                361                 :                : 
                                362                 :                : static bool
                                363                 :             46 : contains_required_value(ITEM *curitem)
                                364                 :                : {
                                365                 :                :     /* since this function recurses, it could be driven to stack overflow */
                                366                 :             46 :     check_stack_depth();
                                367                 :                : 
                                368         [ +  + ]:             46 :     if (curitem->type == VAL)
                                369                 :             18 :         return true;
 5246 peter_e@gmx.net           370         [ +  + ]:             28 :     else if (curitem->val == (int32) '!')
                                371                 :                :     {
                                372                 :                :         /*
                                373                 :                :          * Assume anything under a NOT is non-required.  For some cases with
                                374                 :                :          * nested NOTs, we could prove there's a required value, but it seems
                                375                 :                :          * unlikely to be worth the trouble.
                                376                 :                :          */
 5779 tgl@sss.pgh.pa.us         377                 :              8 :         return false;
                                378                 :                :     }
 5246 peter_e@gmx.net           379         [ +  + ]:             20 :     else if (curitem->val == (int32) '&')
                                380                 :                :     {
                                381                 :                :         /* If either side has a required value, we're good */
 5779 tgl@sss.pgh.pa.us         382         [ +  + ]:             12 :         if (contains_required_value(curitem + curitem->left))
                                383                 :              8 :             return true;
                                384                 :                :         else
                                385                 :              4 :             return contains_required_value(curitem - 1);
                                386                 :                :     }
                                387                 :                :     else
                                388                 :                :     {                           /* |-operator */
                                389                 :                :         /* Both sides must have required values */
                                390         [ +  - ]:              8 :         if (contains_required_value(curitem + curitem->left))
                                391                 :              8 :             return contains_required_value(curitem - 1);
                                392                 :                :         else
 5779 tgl@sss.pgh.pa.us         393                 :UBC           0 :             return false;
                                394                 :                :     }
                                395                 :                : }
                                396                 :                : 
                                397                 :                : bool
 5779 tgl@sss.pgh.pa.us         398                 :CBC          14 : query_has_required_values(QUERYTYPE *query)
                                399                 :                : {
                                400         [ -  + ]:             14 :     if (query->size <= 0)
 5779 tgl@sss.pgh.pa.us         401                 :UBC           0 :         return false;
 5779 tgl@sss.pgh.pa.us         402                 :CBC          14 :     return contains_required_value(GETQUERY(query) + query->size - 1);
                                403                 :                : }
                                404                 :                : 
                                405                 :                : /*
                                406                 :                :  * boolean operations
                                407                 :                :  */
                                408                 :                : Datum
 8548 bruce@momjian.us          409                 :UBC           0 : rboolop(PG_FUNCTION_ARGS)
                                410                 :                : {
                                411                 :                :     /* just reverse the operands */
 5779 tgl@sss.pgh.pa.us         412                 :              0 :     return DirectFunctionCall2(boolop,
                                413                 :                :                                PG_GETARG_DATUM(1),
                                414                 :                :                                PG_GETARG_DATUM(0));
                                415                 :                : }
                                416                 :                : 
                                417                 :                : Datum
 8548 bruce@momjian.us          418                 :CBC       81998 : boolop(PG_FUNCTION_ARGS)
                                419                 :                : {
 5779 tgl@sss.pgh.pa.us         420                 :          81998 :     ArrayType  *val = PG_GETARG_ARRAYTYPE_P_COPY(0);
                                421                 :          81998 :     QUERYTYPE  *query = PG_GETARG_QUERYTYPE_P(1);
                                422                 :                :     CHKVAL      chkval;
                                423                 :                :     bool        result;
                                424                 :                : 
 7656                           425   [ -  +  -  -  :          81998 :     CHECKARRVALID(val);
                                              -  - ]
 8548 bruce@momjian.us          426         [ -  + ]:          81998 :     PREPAREARR(val);
                                427         [ -  + ]:          81998 :     chkval.arrb = ARRPTR(val);
                                428                 :          81998 :     chkval.arre = chkval.arrb + ARRNELEMS(val);
 5779 tgl@sss.pgh.pa.us         429                 :          81998 :     result = execute(GETQUERY(query) + query->size - 1,
                                430                 :                :                      &chkval, NULL, true,
                                431                 :                :                      checkcondition_arr);
 8548 bruce@momjian.us          432                 :          81998 :     pfree(val);
                                433                 :                : 
                                434         [ -  + ]:          81998 :     PG_FREE_IF_COPY(query, 1);
                                435                 :          81998 :     PG_RETURN_BOOL(result);
                                436                 :                : }
                                437                 :                : 
                                438                 :                : /*
                                439                 :                :  * Recursively fill the "left" fields of an ITEM array that represents
                                440                 :                :  * a valid postfix tree.
                                441                 :                :  *
                                442                 :                :  *  state: only needed for error reporting
                                443                 :                :  *  ptr: starting element of array
                                444                 :                :  *  pos: in/out argument, the array index this call is responsible to fill
                                445                 :                :  *
                                446                 :                :  * At exit, *pos has been decremented to point before the sub-tree whose
                                447                 :                :  * top is the entry-time value of *pos.
                                448                 :                :  *
                                449                 :                :  * Returns true if okay, false if error (the only possible error is
                                450                 :                :  * overflow of a "left" field).
                                451                 :                :  */
                                452                 :                : static bool
  178 tgl@sss.pgh.pa.us         453                 :          65952 : findoprnd(WORKSTATE *state, ITEM *ptr, int32 *pos)
                                454                 :                : {
                                455                 :                :     int32       mypos;
                                456                 :                : 
                                457                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 4644 noah@leadboat.com         458                 :          65952 :     check_stack_depth();
                                459                 :                : 
                                460                 :                :     /* get the position this call is supposed to update */
  178 tgl@sss.pgh.pa.us         461                 :          65952 :     mypos = *pos;
                                462         [ -  + ]:          65952 :     Assert(mypos >= 0);
                                463                 :                : 
                                464                 :                :     /* in all cases, we should decrement *pos to advance over this item */
                                465                 :          65952 :     (*pos)--;
                                466                 :                : 
                                467                 :                : #ifdef BS_DEBUG
                                468                 :                :     elog(DEBUG3, (ptr[mypos].type == OPR) ?
                                469                 :                :          "%d  %c" : "%d  %d", mypos, ptr[mypos].val);
                                470                 :                : #endif
                                471                 :                : 
                                472         [ +  + ]:          65952 :     if (ptr[mypos].type == VAL)
                                473                 :                :     {
                                474                 :                :         /* base case: a VAL has no operand, so just set its left to zero */
                                475                 :          32993 :         ptr[mypos].left = 0;
                                476                 :                :     }
                                477         [ +  + ]:          32959 :     else if (ptr[mypos].val == (int32) '!')
                                478                 :                :     {
                                479                 :                :         /* unary operator, likewise easy: operand is just before it */
                                480                 :             55 :         ptr[mypos].left = -1;
                                481                 :                :         /* recurse to scan operand */
                                482         [ -  + ]:             55 :         if (!findoprnd(state, ptr, pos))
  178 tgl@sss.pgh.pa.us         483                 :UBC           0 :             return false;
                                484                 :                :     }
                                485                 :                :     else
                                486                 :                :     {
                                487                 :                :         /* binary operator */
                                488                 :                :         int32       delta;
                                489                 :                : 
                                490                 :                :         /* recurse to scan right operand */
  178 tgl@sss.pgh.pa.us         491         [ -  + ]:CBC       32904 :         if (!findoprnd(state, ptr, pos))
  178 tgl@sss.pgh.pa.us         492                 :UBC           0 :             return false;
                                493                 :                :         /* we must fill left with offset to left operand's top */
                                494                 :                :         /* abs(delta) < QUERYTYPEMAXITEMS, so it can't overflow ... */
  178 tgl@sss.pgh.pa.us         495                 :CBC       32904 :         delta = *pos - mypos;
                                496                 :                :         /* ... but it might be too large to fit in the 16-bit left field */
                                497         [ -  + ]:          32904 :         Assert(delta < 0);
                                498         [ +  + ]:          32904 :         if (unlikely(delta < PG_INT16_MIN))
                                499         [ +  - ]:              1 :             ereturn(state->escontext, false,
                                500                 :                :                     (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                501                 :                :                      errmsg("query_int expression is too complex")));
                                502                 :          32903 :         ptr[mypos].left = (int16) delta;
                                503                 :                :         /* recurse to scan left operand */
                                504         [ -  + ]:          32903 :         if (!findoprnd(state, ptr, pos))
  178 tgl@sss.pgh.pa.us         505                 :UBC           0 :             return false;
                                506                 :                :     }
                                507                 :                : 
  178 tgl@sss.pgh.pa.us         508                 :CBC       65951 :     return true;
                                509                 :                : }
                                510                 :                : 
                                511                 :                : 
                                512                 :                : /*
                                513                 :                :  * input
                                514                 :                :  */
                                515                 :                : Datum
 8548 bruce@momjian.us          516                 :             95 : bqarr_in(PG_FUNCTION_ARGS)
                                517                 :                : {
                                518                 :             95 :     char       *buf = (char *) PG_GETARG_POINTER(0);
                                519                 :                :     WORKSTATE   state;
                                520                 :                :     int32       i;
                                521                 :                :     QUERYTYPE  *query;
                                522                 :                :     int32       commonlen;
                                523                 :                :     ITEM       *ptr;
                                524                 :                :     NODE       *tmp;
 5246 peter_e@gmx.net           525                 :             95 :     int32       pos = 0;
 1408 andrew@dunslane.net       526                 :             95 :     struct Node *escontext = fcinfo->context;
                                527                 :                : 
                                528                 :                : #ifdef BS_DEBUG
                                529                 :                :     StringInfoData pbuf;
                                530                 :                : #endif
                                531                 :                : 
 8548 bruce@momjian.us          532                 :             95 :     state.buf = buf;
                                533                 :             95 :     state.state = WAITOPERAND;
                                534                 :             95 :     state.count = 0;
                                535                 :             95 :     state.num = 0;
                                536                 :             95 :     state.str = NULL;
 1408 andrew@dunslane.net       537                 :             95 :     state.escontext = escontext;
                                538                 :                : 
                                539                 :                :     /* make polish notation (postfix, but in reverse order) */
                                540         [ +  + ]:             95 :     if (makepol(&state) == ERR)
                                541                 :              4 :         PG_RETURN_NULL();
 8548 bruce@momjian.us          542         [ -  + ]:             90 :     if (!state.num)
 1408 andrew@dunslane.net       543         [ #  # ]:UBC           0 :         ereturn(escontext, (Datum) 0,
                                544                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                545                 :                :                  errmsg("empty query")));
                                546                 :                : 
 4644 noah@leadboat.com         547         [ -  + ]:CBC          90 :     if (state.num > QUERYTYPEMAXITEMS)
 1408 andrew@dunslane.net       548         [ #  # ]:UBC           0 :         ereturn(escontext, (Datum) 0,
                                549                 :                :                 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                550                 :                :                  errmsg("number of query items (%d) exceeds the maximum allowed (%d)",
                                551                 :                :                         state.num, (int) QUERYTYPEMAXITEMS)));
 8548 bruce@momjian.us          552                 :CBC          90 :     commonlen = COMPUTESIZE(state.num);
                                553                 :                : 
                                554                 :             90 :     query = (QUERYTYPE *) palloc(commonlen);
 7190 tgl@sss.pgh.pa.us         555                 :             90 :     SET_VARSIZE(query, commonlen);
 8548 bruce@momjian.us          556                 :             90 :     query->size = state.num;
                                557                 :             90 :     ptr = GETQUERY(query);
                                558                 :                : 
                                559                 :                :     /* fill the query array from the data makepol constructed */
                                560         [ +  + ]:          66043 :     for (i = state.num - 1; i >= 0; i--)
                                561                 :                :     {
                                562                 :          65953 :         ptr[i].type = state.str->type;
                                563                 :          65953 :         ptr[i].val = state.str->val;
                                564                 :          65953 :         tmp = state.str->next;
                                565                 :          65953 :         pfree(state.str);
                                566                 :          65953 :         state.str = tmp;
                                567                 :                :     }
                                568                 :                : 
                                569                 :                :     /* now fill the "left" fields */
                                570                 :             90 :     pos = query->size - 1;
  178 tgl@sss.pgh.pa.us         571         [ -  + ]:             90 :     if (!findoprnd(&state, ptr, &pos))
  178 tgl@sss.pgh.pa.us         572                 :UBC           0 :         PG_RETURN_NULL();
                                573                 :                :     /* if successful, findoprnd should have scanned the whole array */
  178 tgl@sss.pgh.pa.us         574         [ -  + ]:CBC          89 :     Assert(pos == -1);
                                575                 :                : 
                                576                 :                : #ifdef BS_DEBUG
                                577                 :                :     initStringInfo(&pbuf);
                                578                 :                :     for (i = 0; i < query->size; i++)
                                579                 :                :     {
                                580                 :                :         if (ptr[i].type == OPR)
                                581                 :                :             appendStringInfo(&pbuf, "%c(%d) ", ptr[i].val, ptr[i].left);
                                582                 :                :         else
                                583                 :                :             appendStringInfo(&pbuf, "%d ", ptr[i].val);
                                584                 :                :     }
                                585                 :                :     elog(DEBUG3, "POR: %s", pbuf.data);
                                586                 :                :     pfree(pbuf.data);
                                587                 :                : #endif
                                588                 :                : 
 8548 bruce@momjian.us          589                 :             89 :     PG_RETURN_POINTER(query);
                                590                 :                : }
                                591                 :                : 
                                592                 :                : 
                                593                 :                : /*
                                594                 :                :  * out function
                                595                 :                :  */
                                596                 :                : typedef struct
                                597                 :                : {
                                598                 :                :     ITEM       *curpol;
                                599                 :                :     char       *buf;
                                600                 :                :     char       *cur;
                                601                 :                :     int32       buflen;
                                602                 :                : } INFIX;
                                603                 :                : 
                                604                 :                : #define RESIZEBUF(inf,addsize) while( ( (inf)->cur - (inf)->buf ) + (addsize) + 1 >= (inf)->buflen ) { \
                                605                 :                :     int32 len = inf->cur - inf->buf; \
                                606                 :                :     inf->buflen *= 2; \
                                607                 :                :     inf->buf = (char*) repalloc( (void*)inf->buf, inf->buflen ); \
                                608                 :                :     inf->cur = inf->buf + len; \
                                609                 :                : }
                                610                 :                : 
                                611                 :                : static void
 6930                           612                 :            181 : infix(INFIX *in, bool first)
                                613                 :                : {
                                614                 :                :     /* since this function recurses, it could be driven to stack overflow. */
 4049 noah@leadboat.com         615                 :            181 :     check_stack_depth();
                                616                 :                : 
 8548 bruce@momjian.us          617         [ +  + ]:            181 :     if (in->curpol->type == VAL)
                                618                 :                :     {
                                619         [ -  + ]:             96 :         RESIZEBUF(in, 11);
                                620                 :             96 :         sprintf(in->cur, "%d", in->curpol->val);
                                621                 :             96 :         in->cur = strchr(in->cur, '\0');
                                622                 :             96 :         in->curpol--;
                                623                 :                :     }
 5246 peter_e@gmx.net           624         [ +  + ]:             85 :     else if (in->curpol->val == (int32) '!')
                                625                 :                :     {
 8548 bruce@momjian.us          626                 :             27 :         bool        isopr = false;
                                627                 :                : 
                                628         [ -  + ]:             27 :         RESIZEBUF(in, 1);
                                629                 :             27 :         *(in->cur) = '!';
                                630                 :             27 :         in->cur++;
                                631                 :             27 :         *(in->cur) = '\0';
                                632                 :             27 :         in->curpol--;
                                633         [ +  + ]:             27 :         if (in->curpol->type == OPR)
                                634                 :                :         {
                                635                 :              6 :             isopr = true;
                                636         [ -  + ]:              6 :             RESIZEBUF(in, 2);
                                637                 :              6 :             sprintf(in->cur, "( ");
                                638                 :              6 :             in->cur = strchr(in->cur, '\0');
                                639                 :                :         }
                                640                 :             27 :         infix(in, isopr);
                                641         [ +  + ]:             27 :         if (isopr)
                                642                 :                :         {
                                643         [ -  + ]:              6 :             RESIZEBUF(in, 2);
                                644                 :              6 :             sprintf(in->cur, " )");
                                645                 :              6 :             in->cur = strchr(in->cur, '\0');
                                646                 :                :         }
                                647                 :                :     }
                                648                 :                :     else
                                649                 :                :     {
 5246 peter_e@gmx.net           650                 :             58 :         int32       op = in->curpol->val;
                                651                 :                :         INFIX       nrm;
                                652                 :                : 
 8548 bruce@momjian.us          653                 :             58 :         in->curpol--;
 5246 peter_e@gmx.net           654   [ +  +  +  + ]:             58 :         if (op == (int32) '|' && !first)
                                655                 :                :         {
 8548 bruce@momjian.us          656         [ -  + ]:             10 :             RESIZEBUF(in, 2);
                                657                 :             10 :             sprintf(in->cur, "( ");
                                658                 :             10 :             in->cur = strchr(in->cur, '\0');
                                659                 :                :         }
                                660                 :                : 
                                661                 :             58 :         nrm.curpol = in->curpol;
                                662                 :             58 :         nrm.buflen = 16;
  335 michael@paquier.xyz       663                 :             58 :         nrm.cur = nrm.buf = palloc_array(char, nrm.buflen);
                                664                 :                : 
                                665                 :                :         /* get right operand */
 8548 bruce@momjian.us          666                 :             58 :         infix(&nrm, false);
                                667                 :                : 
                                668                 :                :         /* get & print left operand */
                                669                 :             58 :         in->curpol = nrm.curpol;
                                670                 :             58 :         infix(in, false);
                                671                 :                : 
                                672                 :                :         /* print operator & right operand */
                                673         [ +  + ]:             62 :         RESIZEBUF(in, 3 + (nrm.cur - nrm.buf));
                                674                 :             58 :         sprintf(in->cur, " %c %s", op, nrm.buf);
                                675                 :             58 :         in->cur = strchr(in->cur, '\0');
                                676                 :             58 :         pfree(nrm.buf);
                                677                 :                : 
 5246 peter_e@gmx.net           678   [ +  +  +  + ]:             58 :         if (op == (int32) '|' && !first)
                                679                 :                :         {
 8548 bruce@momjian.us          680         [ -  + ]:             10 :             RESIZEBUF(in, 2);
                                681                 :             10 :             sprintf(in->cur, " )");
                                682                 :             10 :             in->cur = strchr(in->cur, '\0');
                                683                 :                :         }
                                684                 :                :     }
                                685                 :            181 : }
                                686                 :                : 
                                687                 :                : 
                                688                 :                : Datum
                                689                 :             38 : bqarr_out(PG_FUNCTION_ARGS)
                                690                 :                : {
 5779 tgl@sss.pgh.pa.us         691                 :             38 :     QUERYTYPE  *query = PG_GETARG_QUERYTYPE_P(0);
                                692                 :                :     INFIX       nrm;
                                693                 :                : 
 8548 bruce@momjian.us          694         [ -  + ]:             38 :     if (query->size == 0)
 8505 tgl@sss.pgh.pa.us         695         [ #  # ]:UBC           0 :         ereport(ERROR,
                                696                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                697                 :                :                  errmsg("empty query")));
                                698                 :                : 
 8548 bruce@momjian.us          699                 :CBC          38 :     nrm.curpol = GETQUERY(query) + query->size - 1;
                                700                 :             38 :     nrm.buflen = 32;
  335 michael@paquier.xyz       701                 :             38 :     nrm.cur = nrm.buf = palloc_array(char, nrm.buflen);
 8548 bruce@momjian.us          702                 :             38 :     *(nrm.cur) = '\0';
                                703                 :             38 :     infix(&nrm, true);
                                704                 :                : 
                                705         [ -  + ]:             38 :     PG_FREE_IF_COPY(query, 0);
                                706                 :             38 :     PG_RETURN_POINTER(nrm.buf);
                                707                 :                : }
                                708                 :                : 
                                709                 :                : 
                                710                 :                : /* Useless old "debugging" function for a fundamentally wrong algorithm */
                                711                 :                : Datum
 8548 bruce@momjian.us          712                 :UBC           0 : querytree(PG_FUNCTION_ARGS)
                                713                 :                : {
 5779 tgl@sss.pgh.pa.us         714         [ #  # ]:              0 :     elog(ERROR, "querytree is no longer implemented");
                                715                 :                :     PG_RETURN_NULL();
                                716                 :                : }
        

Generated by: LCOV version 2.0-1