1/*-------------------------------------------------------------------------
3 * String-processing utility routines for frontend code
5 * Assorted utility functions that are useful in constructing SQL queries
6 * and interpreting backend output.
9 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/fe_utils/string_utils.c
14 *-------------------------------------------------------------------------
26/* Globals exported by this file */
30static int fmtIdEncoding = -1;
34 * Returns a temporary PQExpBuffer, valid until the next call to the function.
35 * This is used by fmtId and fmtQualifiedId.
37 * Non-reentrant and non-thread-safe but reduces memory leakage. You can
38 * replace this with a custom version by setting the getLocalPQExpBuffer
46 if (id_return)
/* first time through? */
48 /* same buffer, just wipe contents */
61 * Set the encoding that fmtId() and fmtQualifiedId() use.
63 * This is not safe against multiple connections having different encodings,
64 * but there is no real other way to address the need to know the encoding for
65 * fmtId()/fmtQualifiedId() input for safe escaping. Eventually we should get
75 * Return the currently configured encoding for fmtId() and fmtQualifiedId().
80 if (fmtIdEncoding != -1)
84 * In assertion builds it seems best to fail hard if the encoding was not
85 * set, to make it easier to find places with missing calls. But in
86 * production builds that seems like a bad idea, thus we instead just
89 Assert(fmtIdEncoding != -1);
95 * Quotes input string if it's not a legitimate SQL identifier as-is.
97 * Note that the returned string must be used before calling fmtIdEnc again,
98 * since we re-use the same return buffer each time.
106 bool need_quotes =
false;
110 * These checks need to match the identifier production in scan.l. Don't
115 /* slightly different rules for first character */
116 else if (!((rawid[0] >=
'a' && rawid[0] <=
'z') || rawid[0] ==
'_'))
120 /* otherwise check the entire string */
124 if (!((*cp >=
'a' && *cp <=
'z')
125 || (*cp >=
'0' && *cp <=
'9')
137 * Check for keyword. We quote keywords except for unreserved ones.
138 * (In some cases we could avoid quoting a col_name or type_func_name
139 * keyword, but it seems much harder than it's worth to tell that.)
141 * Note: ScanKeywordLookup() does case-insensitive comparison, but
142 * that's fine, since we already know we have all-lower-case.
152 /* no quoting needed */
164 /* Fast path for plain ASCII */
168 * Did we find a double-quote in the string? Then make this a
169 * double double-quote per SQL99. Before, we put in a
170 * backslash/double-quote pair. - thomas 2000年08月05日
180 /* Slow path for possible multibyte characters */
187 * Multibyte character is invalid. It's important to verify
188 * that as invalid multibyte characters could e.g. be used to
189 * "skip" over quote characters, e.g. when parsing
190 * character-by-character.
192 * Replace the character's first byte with an invalid
193 * sequence. The invalid sequence ensures that the escaped
194 * string will trigger an error on the server-side, even if we
195 * can't directly report an error here.
197 * It would be a bit faster to verify the whole string the
198 * first time we encounter a set highbit, but this way we can
199 * replace just the invalid data, which probably makes it
200 * easier for users to find the invalidly encoded portion of a
206 id_return->
data + id_return->
len);
208 id_return->
data[id_return->
len] =
'0円';
212 * Handle the following bytes as if this byte didn't exist.
213 * That's safer in case the subsequent bytes contain
214 * characters that are significant for the caller (e.g. '>' in
222 for (
int i = 0;
i < charlen;
i++)
234 return id_return->
data;
238 * Quotes input string if it's not a legitimate SQL identifier as-is.
240 * Note that the returned string must be used before calling fmtId again,
241 * since we re-use the same return buffer each time.
243 * NB: This assumes setFmtEncoding() previously has been called to configure
244 * the encoding of rawid. It is preferable to use fmtIdEnc() with an
254 * fmtQualifiedIdEnc - construct a schema-qualified name, with quoting as
257 * Like fmtId, use the result before calling again.
259 * Since we call fmtId and it also uses getLocalPQExpBuffer() we cannot
260 * use that buffer until we're finished with calling fmtId().
268 /* Some callers might fail to provide a schema name */
269 if (schema && *schema)
280 return id_return->
data;
284 * fmtQualifiedId - construct a schema-qualified name, with quoting as needed.
286 * Like fmtId, use the result before calling again.
288 * Since we call fmtId and it also uses getLocalPQExpBuffer() we cannot
289 * use that buffer until we're finished with calling fmtId().
291 * NB: This assumes setFmtEncoding() previously has been called to configure
292 * the encoding of schema/id. It is preferable to use fmtQualifiedIdEnc()
293 * with an explicit encoding.
303 * Format a Postgres version number (in the PG_VERSION_NUM integer format
304 * returned by PQserverVersion()) as a string. This exists mainly to
305 * encapsulate knowledge about two-part vs. three-part version numbers.
307 * For reentrancy, caller must supply the buffer the string is put in.
308 * Recommended size of the buffer is 32 bytes.
310 * Returns address of 'buf', as a notational convenience.
314 char *
buf,
size_t buflen)
316 if (version_number >= 100000)
318 /* New two-part style */
320 snprintf(
buf, buflen,
"%d.%d", version_number / 10000,
321 version_number % 10000);
323 snprintf(
buf, buflen,
"%d", version_number / 10000);
327 /* Old three-part style */
329 snprintf(
buf, buflen,
"%d.%d.%d", version_number / 10000,
330 (version_number / 100) % 100,
331 version_number % 100);
333 snprintf(
buf, buflen,
"%d.%d", version_number / 10000,
334 (version_number / 100) % 100);
341 * Convert a string value to an SQL string literal and append it to
342 * the given buffer. We assume the specified client_encoding and
343 * standard_conforming_strings settings.
345 * This is essentially equivalent to libpq's PQescapeStringInternal,
346 * except for the output buffer structure. We need it in situations
347 * where we do not have a PGconn available. Where we do,
348 * appendStringLiteralConn is a better choice.
354 size_t length = strlen(
str);
362 target =
buf->data +
buf->len;
371 /* Fast path for plain ASCII */
374 /* Apply quoting if needed */
377 /* Copy the character */
384 /* Slow path for possible multibyte characters */
391 * Multibyte character is invalid. It's important to verify that
392 * as invalid multibyte characters could e.g. be used to "skip"
393 * over quote characters, e.g. when parsing
394 * character-by-character.
396 * Replace the character's first byte with an invalid sequence.
397 * The invalid sequence ensures that the escaped string will
398 * trigger an error on the server-side, even if we can't directly
399 * report an error here.
401 * We know there's enough space for the invalid sequence because
402 * the "target" buffer is 2 * length + 2 long, and at worst we're
403 * replacing a single input byte with two invalid bytes.
405 * It would be a bit faster to verify the whole string the first
406 * time we encounter a set highbit, but this way we can replace
407 * just the invalid data, which probably makes it easier for users
408 * to find the invalidly encoded portion of a larger string.
414 * Handle the following bytes as if this byte didn't exist. That's
415 * safer in case the subsequent bytes contain important characters
416 * for the caller (e.g. '>' in html).
423 /* Copy the character */
424 for (
i = 0;
i < charlen;
i++)
432 /* Write the terminating quote and NUL character. */
436 buf->len = target -
buf->data;
441 * Convert a string value to an SQL string literal and append it to
442 * the given buffer. Encoding and string syntax rules are as indicated
443 * by current settings of the PGconn.
448 size_t length = strlen(
str);
451 * XXX This is a kluge to silence escape_string_warning in our utility
452 * programs. It should go away someday.
456 /* ensure we are not adjacent to an identifier */
457 if (
buf->len > 0 &&
buf->data[
buf->len - 1] !=
' ')
475 * Convert a string value to a dollar quoted literal and append it to
476 * the given buffer. If the dqprefix parameter is not NULL then the
477 * dollar quote delimiter will begin with that (after the opening $).
479 * No escaping is done at all on str, in compliance with the rules
480 * for parsing dollar quoted strings. Also, we need not worry about
486 static const char suffixes[] =
"_XXXXXXX";
490 /* start with $ + dqprefix if not NULL */
496 * Make sure we choose a delimiter which (without the trailing $) is not
497 * present in the string being quoted. We don't check with the trailing $
498 * because a string ending in $foo must not be quoted with $foo$.
500 while (strstr(
str, delimBuf->
data) != NULL)
503 nextchar %=
sizeof(suffixes) - 1;
509 /* quote it and we are all done */
519 * Convert a bytea value (presented as raw bytes) to an SQL string literal
520 * and append it to the given buffer. We assume the specified
521 * standard_conforming_strings setting.
523 * This is needed in situations where we do not have a PGconn available.
524 * Where we do, PQescapeByteaConn is a better choice.
533 static const char hextbl[] =
"0123456789abcdef";
536 * This implementation is hard-wired to produce hex-format output. We do
537 * not know the server version the output will be loaded into, so making
538 * an intelligent format choice is impossible. It might be better to
539 * always use the old escaped format.
544 target =
buf->data +
buf->len;
555 *target++ =
hextbl[(
c >> 4) & 0xF];
559 /* Write the terminating quote and NUL character. */
563 buf->len = target -
buf->data;
568 * Append the given string to the shell command being built in the buffer,
569 * with shell-style quoting as needed to create exactly one argument.
571 * Forbid LF or CR characters, which have scant practical use beyond designing
572 * security breaches. The Windows command shell is unusable as a conduit for
573 * arguments containing LF or CR characters. A future major release should
574 * reject those characters in CREATE ROLE and CREATE DATABASE, because use
575 * there eventually leads to errors here.
577 * appendShellString() simply prints an error and dies if LF or CR appears.
578 * appendShellStringNoError() omits those characters from the result, and
579 * returns false if there were any.
587 _(
"shell command argument contains a newline or carriage return: \"%s\"\n"),
597 int backslash_run_length = 0;
603 * Don't bother with adding quotes if the string is nonempty and clearly
604 * contains only safe characters.
607 strspn(
str,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_./:") == strlen(
str))
615 for (p =
str; *p; p++)
617 if (*p ==
'\n' || *p ==
'\r')
632 * A Windows system() argument experiences two layers of interpretation.
633 * First, cmd.exe interprets the string. Its behavior is undocumented,
634 * but a caret escapes any byte except LF or CR that would otherwise have
635 * special meaning. Handling of a caret before LF or CR differs between
636 * "cmd.exe /c" and other modes, and it is unusable here.
638 * Second, the new process parses its command line to construct argv (see
639 * https://msdn.microsoft.com/en-us/library/17w5ykft.aspx). This treats
640 * backslash-double quote sequences specially.
643 for (p =
str; *p; p++)
645 if (*p ==
'\n' || *p ==
'\r')
651 /* Change N backslashes before a double quote to 2N+1 backslashes. */
654 while (backslash_run_length)
657 backslash_run_length--;
662 backslash_run_length++;
664 backslash_run_length = 0;
667 * Decline to caret-escape the most mundane characters, to ease
668 * debugging and lest we approach the command length limit.
670 if (!((*p >=
'a' && *p <=
'z') ||
671 (*p >=
'A' && *p <=
'Z') ||
672 (*p >=
'0' && *p <=
'9')))
678 * Change N backslashes at end of argument to 2N backslashes, because they
679 * precede the double quote that terminates the argument.
681 while (backslash_run_length)
684 backslash_run_length--;
694 * Append the given string to the buffer, with suitable quoting for passing
695 * the string as a value in a keyword/value pair in a libpq connection string.
704 * If the string is one or more plain ASCII characters, no need to quote
705 * it. This is quite conservative, but better safe than sorry.
708 for (s =
str; *s; s++)
710 if (!((*s >=
'a' && *s <=
'z') || (*s >=
'A' && *s <=
'Z') ||
711 (*s >=
'0' && *s <=
'9') || *s ==
'_' || *s ==
'.'))
724 /* ' and \ must be escaped by to \' and \\ */
725 if (*
str ==
'\'' || *
str ==
'\\')
739 * Append a psql meta-command that connects to the given database with the
740 * then-current connection's user, host and port.
749 * If the name is plain ASCII characters, emit a trivial "\connect "foo"".
750 * For other names, even many not technically requiring it, skip to the
751 * general case. No database has a zero-length name.
757 if (*s ==
'\n' || *s ==
'\r')
760 _(
"database name contains a newline or carriage return: \"%s\"\n"),
765 if (!((*s >=
'a' && *s <=
'z') || (*s >=
'A' && *s <=
'Z') ||
766 (*s >=
'0' && *s <=
'9') || *s ==
'_' || *s ==
'.'))
779 * Force the target psql's encoding to SQL_ASCII. We don't really
780 * know the encoding of the database name, and it doesn't matter as
781 * long as psql will forward it to the server unchanged.
790 * As long as the name does not contain a newline, SQL identifier
791 * quoting satisfies the psql meta-command parser. Prefer not to
792 * involve psql-interpreted single quotes, which behaved differently
793 * before PostgreSQL 9.2.
809 * Deconstruct the text representation of a 1-dimensional Postgres array
810 * into individual items.
812 * On success, returns true and sets *itemarray and *nitems to describe
813 * an array of individual strings. On parse failure, returns false;
814 * *itemarray may exist or be NULL.
816 * NOTE: free'ing itemarray is sufficient to deallocate the working storage.
827 * We expect input in the form of "{item,item,item}" where any item is
828 * either raw data, or surrounded by double quotes (in which case embedded
829 * characters including backslashes and quotes are backslashed).
831 * We build the result as an array of pointers followed by the actual
832 * string data, all in one malloc block for convenience of deallocation.
833 * The worst-case storage need is not more than one pointer and one
834 * character for each input character (consider "{,,,,,,,,,,}").
838 inputlen = strlen(atext);
839 if (inputlen < 2 || atext[0] !=
'{' || atext[inputlen - 1] !=
'}')
840 return false;
/* bad input */
841 items = (
char **)
malloc(inputlen * (
sizeof(
char *) +
sizeof(
char)));
843 return false;
/* out of memory */
845 strings = (
char *) (
items + inputlen);
847 atext++;
/* advance over initial '{' */
849 while (*atext !=
'}')
852 return false;
/* premature end of string */
853 items[curitem] = strings;
854 while (*atext !=
'}' && *atext !=
',')
857 return false;
/* premature end of string */
859 *strings++ = *atext++;
/* copy unquoted data */
862 /* process quoted substring */
864 while (*atext !=
'"')
867 return false;
/* premature end of string */
872 return false;
/* premature end of string */
874 *strings++ = *atext++;
/* copy quoted data */
884 if (atext[1] !=
'0円')
885 return false;
/* bogus syntax (embedded '}') */
892 * Append one element to the text representation of a 1-dimensional Postgres
895 * The caller must provide the initial '{' and closing '}' of the array.
896 * This function handles all else, including insertion of commas and
899 * We assume that typdelim is ','.
907 if (buffer->
data[buffer->
len - 1] !=
'{')
910 /* Decide if we need quotes; this should match array_out()'s choices. */
911 if (
value[0] ==
'0円')
912 needquote =
true;
/* force quotes for empty string */
914 needquote =
true;
/* force quotes for literal NULL */
920 for (tmp =
value; *tmp; tmp++)
924 if (ch ==
'"' || ch ==
'\\' ||
925 ch ==
'{' || ch ==
'}' || ch ==
',' ||
926 /* these match scanner_isspace(): */
927 ch ==
' ' || ch ==
'\t' || ch ==
'\n' ||
928 ch ==
'\r' || ch ==
'\v' || ch ==
'\f')
939 for (tmp =
value; *tmp; tmp++)
943 if (ch ==
'"' || ch ==
'\\')
955 * Format a reloptions array and append it to the given buffer.
957 * "prefix" is prepended to the option names; typically it's "" or "toast.".
959 * Returns false if the reloptions array could not be parsed (in which case
960 * nothing will have been appended to the buffer), or true on success.
962 * Note: this logic should generally match the backend's flatten_reloptions()
963 * (in adt/ruleutils.c).
967 const char *prefix,
int encoding,
bool std_strings)
987 * Each array element should have the form name=value. If the "=" is
988 * missing for some reason, treat it like an empty value.
1005 * In general we need to quote the value; but to avoid unnecessary
1006 * clutter, do not quote if it is an identifier that would not need
1007 * quoting. (We could also allow numbers, but that is a bit trickier
1008 * than it looks --- for example, are leading zeroes significant? We
1009 * don't want to assume very much here about what custom reloptions
1025 * processSQLNamePattern
1027 * Scan a wildcard-pattern string and generate appropriate WHERE clauses
1028 * to limit the set of objects returned. The WHERE clauses are appended
1029 * to the already-partially-constructed query in buf. Returns whether
1030 * any clause was added.
1032 * conn: connection query will be sent to (consulted for escaping rules).
1033 * buf: output parameter.
1034 * pattern: user-specified pattern option, or NULL if none ("*" is implied).
1035 * have_where: true if caller already emitted "WHERE" (clauses will be ANDed
1036 * onto the existing WHERE clause).
1037 * force_escape: always quote regexp special characters, even outside
1038 * double quotes (else they are quoted only between double quotes).
1039 * schemavar: name of query variable to match against a schema-name pattern.
1040 * Can be NULL if no schema.
1041 * namevar: name of query variable to match against an object-name pattern.
1042 * altnamevar: NULL, or name of an alternative variable to match against name.
1043 * visibilityrule: clause to use if we want to restrict to visible objects
1044 * (for example, "pg_catalog.pg_table_is_visible(p.oid)"). Can be NULL.
1045 * dbnamebuf: output parameter receiving the database name portion of the
1046 * pattern, if any. Can be NULL.
1047 * dotcnt: how many separators were parsed from the pattern, by reference.
1049 * Formatting note: the text already present in buf should end with a newline.
1050 * The appended text, if any, will end with one too.
1054 bool have_where,
bool force_escape,
1055 const char *schemavar,
const char *namevar,
1056 const char *altnamevar,
const char *visibilityrule,
1061 bool added_clause =
false;
1065 (appendPQExpBufferStr(buf, have_where ? " AND " : "WHERE "), \
1066 have_where = true, added_clause = true)
1071 if (pattern == NULL)
1073 /* Default: select all visible objects */
1079 return added_clause;
1086 * Convert shell-style 'pattern' into the regular expression(s) we want to
1087 * execute. Quoting/escaping into SQL literal format will be done below
1088 * using appendStringLiteralConn().
1090 * If the caller provided a schemavar, we want to split the pattern on
1091 * ".", otherwise not.
1094 (schemavar ? dbnamebuf : NULL),
1095 (schemavar ? &schemabuf : NULL),
1097 pattern, force_escape,
true, dotcnt);
1100 * Now decide what we need to emit. We may run under a hostile
1101 * search_path, so qualify EVERY name. Note there will be a leading "^("
1102 * in the patterns in any case.
1104 * We want the regex matches to use the database's default collation where
1105 * collation-sensitive behavior is required (for example, which characters
1106 * match '\w'). That happened by default before PG v12, but if the server
1107 * is >= v12 then we need to force it through explicit COLLATE clauses,
1108 * otherwise the "C" collation attached to "name" catalog columns wins.
1110 if (namevar && namebuf.
len > 2)
1112 /* We have a name pattern, so constrain the namevar(s) */
1114 /* Optimize away a "*" pattern */
1115 if (strcmp(namebuf.
data,
"^(.*)$") != 0)
1121 "(%s OPERATOR(pg_catalog.~) ", namevar);
1126 "\n OR %s OPERATOR(pg_catalog.~) ",
1144 if (schemavar && schemabuf.
len > 2)
1146 /* We have a schema pattern, so constrain the schemavar */
1148 /* Optimize away a "*" pattern */
1149 if (strcmp(schemabuf.
data,
"^(.*)$") != 0 && schemavar)
1161 /* No schema pattern given, so select only visible objects */
1172 return added_clause;
1177 * Transform a possibly qualified shell-style object name pattern into up to
1178 * three SQL-style regular expressions, converting quotes, lower-casing
1179 * unquoted letters, and adjusting shell-style wildcard characters into regexp
1182 * If the dbnamebuf and schemabuf arguments are non-NULL, and the pattern
1183 * contains two or more dbname/schema/name separators, we parse the portions of
1184 * the pattern prior to the first and second separators into dbnamebuf and
1185 * schemabuf, and the rest into namebuf.
1187 * If dbnamebuf is NULL and schemabuf is non-NULL, and the pattern contains at
1188 * least one separator, we parse the first portion into schemabuf and the rest
1191 * Otherwise, we parse all the pattern into namebuf.
1193 * If the pattern contains more dotted parts than buffers to parse into, the
1194 * extra dots will be treated as literal characters and written into the
1195 * namebuf, though they will be counted. Callers should always check the value
1196 * returned by reference in dotcnt and handle this error case appropriately.
1198 * We surround the regexps with "^(...)$" to force them to match whole strings,
1199 * as per SQL practice. We have to have parens in case strings contain "|",
1200 * else the "^" and "$" will be bound into the first and last alternatives
1201 * which is not what we want. Whether this is done for dbnamebuf is controlled
1202 * by the want_literal_dbname parameter.
1204 * The regexps we parse into the buffers are appended to the data (if any)
1205 * already present. If we parse fewer fields than the number of buffers we
1206 * were given, the extra buffers are unaltered.
1208 * encoding: the character encoding for the given pattern
1209 * dbnamebuf: output parameter receiving the database name portion of the
1210 * pattern, if any. Can be NULL.
1211 * schemabuf: output parameter receiving the schema name portion of the
1212 * pattern, if any. Can be NULL.
1213 * namebuf: output parameter receiving the database name portion of the
1214 * pattern, if any. Can be NULL.
1215 * pattern: user-specified pattern option, or NULL if none ("*" is implied).
1216 * force_escape: always quote regexp special characters, even outside
1217 * double quotes (else they are quoted only between double quotes).
1218 * want_literal_dbname: if true, regexp special characters within the database
1219 * name portion of the pattern will not be escaped, nor will the dbname be
1220 * converted into a regular expression.
1221 * dotcnt: output parameter receiving the number of separators parsed from the
1226 PQExpBuffer namebuf,
const char *pattern,
bool force_escape,
1227 bool want_literal_dbname,
int *dotcnt)
1241 /* callers should never expect "dbname.relname" format */
1242 Assert(dbnamebuf == NULL || schemabuf != NULL);
1249 if (dbnamebuf != NULL)
1251 else if (schemabuf != NULL)
1257 if (want_literal_dbname)
1272 if (inquotes && cp[1] ==
'"')
1274 /* emit one quote, stay in inquotes mode */
1281 inquotes = !inquotes;
1284 else if (!inquotes && isupper((
unsigned char) ch))
1293 else if (!inquotes && ch ==
'*')
1300 else if (!inquotes && ch ==
'?')
1307 else if (!inquotes && ch ==
'.')
1312 if (curbuf < maxbuf)
1326 * Dollar is always quoted, whether inside quotes or not. The
1327 * reason is that it's allowed in SQL identifiers, so there's a
1328 * significant use-case for treating it literally, while because
1329 * we anchor the pattern automatically there is no use-case for
1330 * having it possess its regexp meaning.
1340 * Ordinary data character, transfer to pattern
1342 * Inside double quotes, or at all times if force_escape is true,
1343 * quote regexp special characters with a backslash to avoid
1344 * regexp errors. Outside quotes, however, let them pass through
1345 * as-is; this lets knowledgeable users build regexp expressions
1346 * that are more powerful than shell-style patterns.
1348 * As an exception to that, though, always quote "[]", as that's
1349 * much more likely to be an attempt to write an array type name
1350 * than it is to be the start of a regexp bracket expression.
1352 if ((inquotes || force_escape) &&
1353 strchr(
"|*+?()[]{}.^$\\", ch))
1355 else if (ch ==
'[' && cp[1] ==
']')
1375 if (schemabuf && curbuf >=
buf)
1382 if (dbnamebuf && curbuf >=
buf)
1384 if (want_literal_dbname)
1391 if (want_literal_dbname)
#define IS_HIGHBIT_SET(ch)
#define ESCAPE_STRING_SYNTAX
#define SQL_STR_DOUBLE(ch, escape_backslash)
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
#define fprintf(file, fmt, msg)
int PQserverVersion(const PGconn *conn)
int PQclientEncoding(const PGconn *conn)
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
int PQmblen(const char *s, int encoding)
int PQmblenBounded(const char *s, int encoding)
Assert(PointerIsAligned(start, uint64))
PGDLLIMPORT const ScanKeywordList ScanKeywords
#define UNRESERVED_KEYWORD
int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords)
static const char * connstr
static rewind_source * source
static const char hextbl[]
int pg_strcasecmp(const char *s1, const char *s2)
unsigned char pg_tolower(unsigned char ch)
PQExpBuffer createPQExpBuffer(void)
void initPQExpBuffer(PQExpBuffer str)
int enlargePQExpBuffer(PQExpBuffer str, size_t needed)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
PQExpBufferData * PQExpBuffer
const char * fmtQualifiedId(const char *schema, const char *id)
bool appendShellStringNoError(PQExpBuffer buf, const char *str)
const char * fmtIdEnc(const char *rawid, int encoding)
const char * fmtId(const char *rawid)
const char * fmtQualifiedIdEnc(const char *schema, const char *id, int encoding)
void setFmtEncoding(int encoding)
void appendShellString(PQExpBuffer buf, const char *str)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
void appendPGArray(PQExpBuffer buffer, const char *value)
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule, PQExpBuffer dbnamebuf, int *dotcnt)
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
void appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length, bool std_strings)
bool parsePGArray(const char *atext, char ***itemarray, int *nitems)
void appendStringLiteral(PQExpBuffer buf, const char *str, int encoding, bool std_strings)
void patternToSQLRegex(int encoding, PQExpBuffer dbnamebuf, PQExpBuffer schemabuf, PQExpBuffer namebuf, const char *pattern, bool force_escape, bool want_literal_dbname, int *dotcnt)
bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, const char *prefix, int encoding, bool std_strings)
static PQExpBuffer defaultGetLocalPQExpBuffer(void)
static int getFmtEncoding(void)
PQExpBuffer(* getLocalPQExpBuffer)(void)
void appendStringLiteralDQ(PQExpBuffer buf, const char *str, const char *dqprefix)
void appendConnStrVal(PQExpBuffer buf, const char *str)
int quote_all_identifiers
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
void pg_encoding_set_invalid(int encoding, char *dst)
int pg_encoding_mblen(int encoding, const char *mbstr)
int pg_encoding_verifymbchar(int encoding, const char *mbstr, int len)