From a995c0ddc3077879199bf0b2bc73c2611e77d593 Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Tue, 28 Jan 2020 09:17:55 -0800
Subject: [PATCH 1/2] Relocating jsonapi to common.

Moving jsonapi.c and jsonapi.h to src/common and src/include/common.
Reworking the code to not include elog, ereport, pg_mblen, and
similar backend-only functionality.
---
 contrib/hstore/hstore_io.c                  |  2 +-
 src/backend/tsearch/to_tsany.c              |  2 +-
 src/backend/tsearch/wparser.c               |  2 +-
 src/backend/utils/adt/Makefile              |  1 -
 src/backend/utils/adt/json.c                |  2 +-
 src/backend/utils/adt/jsonb.c               |  2 +-
 src/backend/utils/adt/jsonb_util.c          |  2 +-
 src/backend/utils/adt/jsonfuncs.c           |  7 ++--
 src/common/Makefile                         |  1 +
 src/{backend/utils/adt => common}/jsonapi.c | 36 +++++++++++++++------
 src/include/{utils => common}/jsonapi.h     |  2 ++
 src/include/utils/jsonfuncs.h               |  2 +-
 12 files changed, 41 insertions(+), 20 deletions(-)
 rename src/{backend/utils/adt => common}/jsonapi.c (96%)
 rename src/include/{utils => common}/jsonapi.h (99%)

diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index 10ec392775..f3174f2995 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -7,13 +7,13 @@
 
 #include "access/htup_details.h"
 #include "catalog/pg_type.h"
+#include "common/jsonapi.h"
 #include "funcapi.h"
 #include "hstore.h"
 #include "lib/stringinfo.h"
 #include "libpq/pqformat.h"
 #include "utils/builtins.h"
 #include "utils/json.h"
-#include "utils/jsonapi.h"
 #include "utils/jsonb.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c
index adf181c191..1fe67c4c99 100644
--- a/src/backend/tsearch/to_tsany.c
+++ b/src/backend/tsearch/to_tsany.c
@@ -13,10 +13,10 @@
  */
 #include "postgres.h"
 
+#include "common/jsonapi.h"
 #include "tsearch/ts_cache.h"
 #include "tsearch/ts_utils.h"
 #include "utils/builtins.h"
-#include "utils/jsonapi.h"
 #include "utils/jsonfuncs.h"
 
 
diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c
index c7499a94ac..88005c0519 100644
--- a/src/backend/tsearch/wparser.c
+++ b/src/backend/tsearch/wparser.c
@@ -16,11 +16,11 @@
 #include "catalog/namespace.h"
 #include "catalog/pg_type.h"
 #include "commands/defrem.h"
+#include "common/jsonapi.h"
 #include "funcapi.h"
 #include "tsearch/ts_cache.h"
 #include "tsearch/ts_utils.h"
 #include "utils/builtins.h"
-#include "utils/jsonapi.h"
 #include "utils/jsonfuncs.h"
 #include "utils/varlena.h"
 
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 790d7a24fb..13efa9338c 100644
--- a/src/backend/utils/adt/Makefile
+++ b/src/backend/utils/adt/Makefile
@@ -44,7 +44,6 @@ OBJS = \
 	int.o \
 	int8.o \
 	json.o \
-	jsonapi.o \
 	jsonb.o \
 	jsonb_gin.o \
 	jsonb_op.o \
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index f6cd2b9911..567eab1e01 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -127,7 +127,7 @@ json_recv(PG_FUNCTION_ARGS)
 	str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
 
 	/* Validate it. */
-	lex = makeJsonLexContextCstringLen(str, nbytes, false);
+	lex = makeJsonLexContextCstringLen(str, nbytes, GetDatabaseEncoding(), false);
 	pg_parse_json_or_ereport(lex, &nullSemAction);
 
 	PG_RETURN_TEXT_P(cstring_to_text_with_len(str, nbytes));
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index c912f8932d..fea4335951 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -261,7 +261,7 @@ jsonb_from_cstring(char *json, int len)
 
 	memset(&state, 0, sizeof(state));
 	memset(&sem, 0, sizeof(sem));
-	lex = makeJsonLexContextCstringLen(json, len, true);
+	lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true);
 
 	sem.semstate = (void *) &state;
 
diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c
index b33c3ef43c..edec657cd3 100644
--- a/src/backend/utils/adt/jsonb_util.c
+++ b/src/backend/utils/adt/jsonb_util.c
@@ -15,12 +15,12 @@
 
 #include "catalog/pg_collation.h"
 #include "catalog/pg_type.h"
+#include "common/jsonapi.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
 #include "utils/datetime.h"
 #include "utils/hashutils.h"
 #include "utils/json.h"
-#include "utils/jsonapi.h"
 #include "utils/jsonb.h"
 #include "utils/memutils.h"
 #include "utils/varlena.h"
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index 66ea11b971..4f6fd0de02 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -18,6 +18,7 @@
 
 #include "access/htup_details.h"
 #include "catalog/pg_type.h"
+#include "common/jsonapi.h"
 #include "fmgr.h"
 #include "funcapi.h"
 #include "lib/stringinfo.h"
@@ -27,7 +28,6 @@
 #include "utils/builtins.h"
 #include "utils/hsearch.h"
 #include "utils/json.h"
-#include "utils/jsonapi.h"
 #include "utils/jsonb.h"
 #include "utils/jsonfuncs.h"
 #include "utils/lsyscache.h"
@@ -514,6 +514,7 @@ makeJsonLexContext(text *json, bool need_escapes)
 {
 	return makeJsonLexContextCstringLen(VARDATA_ANY(json),
 										VARSIZE_ANY_EXHDR(json),
+										GetDatabaseEncoding(),
 										need_escapes);
 }
 
@@ -2605,7 +2606,7 @@ populate_array_json(PopulateArrayContext *ctx, char *json, int len)
 	PopulateArrayState state;
 	JsonSemAction sem;
 
-	state.lex = makeJsonLexContextCstringLen(json, len, true);
+	state.lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true);
 	state.ctx = ctx;
 
 	memset(&sem, 0, sizeof(sem));
@@ -3448,7 +3449,7 @@ get_json_object_as_hash(char *json, int len, const char *funcname)
 	HASHCTL		ctl;
 	HTAB	   *tab;
 	JHashState *state;
-	JsonLexContext *lex = makeJsonLexContextCstringLen(json, len, true);
+	JsonLexContext *lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true);
 	JsonSemAction *sem;
 
 	memset(&ctl, 0, sizeof(ctl));
diff --git a/src/common/Makefile b/src/common/Makefile
index 44ca68fa6c..e757fb7399 100644
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -56,6 +56,7 @@ OBJS_COMMON = \
 	f2s.o \
 	file_perm.o \
 	ip.o \
+	jsonapi.o \
 	keywords.o \
 	kwlookup.o \
 	link-canary.o \
diff --git a/src/backend/utils/adt/jsonapi.c b/src/common/jsonapi.c
similarity index 96%
rename from src/backend/utils/adt/jsonapi.c
rename to src/common/jsonapi.c
index 230a55b101..7628fe52e1 100644
--- a/src/backend/utils/adt/jsonapi.c
+++ b/src/common/jsonapi.c
@@ -7,15 +7,32 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  src/backend/utils/adt/jsonapi.c
+ *	  src/common/jsonapi.c
  *
  *-------------------------------------------------------------------------
  */
+#ifndef FRONTEND
 #include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
 
+#include "common/jsonapi.h"
+
+#ifdef FRONTEND
+#include "common/logging.h"
+#include "mb/pg_wchar.h"
+#else
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
-#include "utils/jsonapi.h"
+#endif
+
+#ifdef FRONTEND
+#define check_stack_depth()
+#define json_log_and_abort(...) do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0)
+#else
+#define json_log_and_abort(...) elog(ERROR, __VA_ARGS__)
+#endif
 
 /*
  * The context of the parser is maintained by the recursive descent
@@ -135,13 +152,14 @@ IsValidJsonNumber(const char *str, int len)
  * if really required.
  */
 JsonLexContext *
-makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
+makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
 {
 	JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
 
 	lex->input = lex->token_terminator = lex->line_start = json;
 	lex->line_number = 1;
 	lex->input_length = len;
+	lex->input_encoding = encoding;
 	if (need_escapes)
 		lex->strval = makeStringInfo();
 	return lex;
@@ -720,7 +738,7 @@ json_lex_string(JsonLexContext *lex)
 						ch = (ch * 16) + (*s - 'A') + 10;
 					else
 					{
-						lex->token_terminator = s + pg_mblen(s);
+						lex->token_terminator = s + pg_encoding_mblen(lex->input_encoding, s);
 						return JSON_UNICODE_ESCAPE_FORMAT;
 					}
 				}
@@ -759,7 +777,7 @@ json_lex_string(JsonLexContext *lex)
 						/* We can't allow this, since our TEXT type doesn't */
 						return JSON_UNICODE_CODE_POINT_ZERO;
 					}
-					else if (GetDatabaseEncoding() == PG_UTF8)
+					else if (lex->input_encoding == PG_UTF8)
 					{
 						unicode_to_utf8(ch, (unsigned char *) utf8str);
 						utf8len = pg_utf_mblen((unsigned char *) utf8str);
@@ -809,7 +827,7 @@ json_lex_string(JsonLexContext *lex)
 					default:
 						/* Not a valid string escape, so signal error. */
 						lex->token_start = s;
-						lex->token_terminator = s + pg_mblen(s);
+						lex->token_terminator = s + pg_encoding_mblen(lex->input_encoding, s);
 						return JSON_ESCAPING_INVALID;
 				}
 			}
@@ -823,7 +841,7 @@ json_lex_string(JsonLexContext *lex)
 				 * shown it's not a performance win.
 				 */
 				lex->token_start = s;
-				lex->token_terminator = s + pg_mblen(s);
+				lex->token_terminator = s + pg_encoding_mblen(lex->input_encoding, s);
 				return JSON_ESCAPING_INVALID;
 			}
 
@@ -1010,7 +1028,7 @@ report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
 	 * unhandled enum values.  But this needs to be here anyway to cover the
 	 * possibility of an incorrect input.
 	 */
-	elog(ERROR, "unexpected json parse state: %d", (int) ctx);
+	json_log_and_abort("unexpected json parse state: %d", (int) ctx);
 	return JSON_SUCCESS;		/* silence stupider compilers */
 }
 
@@ -1077,7 +1095,7 @@ json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
 	 * unhandled enum values.  But this needs to be here anyway to cover the
 	 * possibility of an incorrect input.
 	 */
-	elog(ERROR, "unexpected json parse error type: %d", (int) error);
+	json_log_and_abort("unexpected json parse error type: %d", (int) error);
 	return NULL;				/* silence stupider compilers */
 }
 
diff --git a/src/include/utils/jsonapi.h b/src/include/common/jsonapi.h
similarity index 99%
rename from src/include/utils/jsonapi.h
rename to src/include/common/jsonapi.h
index 4d69b18495..bcfd57cc53 100644
--- a/src/include/utils/jsonapi.h
+++ b/src/include/common/jsonapi.h
@@ -73,6 +73,7 @@ typedef struct JsonLexContext
 {
 	char	   *input;
 	int			input_length;
+	int			input_encoding;
 	char	   *token_start;
 	char	   *token_terminator;
 	char	   *prev_token_terminator;
@@ -149,6 +150,7 @@ extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
  */
 extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
 													int len,
+													int encoding,
 													bool need_escapes);
 
 /* lex one token */
diff --git a/src/include/utils/jsonfuncs.h b/src/include/utils/jsonfuncs.h
index b993f38409..1f1b4029cb 100644
--- a/src/include/utils/jsonfuncs.h
+++ b/src/include/utils/jsonfuncs.h
@@ -14,7 +14,7 @@
 #ifndef JSONFUNCS_H
 #define JSONFUNCS_H
 
-#include "utils/jsonapi.h"
+#include "common/jsonapi.h"
 #include "utils/jsonb.h"
 
 /*
-- 
2.21.1 (Apple Git-122.3)

