/
githubmirror
/
postgres
Обзор
Документация
Войти
/
githubmirror
/
postgres
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/include/fe_utils/conditional.h
102 строки
4 KB
Tom Lane
Save/restore more lexer state when skipping text due to \if.
10 авг 2026, 16:37
10 авг 2026, 16:37
cf754f7
Код
Авторство
О чём код?
/*------------------------------------------------------------------------- * A stack of automaton states to handle nested conditionals. * * This file describes a stack of automaton states which * allow a manage nested conditionals. * * It is used by: * - "psql" interpreter for handling \if ... \endif * - "pgbench" interpreter for handling \if ... \endif * - "pgbench" syntax checker to test for proper nesting * * The stack holds the state of enclosing conditionals (are we in * a true branch? in a false branch? have we already encountered * a true branch?) so that the interpreter knows whether to execute * code and whether to evaluate conditions. * * Copyright (c) 2000-2026, PostgreSQL Global Development Group * * src/include/fe_utils/conditional.h * *------------------------------------------------------------------------- */ #ifndef CONDITIONAL_H #define CONDITIONAL_H /* * Possible states of a single level of \if block. */ typedef enum ifState { IFSTATE_NONE = 0, /* not currently in an \if block */ IFSTATE_TRUE, /* currently in an \if or \elif that is true * and all parent branches (if any) are true */ IFSTATE_FALSE, /* currently in an \if or \elif that is false * but no true branch has yet been seen, and * all parent branches (if any) are true */ IFSTATE_IGNORED, /* currently in an \elif that follows a true * branch, or the whole \if is a child of a * false parent branch */ IFSTATE_ELSE_TRUE, /* currently in an \else that is true and all * parent branches (if any) are true */ IFSTATE_ELSE_FALSE, /* currently in an \else that is false or * ignored */ } ifState; /* * The state of nested \ifs is stored in a stack. * * query_len is used to determine what accumulated text to throw away at the * end of an inactive branch. (We could, perhaps, teach the lexer to not add * stuff to the query buffer in the first place when inside an inactive branch; * but that would be very invasive.) We also need to save and restore some * lexer state, such as parenthesis nesting depth, when throwing away text. */ typedef struct PsqlScanStateSave PsqlScanStateSave; /* opaque outside lexer */ typedef struct IfStackElem { ifState if_state; /* current state, see enum above */ int query_len; /* length of query_buf at last branch start */ PsqlScanStateSave *lex_state; /* lexer state at last branch start */ struct IfStackElem *next; /* next surrounding \if, if any */ } IfStackElem; typedef struct ConditionalStackData { IfStackElem *head; } ConditionalStackData; typedef struct ConditionalStackData *ConditionalStack; extern ConditionalStack conditional_stack_create(void); extern void conditional_stack_reset(ConditionalStack cstack); extern void conditional_stack_destroy(ConditionalStack cstack); extern int conditional_stack_depth(ConditionalStack cstack); extern void conditional_stack_push(ConditionalStack cstack, ifState new_state); extern bool conditional_stack_pop(ConditionalStack cstack); extern ifState conditional_stack_peek(ConditionalStack cstack); extern bool conditional_stack_poke(ConditionalStack cstack, ifState new_state); extern bool conditional_stack_empty(ConditionalStack cstack); extern bool conditional_active(ConditionalStack cstack); extern void conditional_stack_set_query_len(ConditionalStack cstack, int len); extern int conditional_stack_get_query_len(ConditionalStack cstack); extern void conditional_stack_set_lex_state(ConditionalStack cstack, PsqlScanStateSave *lex_state); extern PsqlScanStateSave *conditional_stack_get_lex_state(ConditionalStack cstack); #endif /* CONDITIONAL_H */