aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonapi.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2020-01-27 11:22:13 -0500
committerRobert Haas <rhaas@postgresql.org>2020-01-27 11:22:13 -0500
commit73ce2a03f30b52d6bfb26bc28f1e3e1aa1637577 (patch)
treea6a19f146fb7281f146fec7d413a79032fd1557f /src/backend/utils/adt/jsonapi.c
parent1f3a021730be98b880d94cabbe21de7e4d8136f5 (diff)
downloadpostgresql-73ce2a03f30b52d6bfb26bc28f1e3e1aa1637577.tar.gz
postgresql-73ce2a03f30b52d6bfb26bc28f1e3e1aa1637577.zip
Move some code from jsonapi.c to jsonfuncs.c.
Specifically, move those functions that depend on ereport() from jsonapi.c to jsonfuncs.c, in preparation for allowing jsonapi.c to be used from frontend code. A few cases where elog(ERROR, ...) is used for can't-happen conditions are left alone; we can handle those in some other way in frontend code. Reviewed by Mark Dilger and Andrew Dunstan. Discussion: http://postgr.es/m/CA+TgmoYfOXhd27MUDGioVh6QtpD0C1K-f6ObSA10AWiHBAL5bA@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/jsonapi.c')
-rw-r--r--src/backend/utils/adt/jsonapi.c127
1 files changed, 2 insertions, 125 deletions
diff --git a/src/backend/utils/adt/jsonapi.c b/src/backend/utils/adt/jsonapi.c
index 129fbd65d51..1ac3b7beda8 100644
--- a/src/backend/utils/adt/jsonapi.c
+++ b/src/backend/utils/adt/jsonapi.c
@@ -44,7 +44,6 @@ static JsonParseErrorType parse_object(JsonLexContext *lex, JsonSemAction *sem);
static JsonParseErrorType parse_array_element(JsonLexContext *lex, JsonSemAction *sem);
static JsonParseErrorType parse_array(JsonLexContext *lex, JsonSemAction *sem);
static JsonParseErrorType report_parse_error(JsonParseContext ctx, JsonLexContext *lex);
-static int report_json_context(JsonLexContext *lex);
static char *extract_token(JsonLexContext *lex);
/* the null action object used for pure validation */
@@ -128,26 +127,14 @@ IsValidJsonNumber(const char *str, int len)
}
/*
- * makeJsonLexContext
+ * makeJsonLexContextCstringLen
*
- * lex constructor, with or without StringInfo object
- * for de-escaped lexemes.
+ * lex constructor, with or without StringInfo object for de-escaped lexemes.
*
* Without is better as it makes the processing faster, so only make one
* if really required.
- *
- * If you already have the json as a text* value, use the first of these
- * functions, otherwise use makeJsonLexContextCstringLen().
*/
JsonLexContext *
-makeJsonLexContext(text *json, bool need_escapes)
-{
- return makeJsonLexContextCstringLen(VARDATA_ANY(json),
- VARSIZE_ANY_EXHDR(json),
- need_escapes);
-}
-
-JsonLexContext *
makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
{
JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
@@ -203,23 +190,6 @@ pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
}
/*
- * pg_parse_json_or_ereport
- *
- * This fuction is like pg_parse_json, except that it does not return a
- * JsonParseErrorType. Instead, in case of any failure, this function will
- * ereport(ERROR).
- */
-void
-pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem)
-{
- JsonParseErrorType result;
-
- result = pg_parse_json(lex, sem);
- if (result != JSON_SUCCESS)
- json_ereport_error(result, lex);
-}
-
-/*
* json_count_array_elements
*
* Returns number of array elements in lex context at start of array token
@@ -1039,27 +1009,6 @@ report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
}
/*
- * Report a JSON error.
- */
-void
-json_ereport_error(JsonParseErrorType error, JsonLexContext *lex)
-{
- if (error == JSON_UNICODE_HIGH_ESCAPE ||
- error == JSON_UNICODE_CODE_POINT_ZERO)
- ereport(ERROR,
- (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
- errmsg("unsupported Unicode escape sequence"),
- errdetail("%s", json_errdetail(error, lex)),
- report_json_context(lex)));
- else
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type %s", "json"),
- errdetail("%s", json_errdetail(error, lex)),
- report_json_context(lex)));
-}
-
-/*
* Construct a detail message for a JSON error.
*/
char *
@@ -1119,78 +1068,6 @@ json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
}
/*
- * Report a CONTEXT line for bogus JSON input.
- *
- * lex->token_terminator must be set to identify the spot where we detected
- * the error. Note that lex->token_start might be NULL, in case we recognized
- * error at EOF.
- *
- * The return value isn't meaningful, but we make it non-void so that this
- * can be invoked inside ereport().
- */
-static int
-report_json_context(JsonLexContext *lex)
-{
- const char *context_start;
- const char *context_end;
- const char *line_start;
- int line_number;
- char *ctxt;
- int ctxtlen;
- const char *prefix;
- const char *suffix;
-
- /* Choose boundaries for the part of the input we will display */
- context_start = lex->input;
- context_end = lex->token_terminator;
- line_start = context_start;
- line_number = 1;
- for (;;)
- {
- /* Always advance over newlines */
- if (context_start < context_end && *context_start == '\n')
- {
- context_start++;
- line_start = context_start;
- line_number++;
- continue;
- }
- /* Otherwise, done as soon as we are close enough to context_end */
- if (context_end - context_start < 50)
- break;
- /* Advance to next multibyte character */
- if (IS_HIGHBIT_SET(*context_start))
- context_start += pg_mblen(context_start);
- else
- context_start++;
- }
-
- /*
- * We add "..." to indicate that the excerpt doesn't start at the
- * beginning of the line ... but if we're within 3 characters of the
- * beginning of the line, we might as well just show the whole line.
- */
- if (context_start - line_start <= 3)
- context_start = line_start;
-
- /* Get a null-terminated copy of the data to present */
- ctxtlen = context_end - context_start;
- ctxt = palloc(ctxtlen + 1);
- memcpy(ctxt, context_start, ctxtlen);
- ctxt[ctxtlen] = '\0';
-
- /*
- * Show the context, prefixing "..." if not starting at start of line, and
- * suffixing "..." if not ending at end of line.
- */
- prefix = (context_start > line_start) ? "..." : "";
- suffix = (lex->token_type != JSON_TOKEN_END && context_end - lex->input < lex->input_length && *context_end != '\n' && *context_end != '\r') ? "..." : "";
-
- return errcontext("JSON data, line %d: %s%s%s",
- line_number, prefix, ctxt, suffix);
-}
-
-/*
* Extract the current token from a lexing context, for error reporting.
*/
static char *