PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
conditional.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 * A stack of automaton states to handle nested conditionals.
3 *
4 * Copyright (c) 2000-2025, PostgreSQL Global Development Group
5 *
6 * src/fe_utils/conditional.c
7 *
8 *-------------------------------------------------------------------------
9 */
10#include "postgres_fe.h"
11
13
14/*
15 * create stack
16 */
19{
21
22 cstack->head = NULL;
23 return cstack;
24}
25
26/*
27 * Destroy all the elements from the stack. The stack itself is not freed.
28 */
29void
31{
32 if (!cstack)
33 return; /* nothing to do here */
34
35 while (conditional_stack_pop(cstack))
36 continue;
37}
38
39/*
40 * destroy stack
41 */
42void
44{
46 free(cstack);
47}
48
49/*
50 * Create a new conditional branch.
51 */
52void
54{
56
57 p->if_state = new_state;
58 p->query_len = -1;
59 p->paren_depth = -1;
60 p->next = cstack->head;
61 cstack->head = p;
62}
63
64/*
65 * Destroy the topmost conditional branch.
66 * Returns false if there was no branch to end.
67 */
68bool
70{
71 IfStackElem *p = cstack->head;
72
73 if (!p)
74 return false;
75 cstack->head = cstack->head->next;
76 free(p);
77 return true;
78}
79
80/*
81 * Returns current stack depth, for debugging purposes.
82 */
83int
85{
86 if (cstack == NULL)
87 return -1;
88 else
89 {
90 IfStackElem *p = cstack->head;
91 int depth = 0;
92
93 while (p != NULL)
94 {
95 depth++;
96 p = p->next;
97 }
98 return depth;
99 }
100}
101
102/*
103 * Fetch the current state of the top of the stack.
104 */
107{
108 if (conditional_stack_empty(cstack))
109 return IFSTATE_NONE;
110 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 */
117bool
119{
120 if (conditional_stack_empty(cstack))
121 return false;
122 cstack->head->if_state = new_state;
123 return true;
124}
125
126/*
127 * True if there are no active \if-blocks.
128 */
129bool
131{
132 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 */
139bool
141{
143
144 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 */
150void
152{
154 cstack->head->query_len = len;
155}
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 */
161int
163{
164 if (conditional_stack_empty(cstack))
165 return -1;
166 return cstack->head->query_len;
167}
168
169/*
170 * Save current parenthesis nesting depth in topmost stack entry.
171 */
172void
174{
176 cstack->head->paren_depth = depth;
177}
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 */
183int
185{
186 if (conditional_stack_empty(cstack))
187 return -1;
188 return cstack->head->paren_depth;
189}
#define Assert(condition)
Definition: c.h:815
void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth)
Definition: conditional.c:173
ifState conditional_stack_peek(ConditionalStack cstack)
Definition: conditional.c:106
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:53
ConditionalStack conditional_stack_create(void)
Definition: conditional.c:18
int conditional_stack_depth(ConditionalStack cstack)
Definition: conditional.c:84
bool conditional_stack_pop(ConditionalStack cstack)
Definition: conditional.c:69
void conditional_stack_destroy(ConditionalStack cstack)
Definition: conditional.c:43
void conditional_stack_set_query_len(ConditionalStack cstack, int len)
Definition: conditional.c:151
int conditional_stack_get_query_len(ConditionalStack cstack)
Definition: conditional.c:162
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:140
void conditional_stack_reset(ConditionalStack cstack)
Definition: conditional.c:30
int conditional_stack_get_paren_depth(ConditionalStack cstack)
Definition: conditional.c:184
bool conditional_stack_poke(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:118
bool conditional_stack_empty(ConditionalStack cstack)
Definition: conditional.c:130
ifState
Definition: conditional.h:30
@ IFSTATE_ELSE_TRUE
Definition: conditional.h:40
@ IFSTATE_TRUE
Definition: conditional.h:32
@ IFSTATE_NONE
Definition: conditional.h:31
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define free(a)
Definition: header.h:65
const void size_t len
IfStackElem * head
Definition: conditional.h:68
struct IfStackElem * next
Definition: conditional.h:63
int paren_depth
Definition: conditional.h:62
ifState if_state
Definition: conditional.h:60