summaryrefslogtreecommitdiff
path: root/src/fe_utils
diff options
context:
space:
mode:
authorAndrew Dunstan2017-09-21 23:02:23 +0000
committerAndrew Dunstan2017-09-21 23:02:23 +0000
commitd57c7a7c506276597af619bdb8c62fa5b592745a (patch)
tree6cab776216fa74f256164cbbc7859fbe1fb97b02 /src/fe_utils
parent71480501057fee9fa3649b072173ff10e2b842d0 (diff)
Provide a test for variable existence in psql
"\if :{?variable_name}" will be translated to "\if TRUE" if the variable exists and "\if FALSE" otherwise. Thus it will be possible to execute code conditionally on the existence of the variable, regardless of its value. Fabien Coelho, with some review by Robins Tharakan and some light text editing by me. Discussion: https://postgr.es/m/alpine.DEB.2.20.1708260835520.3627@lancre
Diffstat (limited to 'src/fe_utils')
-rw-r--r--src/fe_utils/psqlscan.l42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l
index 27689d72da8..4375142a007 100644
--- a/src/fe_utils/psqlscan.l
+++ b/src/fe_utils/psqlscan.l
@@ -745,9 +745,13 @@ other .
PQUOTE_SQL_IDENT);
}
+:\{\?{variable_char}+\} {
+ psqlscan_test_variable(cur_state, yytext, yyleng);
+ }
+
/*
* These rules just avoid the need for scanner backup if one of the
- * two rules above fails to match completely.
+ * three rules above fails to match completely.
*/
:'{variable_char}* {
@@ -762,6 +766,17 @@ other .
ECHO;
}
+:\{\?{variable_char}* {
+ /* Throw back everything but the colon */
+ yyless(1);
+ ECHO;
+ }
+:\{ {
+ /* Throw back everything but the colon */
+ yyless(1);
+ ECHO;
+ }
+
/*
* Back to backend-compatible rules.
*/
@@ -1442,3 +1457,28 @@ psqlscan_escape_variable(PsqlScanState state, const char *txt, int len,
psqlscan_emit(state, txt, len);
}
}
+
+void
+psqlscan_test_variable(PsqlScanState state, const char *txt, int len)
+{
+ char *varname;
+ char *value;
+
+ varname = psqlscan_extract_substring(state, txt + 3, len - 4);
+ if (state->callbacks->get_variable)
+ value = state->callbacks->get_variable(varname, PQUOTE_PLAIN,
+ state->cb_passthrough);
+ else
+ value = NULL;
+ free(varname);
+
+ if (value != NULL)
+ {
+ psqlscan_emit(state, "TRUE", 4);
+ free(value);
+ }
+ else
+ {
+ psqlscan_emit(state, "FALSE", 5);
+ }
+}