* Variable-fetching callback for flex lexer * * If the specified variable exists, return its value as a string (malloc'd * and expected to be freed by the caller); else return NULL. * * If "quote" isn't PQUOTE_PLAIN, then return the value suitably quoted and * escaped for the specified quoting requirement. (Failure in escaping * should lead to printing an error and returning NULL.) * * "
| 126 | * determine whether variable expansion is allowed. |
| 127 | */ |
| 128 | char * |
| 129 | psql_get_variable(const char *varname, PsqlScanQuoteType quote, |
| 130 | void *passthrough) |
| 131 | { |
| 132 | char *result = NULL; |
| 133 | const char *value; |
| 134 | |
| 135 | /* In an inactive \if branch, suppress all variable substitutions */ |
| 136 | if (passthrough && !conditional_active((ConditionalStack) passthrough)) |
| 137 | return NULL; |
| 138 | |
| 139 | value = GetVariable(pset.vars, varname); |
| 140 | if (!value) |
| 141 | return NULL; |
| 142 | |
| 143 | switch (quote) |
| 144 | { |
| 145 | case PQUOTE_PLAIN: |
| 146 | result = pg_strdup(value); |
| 147 | break; |
| 148 | case PQUOTE_SQL_LITERAL: |
| 149 | case PQUOTE_SQL_IDENT: |
| 150 | { |
| 151 | /* |
| 152 | * For these cases, we use libpq's quoting functions, which |
| 153 | * assume the string is in the connection's client encoding. |
| 154 | */ |
| 155 | char *escaped_value; |
| 156 | |
| 157 | if (!pset.db) |
| 158 | { |
| 159 | pg_log_error("cannot escape without active connection"); |
| 160 | return NULL; |
| 161 | } |
| 162 | |
| 163 | if (quote == PQUOTE_SQL_LITERAL) |
| 164 | escaped_value = |
| 165 | PQescapeLiteral(pset.db, value, strlen(value)); |
| 166 | else |
| 167 | escaped_value = |
| 168 | PQescapeIdentifier(pset.db, value, strlen(value)); |
| 169 | |
| 170 | if (escaped_value == NULL) |
| 171 | { |
| 172 | const char *error = PQerrorMessage(pset.db); |
| 173 | |
| 174 | pg_log_info("%s", error); |
| 175 | return NULL; |
| 176 | } |
| 177 | |
| 178 | /* |
| 179 | * Rather than complicate the lexer's API with a notion of |
| 180 | * which free() routine to use, just pay the price of an extra |
| 181 | * strdup(). |
| 182 | */ |
| 183 | result = pg_strdup(escaped_value); |
| 184 | PQfreemem(escaped_value); |
| 185 | break; |
nothing calls this directly
no test coverage detected