]> granicus.if.org Git - postgresql/commitdiff
Add a "void *" passthrough pointer for psqlscan.l's callback functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Mar 2017 21:14:46 +0000 (17:14 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 13 Mar 2017 21:14:46 +0000 (17:14 -0400)
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

src/bin/psql/common.c
src/bin/psql/common.h
src/bin/psql/psqlscanslash.l
src/fe_utils/psqlscan.l
src/include/fe_utils/psqlscan.h
src/include/fe_utils/psqlscan_int.h

index 1aa56ab3a2fd403373513202008292f1d879823e..e9d4fe678669a088796f3d7480ef897320669c74 100644 (file)
@@ -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;
index a83bc69ab7524f7b9f82922a60017d75e431ef79..3d8b8da7fe49896f3a5880f3c8536142b4e863f7 100644 (file)
@@ -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);
 
index 5b7953bf7bdb5c706e3da9da8d6ab470d8062f8f..ba4a08d00051f9fa16152007d49c046e965c8866 100644 (file)
@@ -243,7 +243,8 @@ other                       .
                                                                                                                         yyleng - 1);
                                                value = cur_state->callbacks->get_variable(varname,
                                                                                                                                   false,
-                                                                                                                                  false);
+                                                                                                                                  false,
+                                                                                                                                  cur_state->cb_passthrough);
                                                free(varname);
 
                                                /*
index 1b29341fa87c554866e58108ea4336727435402e..19b3e57aa4577d5883fb862b52065ec6d5a83d79 100644 (file)
@@ -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);
index 21c4f227a13b716c7c2518eac317e7dc15718f59..0cc632b821b029a9e8dad72a6f07187f4caa6d96 100644 (file)
@@ -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);
index 0fddc7a85642ef7e1af92d2b159ea80a8a5e9b01..b4044e806a8a783c71c712148db992973934d848 100644 (file)
@@ -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;