Hi Robert,
On 1/16/20 11:51 AM, Robert Haas wrote:
On Thu, Jan 16, 2020 at 1:37 PM David Steele <da...@pgmasters.net> wrote:
The next question in my mind is given the caveat that the error handing
is questionable in the front end, can we at least render/parse valid
JSON with the code?
That's a real good question. Thanks for offering to test it; I think
that would be very helpful.
It seems to work just fine. I didn't stress it too hard but I did put
in one escape and a multi-byte character and check the various data types.
Attached is a test hack on pg_basebackup which produces this output:
START
FIELD "number", null 0
SCALAR TYPE 2: 123
FIELD "string", null 0
SCALAR TYPE 1: val ue-丏
FIELD "bool", null 0
SCALAR TYPE 9: true
FIELD "null", null 1
SCALAR TYPE 11: null
END
I used the callbacks because that's the first method I found but it
seems like json_lex() might be easier to use in practice.
I think it's an issue that the entire string must be passed to the lexer
at once. That will not be great for large manifests. However, I don't
think it will be all that hard to implement an optional "want more"
callback in the lexer so JSON data can be fed in from the file in chunks.
So, that just leaves ereport() as the largest remaining issue? I'll
look at that today and Tuesday and see what I can work up.
Regards,
--
-David
da...@pgmasters.net
diff --git a/src/bin/pg_basebackup/pg_basebackup.c
b/src/bin/pg_basebackup/pg_basebackup.c
index 238b671f7a..00b74118fb 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -41,6 +41,7 @@
#include "receivelog.h"
#include "replication/basebackup.h"
#include "streamutil.h"
+#include "utils/jsonapi.h"
#define ERRCODE_DATA_CORRUPTED "XX001"
@@ -2019,10 +2020,40 @@ BaseBackup(void)
pg_log_info("base backup completed");
}
+void
+jsonOFieldAction(void *state, char *fname, bool isnull)
+{
+ fprintf(stderr, " FIELD \"%s\", null %d\n", fname, isnull);
fflush(stderr);
+ pfree(fname);
+}
+
+void
+jsonScalarAction(void *state, char *token, JsonTokenType tokentype)
+{
+ fprintf(stderr, " SCALAR TYPE %u: %s\n", tokentype, token);
fflush(stderr);
+ pfree(token);
+}
int
main(int argc, char **argv)
{
+ if (true)
+ {
+ char json[] = "{\"number\": 123, \"string\": \"val\\tue-丏\",
\"bool\": true, \"null\": null}";
+ JsonSemAction sem = {.semstate = NULL, .scalar =
jsonScalarAction, .object_field_start = jsonOFieldAction};
+ JsonLexContext *lex;
+
+ fprintf(stderr, "START\n"); fflush(stderr);
+
+ lex = makeJsonLexContextCstringLen(json, strlen(json), true);
+
+ pg_parse_json(lex, &sem);
+
+ fprintf(stderr, "END\n"); fflush(stderr);
+
+ exit(0);
+ }
+
static struct option long_options[] = {
{"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'},