From beb4699091e9fab1c5f465056bef35c9ddf7f9fc Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Wed, 29 Jan 2020 10:19:24 -0500 Subject: [PATCH] Move jsonapi.c and jsonapi.h to src/common. To make this work, (1) makeJsonLexContextCstringLen now takes the encoding to be used as an argument; (2) check_stack_depth() is made to do nothing in frontend code, and (3) elog(ERROR, ...) is changed to pg_log_fatal + exit in frontend code. Mark Dilger, reviewed and slightly revised by me. Discussion: http://postgr.es/m/CA+TgmoYfOXhd27MUDGioVh6QtpD0C1K-f6ObSA10AWiHBAL5bA@mail.gmail.com --- 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..f08a03c169 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" #include "mb/pg_wchar.h" + +#ifdef FRONTEND +#include "common/logging.h" +#else #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" /*