LCOV - differential code coverage report
Current view: top level - src/fe_utils - conditional.c (source / functions) Coverage Total Hit UBC CBC
Current: ba12a202ce1b5581dc0ed149cf3f637d7897ad5d vs 2866d8c7dbfc9d882a7d80fef93fbbe763709932 Lines: 81.9 % 72 59 13 59
Current Date: 2026-08-27 14:31:44 +0300 Functions: 92.9 % 14 13 1 13
Baseline: lcov-20260827-baseline Branches: 68.8 % 32 22 10 22
Baseline Date: 2026-08-27 14:31:58 +0300 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 90.0 % 10 9 1 9
(30,360] days: 100.0 % 2 2 2
(360..) days: 80.0 % 60 48 12 48
Function coverage date bins:
(7,30] days: 100.0 % 2 2 2
(360..) days: 91.7 % 12 11 1 11
Branch coverage date bins:
(7,30] days: 100.0 % 4 4 4
(360..) days: 64.3 % 28 18 10 18

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  * A stack of automaton states to handle nested conditionals.
                                  3                 :                :  *
                                  4                 :                :  * Copyright (c) 2000-2026, PostgreSQL Global Development Group
                                  5                 :                :  *
                                  6                 :                :  * src/fe_utils/conditional.c
                                  7                 :                :  *
                                  8                 :                :  *-------------------------------------------------------------------------
                                  9                 :                :  */
                                 10                 :                : #include "postgres_fe.h"
                                 11                 :                : 
                                 12                 :                : #include "fe_utils/conditional.h"
                                 13                 :                : 
                                 14                 :                : /*
                                 15                 :                :  * create stack
                                 16                 :                :  */
                                 17                 :                : ConditionalStack
 3437 tgl@sss.pgh.pa.us          18                 :CBC       10843 : conditional_stack_create(void)
                                 19                 :                : {
  184 michael@paquier.xyz        20                 :          10843 :     ConditionalStack cstack = pg_malloc_object(ConditionalStackData);
                                 21                 :                : 
 3437 tgl@sss.pgh.pa.us          22                 :          10843 :     cstack->head = NULL;
                                 23                 :          10843 :     return cstack;
                                 24                 :                : }
                                 25                 :                : 
                                 26                 :                : /*
                                 27                 :                :  * Destroy all the elements from the stack. The stack itself is not freed.
                                 28                 :                :  */
                                 29                 :                : void
 1618 ishii@postgresql.org       30                 :          10703 : conditional_stack_reset(ConditionalStack cstack)
 3437 tgl@sss.pgh.pa.us          31                 :             15 : {
 1618 ishii@postgresql.org       32         [ -  + ]:          10703 :     if (!cstack)
 1618 ishii@postgresql.org       33                 :UBC           0 :         return;                 /* nothing to do here */
                                 34                 :                : 
 3437 tgl@sss.pgh.pa.us          35         [ +  + ]:CBC       10718 :     while (conditional_stack_pop(cstack))
                                 36                 :             15 :         continue;
                                 37                 :                : }
                                 38                 :                : 
                                 39                 :                : /*
                                 40                 :                :  * destroy stack
                                 41                 :                :  */
                                 42                 :                : void
 1618 ishii@postgresql.org       43                 :          10692 : conditional_stack_destroy(ConditionalStack cstack)
                                 44                 :                : {
                                 45                 :          10692 :     conditional_stack_reset(cstack);
 3437 tgl@sss.pgh.pa.us          46                 :          10692 :     free(cstack);
                                 47                 :          10692 : }
                                 48                 :                : 
                                 49                 :                : /*
                                 50                 :                :  * Create a new conditional branch.
                                 51                 :                :  */
                                 52                 :                : void
                                 53                 :          32335 : conditional_stack_push(ConditionalStack cstack, ifState new_state)
                                 54                 :                : {
  184 michael@paquier.xyz        55                 :          32335 :     IfStackElem *p = pg_malloc_object(IfStackElem);
                                 56                 :                : 
 3437 tgl@sss.pgh.pa.us          57                 :          32335 :     p->if_state = new_state;
                                 58                 :          32335 :     p->query_len = -1;
   17                            59                 :          32335 :     p->lex_state = NULL;
 3437                            60                 :          32335 :     p->next = cstack->head;
                                 61                 :          32335 :     cstack->head = p;
                                 62                 :          32335 : }
                                 63                 :                : 
                                 64                 :                : /*
                                 65                 :                :  * Destroy the topmost conditional branch.
                                 66                 :                :  * Returns false if there was no branch to end.
                                 67                 :                :  */
                                 68                 :                : bool
                                 69                 :          43035 : conditional_stack_pop(ConditionalStack cstack)
                                 70                 :                : {
                                 71                 :          43035 :     IfStackElem *p = cstack->head;
                                 72                 :                : 
                                 73         [ +  + ]:          43035 :     if (!p)
                                 74                 :          10704 :         return false;
                                 75                 :          32331 :     cstack->head = cstack->head->next;
   17                            76         [ +  + ]:          32331 :     if (p->lex_state)
                                 77                 :            156 :         free(p->lex_state);
 3437                            78                 :          32331 :     free(p);
                                 79                 :          32331 :     return true;
                                 80                 :                : }
                                 81                 :                : 
                                 82                 :                : /*
                                 83                 :                :  * Returns current stack depth, for debugging purposes.
                                 84                 :                :  */
                                 85                 :                : int
 3080 teodor@sigaev.ru           86                 :UBC           0 : conditional_stack_depth(ConditionalStack cstack)
                                 87                 :                : {
                                 88         [ #  # ]:              0 :     if (cstack == NULL)
                                 89                 :              0 :         return -1;
                                 90                 :                :     else
                                 91                 :                :     {
 3045 tgl@sss.pgh.pa.us          92                 :              0 :         IfStackElem *p = cstack->head;
 3080 teodor@sigaev.ru           93                 :              0 :         int         depth = 0;
                                 94                 :                : 
                                 95         [ #  # ]:              0 :         while (p != NULL)
                                 96                 :                :         {
                                 97                 :              0 :             depth++;
                                 98                 :              0 :             p = p->next;
                                 99                 :                :         }
                                100                 :              0 :         return depth;
                                101                 :                :     }
                                102                 :                : }
                                103                 :                : 
                                104                 :                : /*
                                105                 :                :  * Fetch the current state of the top of the stack.
                                106                 :                :  */
                                107                 :                : ifState
 3437 tgl@sss.pgh.pa.us         108                 :CBC      335962 : conditional_stack_peek(ConditionalStack cstack)
                                109                 :                : {
                                110         [ +  + ]:         335962 :     if (conditional_stack_empty(cstack))
                                111                 :         332403 :         return IFSTATE_NONE;
                                112                 :           3559 :     return cstack->head->if_state;
                                113                 :                : }
                                114                 :                : 
                                115                 :                : /*
                                116                 :                :  * Change the state of the topmost branch.
                                117                 :                :  * Returns false if there was no branch state to set.
                                118                 :                :  */
                                119                 :                : bool
                                120                 :            232 : conditional_stack_poke(ConditionalStack cstack, ifState new_state)
                                121                 :                : {
                                122         [ -  + ]:            232 :     if (conditional_stack_empty(cstack))
 3437 tgl@sss.pgh.pa.us         123                 :UBC           0 :         return false;
 3437 tgl@sss.pgh.pa.us         124                 :CBC         232 :     cstack->head->if_state = new_state;
                                125                 :            232 :     return true;
                                126                 :                : }
                                127                 :                : 
                                128                 :                : /*
                                129                 :                :  * True if there are no active \if-blocks.
                                130                 :                :  */
                                131                 :                : bool
                                132                 :         363216 : conditional_stack_empty(ConditionalStack cstack)
                                133                 :                : {
                                134                 :         363216 :     return cstack->head == NULL;
                                135                 :                : }
                                136                 :                : 
                                137                 :                : /*
                                138                 :                :  * True if we should execute commands normally; that is, the current
                                139                 :                :  * conditional branch is active, or there is no open \if block.
                                140                 :                :  */
                                141                 :                : bool
                                142                 :         335169 : conditional_active(ConditionalStack cstack)
                                143                 :                : {
                                144                 :         335169 :     ifState     s = conditional_stack_peek(cstack);
                                145                 :                : 
                                146   [ +  +  +  +  :         335169 :     return s == IFSTATE_NONE || s == IFSTATE_TRUE || s == IFSTATE_ELSE_TRUE;
                                              +  + ]
                                147                 :                : }
                                148                 :                : 
                                149                 :                : /*
                                150                 :                :  * Save current query buffer length in topmost stack entry.
                                151                 :                :  */
                                152                 :                : void
                                153                 :            200 : conditional_stack_set_query_len(ConditionalStack cstack, int len)
                                154                 :                : {
                                155         [ -  + ]:            200 :     Assert(!conditional_stack_empty(cstack));
                                156                 :            200 :     cstack->head->query_len = len;
                                157                 :            200 : }
                                158                 :                : 
                                159                 :                : /*
                                160                 :                :  * Fetch last-recorded query buffer length from topmost stack entry.
                                161                 :                :  * Will return -1 if no stack or it was never saved.
                                162                 :                :  */
                                163                 :                : int
                                164                 :            169 : conditional_stack_get_query_len(ConditionalStack cstack)
                                165                 :                : {
                                166         [ -  + ]:            169 :     if (conditional_stack_empty(cstack))
 3437 tgl@sss.pgh.pa.us         167                 :UBC           0 :         return -1;
 3437 tgl@sss.pgh.pa.us         168                 :CBC         169 :     return cstack->head->query_len;
                                169                 :                : }
                                170                 :                : 
                                171                 :                : /*
                                172                 :                :  * Save current lexer state in topmost stack entry.
                                173                 :                :  *
                                174                 :                :  * The lexer state is presumed to be a single pg_malloc'd chunk.
                                175                 :                :  * It will be freed automatically when the stack entry is popped.
                                176                 :                :  */
                                177                 :                : void
   17                           178                 :            200 : conditional_stack_set_lex_state(ConditionalStack cstack,
                                179                 :                :                                 PsqlScanStateSave *lex_state)
                                180                 :                : {
 3437                           181         [ -  + ]:            200 :     Assert(!conditional_stack_empty(cstack));
   17                           182         [ +  + ]:            200 :     if (cstack->head->lex_state)  /* free old state, if any */
                                183                 :             44 :         free(cstack->head->lex_state);
                                184                 :            200 :     cstack->head->lex_state = lex_state;
 3437                           185                 :            200 : }
                                186                 :                : 
                                187                 :                : /*
                                188                 :                :  * Fetch last-recorded lexer state from topmost stack entry.
                                189                 :                :  * Will return NULL if no stack or it was never saved.
                                190                 :                :  */
                                191                 :                : PsqlScanStateSave *
   17                           192                 :            169 : conditional_stack_get_lex_state(ConditionalStack cstack)
                                193                 :                : {
 3437                           194         [ -  + ]:            169 :     if (conditional_stack_empty(cstack))
   17 tgl@sss.pgh.pa.us         195                 :UBC           0 :         return NULL;
   17 tgl@sss.pgh.pa.us         196                 :CBC         169 :     return cstack->head->lex_state;
                                197                 :                : }
        

Generated by: LCOV version 2.0-1