LCOV - differential code coverage report
Current view: top level - src/fe_utils - conditional.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 80.9 % 68 55 13 55
Current Date: 2023-04-08 15:15:32 Functions: 92.9 % 14 13 1 13
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  * A stack of automaton states to handle nested conditionals.
       3                 :  *
       4                 :  * Copyright (c) 2000-2023, 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
      18 CBC        6299 : conditional_stack_create(void)
      19                 : {
      20            6299 :     ConditionalStack cstack = pg_malloc(sizeof(ConditionalStackData));
      21                 : 
      22            6299 :     cstack->head = NULL;
      23            6299 :     return cstack;
      24                 : }
      25                 : 
      26                 : /*
      27                 :  * Destroy all the elements from the stack. The stack itself is not freed.
      28                 :  */
      29                 : void
      30            6188 : conditional_stack_reset(ConditionalStack cstack)
      31               4 : {
      32            6188 :     if (!cstack)
      33 UBC           0 :         return;                 /* nothing to do here */
      34                 : 
      35 CBC        6192 :     while (conditional_stack_pop(cstack))
      36               4 :         continue;
      37                 : }
      38                 : 
      39                 : /*
      40                 :  * destroy stack
      41                 :  */
      42                 : void
      43            6186 : conditional_stack_destroy(ConditionalStack cstack)
      44                 : {
      45            6186 :     conditional_stack_reset(cstack);
      46            6186 :     free(cstack);
      47            6186 : }
      48                 : 
      49                 : /*
      50                 :  * Create a new conditional branch.
      51                 :  */
      52                 : void
      53            6160 : conditional_stack_push(ConditionalStack cstack, ifState new_state)
      54                 : {
      55            6160 :     IfStackElem *p = (IfStackElem *) pg_malloc(sizeof(IfStackElem));
      56                 : 
      57            6160 :     p->if_state = new_state;
      58            6160 :     p->query_len = -1;
      59            6160 :     p->paren_depth = -1;
      60            6160 :     p->next = cstack->head;
      61            6160 :     cstack->head = p;
      62            6160 : }
      63                 : 
      64                 : /*
      65                 :  * Destroy the topmost conditional branch.
      66                 :  * Returns false if there was no branch to end.
      67                 :  */
      68                 : bool
      69           12346 : conditional_stack_pop(ConditionalStack cstack)
      70                 : {
      71           12346 :     IfStackElem *p = cstack->head;
      72                 : 
      73           12346 :     if (!p)
      74            6189 :         return false;
      75            6157 :     cstack->head = cstack->head->next;
      76            6157 :     free(p);
      77            6157 :     return true;
      78                 : }
      79                 : 
      80                 : /*
      81                 :  * Returns current stack depth, for debugging purposes.
      82                 :  */
      83                 : int
      84 UBC           0 : conditional_stack_depth(ConditionalStack cstack)
      85                 : {
      86               0 :     if (cstack == NULL)
      87               0 :         return -1;
      88                 :     else
      89                 :     {
      90               0 :         IfStackElem *p = cstack->head;
      91               0 :         int         depth = 0;
      92                 : 
      93               0 :         while (p != NULL)
      94                 :         {
      95               0 :             depth++;
      96               0 :             p = p->next;
      97                 :         }
      98               0 :         return depth;
      99                 :     }
     100                 : }
     101                 : 
     102                 : /*
     103                 :  * Fetch the current state of the top of the stack.
     104                 :  */
     105                 : ifState
     106 CBC      168575 : conditional_stack_peek(ConditionalStack cstack)
     107                 : {
     108          168575 :     if (conditional_stack_empty(cstack))
     109          166101 :         return IFSTATE_NONE;
     110            2474 :     return cstack->head->if_state;
     111                 : }
     112                 : 
     113                 : /*
     114                 :  * Change the state of the topmost branch.
     115                 :  * Returns false if there was no branch state to set.
     116                 :  */
     117                 : bool
     118             137 : conditional_stack_poke(ConditionalStack cstack, ifState new_state)
     119                 : {
     120             137 :     if (conditional_stack_empty(cstack))
     121 UBC           0 :         return false;
     122 CBC         137 :     cstack->head->if_state = new_state;
     123             137 :     return true;
     124                 : }
     125                 : 
     126                 : /*
     127                 :  * True if there are no active \if-blocks.
     128                 :  */
     129                 : bool
     130          180589 : conditional_stack_empty(ConditionalStack cstack)
     131                 : {
     132          180589 :     return cstack->head == NULL;
     133                 : }
     134                 : 
     135                 : /*
     136                 :  * True if we should execute commands normally; that is, the current
     137                 :  * conditional branch is active, or there is no open \if block.
     138                 :  */
     139                 : bool
     140          168009 : conditional_active(ConditionalStack cstack)
     141                 : {
     142          168009 :     ifState     s = conditional_stack_peek(cstack);
     143                 : 
     144          168009 :     return s == IFSTATE_NONE || s == IFSTATE_TRUE || s == IFSTATE_ELSE_TRUE;
     145                 : }
     146                 : 
     147                 : /*
     148                 :  * Save current query buffer length in topmost stack entry.
     149                 :  */
     150                 : void
     151             114 : conditional_stack_set_query_len(ConditionalStack cstack, int len)
     152                 : {
     153             114 :     Assert(!conditional_stack_empty(cstack));
     154             114 :     cstack->head->query_len = len;
     155             114 : }
     156                 : 
     157                 : /*
     158                 :  * Fetch last-recorded query buffer length from topmost stack entry.
     159                 :  * Will return -1 if no stack or it was never saved.
     160                 :  */
     161                 : int
     162              98 : conditional_stack_get_query_len(ConditionalStack cstack)
     163                 : {
     164              98 :     if (conditional_stack_empty(cstack))
     165 UBC           0 :         return -1;
     166 CBC          98 :     return cstack->head->query_len;
     167                 : }
     168                 : 
     169                 : /*
     170                 :  * Save current parenthesis nesting depth in topmost stack entry.
     171                 :  */
     172                 : void
     173             114 : conditional_stack_set_paren_depth(ConditionalStack cstack, int depth)
     174                 : {
     175             114 :     Assert(!conditional_stack_empty(cstack));
     176             114 :     cstack->head->paren_depth = depth;
     177             114 : }
     178                 : 
     179                 : /*
     180                 :  * Fetch last-recorded parenthesis nesting depth from topmost stack entry.
     181                 :  * Will return -1 if no stack or it was never saved.
     182                 :  */
     183                 : int
     184              98 : conditional_stack_get_paren_depth(ConditionalStack cstack)
     185                 : {
     186              98 :     if (conditional_stack_empty(cstack))
     187 UBC           0 :         return -1;
     188 CBC          98 :     return cstack->head->paren_depth;
     189                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a