diff options
author | Tom Lane | 2017-03-13 21:14:46 +0000 |
---|---|---|
committer | Tom Lane | 2017-03-13 21:14:46 +0000 |
commit | 895e36bb3f36fdb7ec8e573be1a20d104fac820b (patch) | |
tree | 0174e31cf8b59bc4ae31f314f323642bcc06bda7 | |
parent | 1c7a66a8e9378aeb092d7ed26890134d17fdd691 (diff) |
Add a "void *" passthrough pointer for psqlscan.l's callback functions.
The immediate motivation for this is to provide clean infrastructure
for the proposed \if...\endif patch for psql; but it seems like a good
thing to have even if that patch doesn't get in. Previously the callback
functions could only make use of application-global state, which is a
pretty severe handicap.
For the moment, the pointer is only passed through to the get_variable
callback function. I considered also passing it to the write_error
callback, but for now let's not. Neither psql nor pgbench has a use
for that, and in the case of psql we'd have to invent a separate wrapper
function because we would certainly not want to change the signature of
psql_error().
Discussion: https://postgr.es/m/[email protected]
-rw-r--r-- | src/bin/psql/common.c | 6 | ||||
-rw-r--r-- | src/bin/psql/common.h | 3 | ||||
-rw-r--r-- | src/bin/psql/psqlscanslash.l | 3 | ||||
-rw-r--r-- | src/fe_utils/psqlscan.l | 19 | ||||
-rw-r--r-- | src/include/fe_utils/psqlscan.h | 5 | ||||
-rw-r--r-- | src/include/fe_utils/psqlscan_int.h | 4 |
6 files changed, 33 insertions, 7 deletions
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 1aa56ab3a2..e9d4fe6786 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -119,9 +119,13 @@ setQFout(const char *fname) * If "escape" is true, return the value suitably quoted and escaped, * as an identifier or string literal depending on "as_ident". * (Failure in escaping should lead to returning NULL.) + * + * "passthrough" is the pointer previously given to psql_scan_set_passthrough. + * psql currently doesn't use this. */ char * -psql_get_variable(const char *varname, bool escape, bool as_ident) +psql_get_variable(const char *varname, bool escape, bool as_ident, + void *passthrough) { char *result; const char *value; diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index a83bc69ab7..3d8b8da7fe 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -16,7 +16,8 @@ extern bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe); extern bool setQFout(const char *fname); -extern char *psql_get_variable(const char *varname, bool escape, bool as_ident); +extern char *psql_get_variable(const char *varname, bool escape, bool as_ident, + void *passthrough); extern void psql_error(const char *fmt,...) pg_attribute_printf(1, 2); diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index 5b7953bf7b..ba4a08d000 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -243,7 +243,8 @@ other . yyleng - 1); value = cur_state->callbacks->get_variable(varname, false, - false); + false, + cur_state->cb_passthrough); free(varname); /* diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index 1b29341fa8..19b3e57aa4 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -700,7 +700,8 @@ other . if (cur_state->callbacks->get_variable) value = cur_state->callbacks->get_variable(varname, false, - false); + false, + cur_state->cb_passthrough); else value = NULL; @@ -923,6 +924,19 @@ psql_scan_destroy(PsqlScanState state) } /* + * Set the callback passthrough pointer for the lexer. + * + * This could have been integrated into psql_scan_create, but keeping it + * separate allows the application to change the pointer later, which might + * be useful. + */ +void +psql_scan_set_passthrough(PsqlScanState state, void *passthrough) +{ + state->cb_passthrough = passthrough; +} + +/* * Set up to perform lexing of the given input line. * * The text at *line, extending for line_len bytes, will be scanned by @@ -1409,7 +1423,8 @@ psqlscan_escape_variable(PsqlScanState state, const char *txt, int len, /* Variable lookup. */ varname = psqlscan_extract_substring(state, txt + 2, len - 3); if (state->callbacks->get_variable) - value = state->callbacks->get_variable(varname, true, as_ident); + value = state->callbacks->get_variable(varname, true, as_ident, + state->cb_passthrough); else value = NULL; free(varname); diff --git a/src/include/fe_utils/psqlscan.h b/src/include/fe_utils/psqlscan.h index 21c4f227a1..0cc632b821 100644 --- a/src/include/fe_utils/psqlscan.h +++ b/src/include/fe_utils/psqlscan.h @@ -53,7 +53,8 @@ typedef struct PsqlScanCallbacks { /* Fetch value of a variable, as a pfree'able string; NULL if unknown */ /* This pointer can be NULL if no variable substitution is wanted */ - char *(*get_variable) (const char *varname, bool escape, bool as_ident); + char *(*get_variable) (const char *varname, bool escape, + bool as_ident, void *passthrough); /* Print an error message someplace appropriate */ /* (very old gcc versions don't support attributes on function pointers) */ #if defined(__GNUC__) && __GNUC__ < 4 @@ -67,6 +68,8 @@ typedef struct PsqlScanCallbacks extern PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks); extern void psql_scan_destroy(PsqlScanState state); +extern void psql_scan_set_passthrough(PsqlScanState state, void *passthrough); + extern void psql_scan_setup(PsqlScanState state, const char *line, int line_len, int encoding, bool std_strings); diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h index 0fddc7a856..b4044e806a 100644 --- a/src/include/fe_utils/psqlscan_int.h +++ b/src/include/fe_utils/psqlscan_int.h @@ -115,9 +115,11 @@ typedef struct PsqlScanStateData char *dolqstart; /* current $foo$ quote start string */ /* - * Callback functions provided by the program making use of the lexer. + * Callback functions provided by the program making use of the lexer, + * plus a void* callback passthrough argument. */ const PsqlScanCallbacks *callbacks; + void *cb_passthrough; } PsqlScanStateData; |