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/10108.1489418309@sss.pgh.pa.us
This commit is contained in:
parent
1c7a66a8e9
commit
895e36bb3f
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -243,7 +243,8 @@ other .
|
||||
yyleng - 1);
|
||||
value = cur_state->callbacks->get_variable(varname,
|
||||
false,
|
||||
false);
|
||||
false,
|
||||
cur_state->cb_passthrough);
|
||||
free(varname);
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
||||
@ -922,6 +923,19 @@ psql_scan_destroy(PsqlScanState state)
|
||||
free(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.
|
||||
*
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user