0007-Moving-json-parsing-logic-into-common.patch.WIP

application/octet-stream

Filename: 0007-Moving-json-parsing-logic-into-common.patch.WIP
Type: application/octet-stream
Part: 6
Message: Re: making the backend's json parser work in frontend code
From fdf45e14e66f9dc7299142a9b0e7a5dc6d95a034 Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Tue, 21 Jan 2020 13:05:48 -0800
Subject: [PATCH 07/11] Moving json parsing logic into common.

Parsing logic for json was in src/backend/utils/adt, but
to be able to parse json from frontend code, this needs
to be moved to common.
---
 src/backend/utils/adt/json.c | 29 +++++++++++------------------
 src/common/jsonapi.c         |  7 +++++++
 src/include/common/jsonapi.h |  5 ++++-
 3 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index dc71909a3c..f86d5042a7 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -80,11 +80,11 @@ static inline void json_lex(JsonLexContext *lex);
 static inline void json_lex_string(JsonLexContext *lex);
 static inline void json_lex_number(JsonLexContext *lex, char *s,
 								   bool *num_err, int *total_len);
-static inline void parse_scalar(JsonLexContext *lex, JsonSemAction *sem);
-static void parse_object_field(JsonLexContext *lex, JsonSemAction *sem);
-static void parse_object(JsonLexContext *lex, JsonSemAction *sem);
-static void parse_array_element(JsonLexContext *lex, JsonSemAction *sem);
-static void parse_array(JsonLexContext *lex, JsonSemAction *sem);
+static inline void parse_scalar(JsonLexContext *lex, const JsonSemAction *sem);
+static void parse_object_field(JsonLexContext *lex, const JsonSemAction *sem);
+static void parse_object(JsonLexContext *lex, const JsonSemAction *sem);
+static void parse_array_element(JsonLexContext *lex, const JsonSemAction *sem);
+static void parse_array(JsonLexContext *lex, const JsonSemAction *sem);
 static void report_parse_error(JsonParseContext ctx, JsonLexContext *lex) pg_attribute_noreturn();
 static void report_invalid_token(JsonLexContext *lex) pg_attribute_noreturn();
 static int	report_json_context(JsonLexContext *lex);
@@ -107,13 +107,6 @@ static void add_json(Datum val, bool is_null, StringInfo result,
 					 Oid val_type, bool key_scalar);
 static text *catenate_stringinfo_string(StringInfo buffer, const char *addon);
 
-/* the null action object used for pure validation */
-static JsonSemAction nullSemAction =
-{
-	NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, NULL
-};
-
 /* Recursive Descent parser support routines */
 
 /*
@@ -297,7 +290,7 @@ json_recv(PG_FUNCTION_ARGS)
  * pointer to a state object to be passed to those routines.
  */
 void
-pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
+pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
 {
 	JsonTokenType tok;
 
@@ -372,7 +365,7 @@ json_count_array_elements(JsonLexContext *lex)
  *	  - object field
  */
 static inline void
-parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
+parse_scalar(JsonLexContext *lex, const JsonSemAction *sem)
 {
 	char	   *val = NULL;
 	json_scalar_action sfunc = sem->scalar;
@@ -408,7 +401,7 @@ parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
 }
 
 static void
-parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
+parse_object_field(JsonLexContext *lex, const JsonSemAction *sem)
 {
 	/*
 	 * An object field is "fieldname" : value where value can be a scalar,
@@ -454,7 +447,7 @@ parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
 }
 
 static void
-parse_object(JsonLexContext *lex, JsonSemAction *sem)
+parse_object(JsonLexContext *lex, const JsonSemAction *sem)
 {
 	/*
 	 * an object is a possibly empty sequence of object fields, separated by
@@ -504,7 +497,7 @@ parse_object(JsonLexContext *lex, JsonSemAction *sem)
 }
 
 static void
-parse_array_element(JsonLexContext *lex, JsonSemAction *sem)
+parse_array_element(JsonLexContext *lex, const JsonSemAction *sem)
 {
 	json_aelem_action astart = sem->array_element_start;
 	json_aelem_action aend = sem->array_element_end;
@@ -535,7 +528,7 @@ parse_array_element(JsonLexContext *lex, JsonSemAction *sem)
 }
 
 static void
-parse_array(JsonLexContext *lex, JsonSemAction *sem)
+parse_array(JsonLexContext *lex, const JsonSemAction *sem)
 {
 	/*
 	 * an array is a possibly empty sequence of array elements, separated by
diff --git a/src/common/jsonapi.c b/src/common/jsonapi.c
index 69fa42705f..c14d6ff4f2 100644
--- a/src/common/jsonapi.c
+++ b/src/common/jsonapi.c
@@ -18,6 +18,13 @@
 #include "utils/palloc.h"
 #endif
 
+/* the null action object used for pure validation */
+const JsonSemAction nullSemAction =
+{
+	NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL
+};
+
 JsonLexContext *
 makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
 {
diff --git a/src/include/common/jsonapi.h b/src/include/common/jsonapi.h
index fd1d94d1d7..581fd48036 100644
--- a/src/include/common/jsonapi.h
+++ b/src/include/common/jsonapi.h
@@ -92,6 +92,9 @@ typedef struct JsonSemAction
 	json_scalar_action scalar;
 } JsonSemAction;
 
+/* the null action object used for pure validation */
+extern const JsonSemAction nullSemAction;
+
 /*
  * pg_parse_json will parse the string in the lex calling the
  * action functions in sem at the appropriate points. It is
@@ -101,7 +104,7 @@ typedef struct JsonSemAction
  * points to. If the action pointers are NULL the parser
  * does nothing and just continues.
  */
-extern void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem);
+extern void pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem);
 
 /*
  * json_count_array_elements performs a fast secondary parse to determine the
-- 
2.21.1 (Apple Git-122.3)