aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2019-12-10 17:09:32 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2019-12-10 17:12:56 -0300
commit6cafde1bd43f1c28b044953cac2f2999eb425b22 (patch)
treef08bc9618832f34f0a26192ab04014d7300e43d8 /src/backend/utils
parent0da33c762b85aeada111aa1371c33ac6737f8396 (diff)
downloadpostgresql-6cafde1bd43f1c28b044953cac2f2999eb425b22.tar.gz
postgresql-6cafde1bd43f1c28b044953cac2f2999eb425b22.zip
Add backend-only appendStringInfoStringQuoted
This provides a mechanism to emit literal values in informative messages, such as query parameters. The new code is more complex than what it replaces, primarily because it wants to be more efficient. It also has the (currently unused) additional optional capability of specifying a maximum size to print. The new function lives out of common/stringinfo.c so that frontend users of that file need not pull in unnecessary multibyte-encoding support code. Author: Álvaro Herrera and Alexey Bashtanov, after a suggestion from Andres Freund Reviewed-by: Tom Lane Discussion: https://postgr.es/m/20190920203905.xkv5udsd5dxfs6tr@alap3.anarazel.de
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/mb/Makefile1
-rw-r--r--src/backend/utils/mb/README1
-rw-r--r--src/backend/utils/mb/stringinfo_mb.c86
3 files changed, 88 insertions, 0 deletions
diff --git a/src/backend/utils/mb/Makefile b/src/backend/utils/mb/Makefile
index 18dd758cfe8..cd4a016449e 100644
--- a/src/backend/utils/mb/Makefile
+++ b/src/backend/utils/mb/Makefile
@@ -16,6 +16,7 @@ OBJS = \
conv.o \
encnames.o \
mbutils.o \
+ stringinfo_mb.o \
wchar.o \
wstrcmp.o \
wstrncmp.o
diff --git a/src/backend/utils/mb/README b/src/backend/utils/mb/README
index c9bc6e6f8d6..7495ca5db23 100644
--- a/src/backend/utils/mb/README
+++ b/src/backend/utils/mb/README
@@ -9,6 +9,7 @@ wchar.c: mostly static functions and a public table for mb string and
multibyte conversion
mbutils.c: public functions for the backend only.
requires conv.c and wchar.c
+stringinfo_mb.c: public backend-only multibyte-aware stringinfo functions
wstrcmp.c: strcmp for mb
wstrncmp.c: strncmp for mb
win866.c: a tool to generate KOI8 <--> CP866 conversion table
diff --git a/src/backend/utils/mb/stringinfo_mb.c b/src/backend/utils/mb/stringinfo_mb.c
new file mode 100644
index 00000000000..51bb051206e
--- /dev/null
+++ b/src/backend/utils/mb/stringinfo_mb.c
@@ -0,0 +1,86 @@
+/*-------------------------------------------------------------------------
+ *
+ * stringinfo_mb.c
+ * Multibyte encoding-aware additional StringInfo facilites
+ *
+ * This is separate from common/stringinfo.c so that frontend users
+ * of that file need not pull in unnecessary multibyte-encoding support
+ * code.
+ *
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/utils/mb/stringinfo_mb.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "mb/stringinfo_mb.h"
+#include "mb/pg_wchar.h"
+
+
+/*
+ * appendStringInfoStringQuoted
+ *
+ * Append up to maxlen characters from s to str, or the whole input string if
+ * maxlen <= 0, adding single quotes around it and doubling all single quotes.
+ * Add an ellipsis if the copy is incomplete.
+ */
+void
+appendStringInfoStringQuoted(StringInfo str, const char *s, int maxlen)
+{
+ char *copy = NULL;
+ const char *chunk_search_start,
+ *chunk_copy_start,
+ *chunk_end;
+ int slen;
+ bool ellipsis;
+
+ Assert(str != NULL);
+
+ slen = strlen(s);
+ if (maxlen > 0 && maxlen < slen)
+ {
+ int finallen = pg_mbcliplen(s, slen, maxlen);
+
+ copy = pnstrdup(s, finallen);
+ chunk_search_start = copy;
+ chunk_copy_start = copy;
+
+ ellipsis = true;
+ }
+ else
+ {
+ chunk_search_start = s;
+ chunk_copy_start = s;
+
+ ellipsis = false;
+ }
+
+ appendStringInfoCharMacro(str, '\'');
+
+ while ((chunk_end = strchr(chunk_search_start, '\'')) != NULL)
+ {
+ /* copy including the found delimiting ' */
+ appendBinaryStringInfoNT(str,
+ chunk_copy_start,
+ chunk_end - chunk_copy_start + 1);
+
+ /* in order to double it, include this ' into the next chunk as well */
+ chunk_copy_start = chunk_end;
+ chunk_search_start = chunk_end + 1;
+ }
+
+ /* copy the last chunk and terminate */
+ if (ellipsis)
+ appendStringInfo(str, "%s...'", chunk_copy_start);
+ else
+ appendStringInfo(str, "%s'", chunk_copy_start);
+
+ if (copy)
+ pfree(copy);
+}