json-error-context-1.patch
text/x-patch
Filename: json-error-context-1.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/json.c | 0 | 0 |
| src/test/regress/expected/json.out | 0 | 0 |
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index e79c294..59335db 100644
*** a/src/backend/utils/adt/json.c
--- b/src/backend/utils/adt/json.c
*************** typedef struct /* state of JSON lexe
*** 43,50 ****
char *token_start; /* start of current token within input */
char *token_terminator; /* end of previous or current token */
JsonValueType token_type; /* type of current token, once it's known */
- int line_number; /* current line number (counting from 1) */
- char *line_start; /* start of current line within input (BROKEN!!) */
} JsonLexContext;
typedef enum /* states of JSON parser */
--- 43,48 ----
*************** static void json_lex_string(JsonLexConte
*** 78,83 ****
--- 76,82 ----
static void json_lex_number(JsonLexContext *lex, char *s);
static void report_parse_error(JsonParseStack *stack, JsonLexContext *lex);
static void report_invalid_token(JsonLexContext *lex);
+ static int report_json_context(JsonLexContext *lex);
static char *extract_mb_char(char *s);
static void composite_to_json(Datum composite, StringInfo result,
bool use_line_feeds);
*************** json_validate_cstring(char *input)
*** 185,192 ****
/* Set up lexing context. */
lex.input = input;
lex.token_terminator = lex.input;
- lex.line_number = 1;
- lex.line_start = input;
/* Set up parse stack. */
stacksize = 32;
--- 184,189 ----
*************** json_lex(JsonLexContext *lex)
*** 335,345 ****
/* Skip leading whitespace. */
s = lex->token_terminator;
while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
- {
- if (*s == '\n')
- lex->line_number++;
s++;
- }
lex->token_start = s;
/* Determine token type. */
--- 332,338 ----
*************** json_lex(JsonLexContext *lex)
*** 350,356 ****
{
/* End of string. */
lex->token_start = NULL;
! lex->token_terminator = NULL;
}
else
{
--- 343,349 ----
{
/* End of string. */
lex->token_start = NULL;
! lex->token_terminator = s;
}
else
{
*************** json_lex(JsonLexContext *lex)
*** 397,403 ****
/*
* We got some sort of unexpected punctuation or an otherwise
* unexpected character, so just complain about that one
! * character.
*/
lex->token_terminator = s + 1;
report_invalid_token(lex);
--- 390,397 ----
/*
* We got some sort of unexpected punctuation or an otherwise
* unexpected character, so just complain about that one
! * character. (It can't be multibyte because the above loop
! * will advance over any multibyte characters.)
*/
lex->token_terminator = s + 1;
report_invalid_token(lex);
*************** json_lex_string(JsonLexContext *lex)
*** 443,453 ****
lex->token_terminator = s;
report_invalid_token(lex);
}
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("line %d: Character with value \"0x%02x\" must be escaped.",
! lex->line_number, (unsigned char) *s)));
}
else if (*s == '\\')
{
--- 437,449 ----
lex->token_terminator = s;
report_invalid_token(lex);
}
+ lex->token_terminator = s + pg_mblen(s);
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("Character with value 0x%02x must be escaped.",
! (unsigned char) *s),
! report_json_context(lex)));
}
else if (*s == '\\')
{
*************** json_lex_string(JsonLexContext *lex)
*** 465,502 ****
for (i = 1; i <= 4; i++)
{
! if (s[i] == '\0')
{
! lex->token_terminator = s + i;
report_invalid_token(lex);
}
! else if (s[i] >= '0' && s[i] <= '9')
! ch = (ch * 16) + (s[i] - '0');
! else if (s[i] >= 'a' && s[i] <= 'f')
! ch = (ch * 16) + (s[i] - 'a') + 10;
! else if (s[i] >= 'A' && s[i] <= 'F')
! ch = (ch * 16) + (s[i] - 'A') + 10;
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("line %d: \"\\u\" must be followed by four hexadecimal digits.",
! lex->line_number)));
}
}
-
- /* Account for the four additional bytes we just parsed. */
- s += 4;
}
else if (strchr("\"\\/bfnrt", *s) == NULL)
{
/* Not a valid string escape, so error out. */
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("line %d: Invalid escape \"\\%s\".",
! lex->line_number, extract_mb_char(s))));
}
}
}
--- 461,499 ----
for (i = 1; i <= 4; i++)
{
! s++;
! if (*s == '\0')
{
! lex->token_terminator = s;
report_invalid_token(lex);
}
! else if (*s >= '0' && *s <= '9')
! ch = (ch * 16) + (*s - '0');
! else if (*s >= 'a' && *s <= 'f')
! ch = (ch * 16) + (*s - 'a') + 10;
! else if (*s >= 'A' && *s <= 'F')
! ch = (ch * 16) + (*s - 'A') + 10;
else
{
+ lex->token_terminator = s + pg_mblen(s);
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("\"\\u\" must be followed by four hexadecimal digits."),
! report_json_context(lex)));
}
}
}
else if (strchr("\"\\/bfnrt", *s) == NULL)
{
/* Not a valid string escape, so error out. */
+ lex->token_terminator = s + pg_mblen(s);
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("Invalid string escape \"\\%s\".",
! extract_mb_char(s)),
! report_json_context(lex)));
}
}
}
*************** json_lex_number(JsonLexContext *lex, cha
*** 599,666 ****
/*
* Report a parse error.
*/
static void
report_parse_error(JsonParseStack *stack, JsonLexContext *lex)
{
! char *detail = NULL;
! char *token = NULL;
int toklen;
/* Handle case where the input ended prematurely. */
if (lex->token_start == NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json: \"%s\"",
! lex->input),
! errdetail("The input string ended unexpectedly.")));
! /* Separate out the offending token. */
toklen = lex->token_terminator - lex->token_start;
token = palloc(toklen + 1);
memcpy(token, lex->token_start, toklen);
token[toklen] = '\0';
! /* Select correct detail message. */
if (stack == NULL)
! detail = "line %d: Expected end of input, but found \"%s\".";
else
{
switch (stack->state)
{
case JSON_PARSE_VALUE:
! detail = "line %d: Expected string, number, object, array, true, false, or null, but found \"%s\".";
break;
case JSON_PARSE_ARRAY_START:
! detail = "line %d: Expected array element or \"]\", but found \"%s\".";
break;
case JSON_PARSE_ARRAY_NEXT:
! detail = "line %d: Expected \",\" or \"]\", but found \"%s\".";
break;
case JSON_PARSE_OBJECT_START:
! detail = "line %d: Expected string or \"}\", but found \"%s\".";
break;
case JSON_PARSE_OBJECT_LABEL:
! detail = "line %d: Expected \":\", but found \"%s\".";
break;
case JSON_PARSE_OBJECT_NEXT:
! detail = "line %d: Expected \",\" or \"}\", but found \"%s\".";
break;
case JSON_PARSE_OBJECT_COMMA:
! detail = "line %d: Expected string, but found \"%s\".";
break;
}
}
-
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for type json: \"%s\"",
- lex->input),
- detail ? errdetail(detail, lex->line_number, token) : 0));
}
/*
* Report an invalid input token.
*/
static void
report_invalid_token(JsonLexContext *lex)
--- 596,703 ----
/*
* Report a parse error.
+ *
+ * lex->token_start and lex->token_terminator must identify the current token.
*/
static void
report_parse_error(JsonParseStack *stack, JsonLexContext *lex)
{
! char *token;
int toklen;
/* Handle case where the input ended prematurely. */
if (lex->token_start == NULL)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("The input string ended unexpectedly."),
! report_json_context(lex)));
! /* Separate out the current token. */
toklen = lex->token_terminator - lex->token_start;
token = palloc(toklen + 1);
memcpy(token, lex->token_start, toklen);
token[toklen] = '\0';
! /* Complain, with the appropriate detail message. */
if (stack == NULL)
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected end of input, but found \"%s\".",
! token),
! report_json_context(lex)));
else
{
switch (stack->state)
{
case JSON_PARSE_VALUE:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected string, number, object, array, true, false, or null, but found \"%s\".",
! token),
! report_json_context(lex)));
break;
case JSON_PARSE_ARRAY_START:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected array element or \"]\", but found \"%s\".",
! token),
! report_json_context(lex)));
break;
case JSON_PARSE_ARRAY_NEXT:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected \",\" or \"]\", but found \"%s\".",
! token),
! report_json_context(lex)));
break;
case JSON_PARSE_OBJECT_START:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected string or \"}\", but found \"%s\".",
! token),
! report_json_context(lex)));
break;
case JSON_PARSE_OBJECT_LABEL:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected \":\", but found \"%s\".",
! token),
! report_json_context(lex)));
break;
case JSON_PARSE_OBJECT_NEXT:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected \",\" or \"}\", but found \"%s\".",
! token),
! report_json_context(lex)));
break;
case JSON_PARSE_OBJECT_COMMA:
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
! errmsg("invalid input syntax for type json"),
! errdetail("Expected string, but found \"%s\".",
! token),
! report_json_context(lex)));
break;
+ default:
+ elog(ERROR, "unexpected json parse state: %d",
+ (int) stack->state);
}
}
}
/*
* Report an invalid input token.
+ *
+ * lex->token_start and lex->token_terminator must identify the token.
*/
static void
report_invalid_token(JsonLexContext *lex)
*************** report_invalid_token(JsonLexContext *lex
*** 668,673 ****
--- 705,711 ----
char *token;
int toklen;
+ /* Separate out the offending token. */
toklen = lex->token_terminator - lex->token_start;
token = palloc(toklen + 1);
memcpy(token, lex->token_start, toklen);
*************** report_invalid_token(JsonLexContext *lex
*** 676,683 ****
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("line %d: Token \"%s\" is invalid.",
! lex->line_number, token)));
}
/*
--- 714,793 ----
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type json"),
! errdetail("Token \"%s\" is invalid.", token),
! report_json_context(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 (context_end test is just paranoia) */
! if (*context_start == '\n' && context_start < context_end)
! {
! 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 = (*context_end != '\0' && *context_end != '\n' && *context_end != '\r') ? "..." : "";
!
! return errcontext("JSON data, line %d: %s%s%s",
! line_number, prefix, ctxt, suffix);
}
/*
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out
index 4b1ad89..1f79e05 100644
*** a/src/test/regress/expected/json.out
--- b/src/test/regress/expected/json.out
*************** SELECT $$''$$::json; -- ERROR, single
*** 9,15 ****
ERROR: invalid input syntax for type json
LINE 1: SELECT $$''$$::json;
^
! DETAIL: line 1: Token "'" is invalid.
SELECT '"abc"'::json; -- OK
json
-------
--- 9,16 ----
ERROR: invalid input syntax for type json
LINE 1: SELECT $$''$$::json;
^
! DETAIL: Token "'" is invalid.
! CONTEXT: JSON data, line 1: '...
SELECT '"abc"'::json; -- OK
json
-------
*************** SELECT '"abc'::json; -- ERROR, quotes
*** 20,32 ****
ERROR: invalid input syntax for type json
LINE 1: SELECT '"abc'::json;
^
! DETAIL: line 1: Token ""abc" is invalid.
SELECT '"abc
def"'::json; -- ERROR, unescaped newline in string constant
ERROR: invalid input syntax for type json
LINE 1: SELECT '"abc
^
! DETAIL: line 1: Character with value "0x0a" must be escaped.
SELECT '"\n\"\\"'::json; -- OK, legal escapes
json
----------
--- 21,36 ----
ERROR: invalid input syntax for type json
LINE 1: SELECT '"abc'::json;
^
! DETAIL: Token ""abc" is invalid.
! CONTEXT: JSON data, line 1: "abc
SELECT '"abc
def"'::json; -- ERROR, unescaped newline in string constant
ERROR: invalid input syntax for type json
LINE 1: SELECT '"abc
^
! DETAIL: Character with value 0x0a must be escaped.
! CONTEXT: JSON data, line 1: "abc
! ...
SELECT '"\n\"\\"'::json; -- OK, legal escapes
json
----------
*************** SELECT '"\v"'::json; -- ERROR, not a v
*** 37,58 ****
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\v"'::json;
^
! DETAIL: line 1: Invalid escape "\v".
SELECT '"\u"'::json; -- ERROR, incomplete escape
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\u"'::json;
^
! DETAIL: line 1: "\u" must be followed by four hexadecimal digits.
SELECT '"\u00"'::json; -- ERROR, incomplete escape
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\u00"'::json;
^
! DETAIL: line 1: "\u" must be followed by four hexadecimal digits.
SELECT '"\u000g"'::json; -- ERROR, g is not a hex digit
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\u000g"'::json;
^
! DETAIL: line 1: "\u" must be followed by four hexadecimal digits.
SELECT '"\u0000"'::json; -- OK, legal escape
json
----------
--- 41,66 ----
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\v"'::json;
^
! DETAIL: Invalid string escape "\v".
! CONTEXT: JSON data, line 1: "\v...
SELECT '"\u"'::json; -- ERROR, incomplete escape
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\u"'::json;
^
! DETAIL: "\u" must be followed by four hexadecimal digits.
! CONTEXT: JSON data, line 1: "\u"
SELECT '"\u00"'::json; -- ERROR, incomplete escape
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\u00"'::json;
^
! DETAIL: "\u" must be followed by four hexadecimal digits.
! CONTEXT: JSON data, line 1: "\u00"
SELECT '"\u000g"'::json; -- ERROR, g is not a hex digit
ERROR: invalid input syntax for type json
LINE 1: SELECT '"\u000g"'::json;
^
! DETAIL: "\u" must be followed by four hexadecimal digits.
! CONTEXT: JSON data, line 1: "\u000g...
SELECT '"\u0000"'::json; -- OK, legal escape
json
----------
*************** SELECT '01'::json; -- ERROR, not vali
*** 82,88 ****
ERROR: invalid input syntax for type json
LINE 1: SELECT '01'::json;
^
! DETAIL: line 1: Token "01" is invalid.
SELECT '0.1'::json; -- OK
json
------
--- 90,97 ----
ERROR: invalid input syntax for type json
LINE 1: SELECT '01'::json;
^
! DETAIL: Token "01" is invalid.
! CONTEXT: JSON data, line 1: 01
SELECT '0.1'::json; -- OK
json
------
*************** SELECT '1f2'::json; -- ERROR
*** 111,127 ****
ERROR: invalid input syntax for type json
LINE 1: SELECT '1f2'::json;
^
! DETAIL: line 1: Token "1f2" is invalid.
SELECT '0.x1'::json; -- ERROR
ERROR: invalid input syntax for type json
LINE 1: SELECT '0.x1'::json;
^
! DETAIL: line 1: Token "0.x1" is invalid.
SELECT '1.3ex100'::json; -- ERROR
ERROR: invalid input syntax for type json
LINE 1: SELECT '1.3ex100'::json;
^
! DETAIL: line 1: Token "1.3ex100" is invalid.
-- Arrays.
SELECT '[]'::json; -- OK
json
--- 120,139 ----
ERROR: invalid input syntax for type json
LINE 1: SELECT '1f2'::json;
^
! DETAIL: Token "1f2" is invalid.
! CONTEXT: JSON data, line 1: 1f2
SELECT '0.x1'::json; -- ERROR
ERROR: invalid input syntax for type json
LINE 1: SELECT '0.x1'::json;
^
! DETAIL: Token "0.x1" is invalid.
! CONTEXT: JSON data, line 1: 0.x1
SELECT '1.3ex100'::json; -- ERROR
ERROR: invalid input syntax for type json
LINE 1: SELECT '1.3ex100'::json;
^
! DETAIL: Token "1.3ex100" is invalid.
! CONTEXT: JSON data, line 1: 1.3ex100
-- Arrays.
SELECT '[]'::json; -- OK
json
*************** SELECT '[1,2]'::json; -- OK
*** 142,161 ****
(1 row)
SELECT '[1,2,]'::json; -- ERROR, trailing comma
! ERROR: invalid input syntax for type json: "[1,2,]"
LINE 1: SELECT '[1,2,]'::json;
^
! DETAIL: line 1: Expected string, number, object, array, true, false, or null, but found "]".
SELECT '[1,2'::json; -- ERROR, no closing bracket
! ERROR: invalid input syntax for type json: "[1,2"
LINE 1: SELECT '[1,2'::json;
^
DETAIL: The input string ended unexpectedly.
SELECT '[1,[2]'::json; -- ERROR, no closing bracket
! ERROR: invalid input syntax for type json: "[1,[2]"
LINE 1: SELECT '[1,[2]'::json;
^
DETAIL: The input string ended unexpectedly.
-- Objects.
SELECT '{}'::json; -- OK
json
--- 154,176 ----
(1 row)
SELECT '[1,2,]'::json; -- ERROR, trailing comma
! ERROR: invalid input syntax for type json
LINE 1: SELECT '[1,2,]'::json;
^
! DETAIL: Expected string, number, object, array, true, false, or null, but found "]".
! CONTEXT: JSON data, line 1: [1,2,]
SELECT '[1,2'::json; -- ERROR, no closing bracket
! ERROR: invalid input syntax for type json
LINE 1: SELECT '[1,2'::json;
^
DETAIL: The input string ended unexpectedly.
+ CONTEXT: JSON data, line 1: [1,2
SELECT '[1,[2]'::json; -- ERROR, no closing bracket
! ERROR: invalid input syntax for type json
LINE 1: SELECT '[1,[2]'::json;
^
DETAIL: The input string ended unexpectedly.
+ CONTEXT: JSON data, line 1: [1,[2]
-- Objects.
SELECT '{}'::json; -- OK
json
*************** SELECT '{}'::json; -- OK
*** 164,173 ****
(1 row)
SELECT '{"abc"}'::json; -- ERROR, no value
! ERROR: invalid input syntax for type json: "{"abc"}"
LINE 1: SELECT '{"abc"}'::json;
^
! DETAIL: line 1: Expected ":", but found "}".
SELECT '{"abc":1}'::json; -- OK
json
-----------
--- 179,189 ----
(1 row)
SELECT '{"abc"}'::json; -- ERROR, no value
! ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc"}'::json;
^
! DETAIL: Expected ":", but found "}".
! CONTEXT: JSON data, line 1: {"abc"}
SELECT '{"abc":1}'::json; -- OK
json
-----------
*************** SELECT '{"abc":1}'::json; -- OK
*** 175,199 ****
(1 row)
SELECT '{1:"abc"}'::json; -- ERROR, keys must be strings
! ERROR: invalid input syntax for type json: "{1:"abc"}"
LINE 1: SELECT '{1:"abc"}'::json;
^
! DETAIL: line 1: Expected string or "}", but found "1".
SELECT '{"abc",1}'::json; -- ERROR, wrong separator
! ERROR: invalid input syntax for type json: "{"abc",1}"
LINE 1: SELECT '{"abc",1}'::json;
^
! DETAIL: line 1: Expected ":", but found ",".
SELECT '{"abc"=1}'::json; -- ERROR, totally wrong separator
ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc"=1}'::json;
^
! DETAIL: line 1: Token "=" is invalid.
SELECT '{"abc"::1}'::json; -- ERROR, another wrong separator
! ERROR: invalid input syntax for type json: "{"abc"::1}"
LINE 1: SELECT '{"abc"::1}'::json;
^
! DETAIL: line 1: Expected string, number, object, array, true, false, or null, but found ":".
SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json; -- OK
json
---------------------------------------------------------
--- 191,219 ----
(1 row)
SELECT '{1:"abc"}'::json; -- ERROR, keys must be strings
! ERROR: invalid input syntax for type json
LINE 1: SELECT '{1:"abc"}'::json;
^
! DETAIL: Expected string or "}", but found "1".
! CONTEXT: JSON data, line 1: {1...
SELECT '{"abc",1}'::json; -- ERROR, wrong separator
! ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc",1}'::json;
^
! DETAIL: Expected ":", but found ",".
! CONTEXT: JSON data, line 1: {"abc",...
SELECT '{"abc"=1}'::json; -- ERROR, totally wrong separator
ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc"=1}'::json;
^
! DETAIL: Token "=" is invalid.
! CONTEXT: JSON data, line 1: {"abc"=...
SELECT '{"abc"::1}'::json; -- ERROR, another wrong separator
! ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc"::1}'::json;
^
! DETAIL: Expected string, number, object, array, true, false, or null, but found ":".
! CONTEXT: JSON data, line 1: {"abc"::...
SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json; -- OK
json
---------------------------------------------------------
*************** SELECT '{"abc":1,"def":2,"ghi":[3,4],"hi
*** 201,215 ****
(1 row)
SELECT '{"abc":1:2}'::json; -- ERROR, colon in wrong spot
! ERROR: invalid input syntax for type json: "{"abc":1:2}"
LINE 1: SELECT '{"abc":1:2}'::json;
^
! DETAIL: line 1: Expected "," or "}", but found ":".
SELECT '{"abc":1,3}'::json; -- ERROR, no value
! ERROR: invalid input syntax for type json: "{"abc":1,3}"
LINE 1: SELECT '{"abc":1,3}'::json;
^
! DETAIL: line 1: Expected string, but found "3".
-- Miscellaneous stuff.
SELECT 'true'::json; -- OK
json
--- 221,237 ----
(1 row)
SELECT '{"abc":1:2}'::json; -- ERROR, colon in wrong spot
! ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc":1:2}'::json;
^
! DETAIL: Expected "," or "}", but found ":".
! CONTEXT: JSON data, line 1: {"abc":1:...
SELECT '{"abc":1,3}'::json; -- ERROR, no value
! ERROR: invalid input syntax for type json
LINE 1: SELECT '{"abc":1,3}'::json;
^
! DETAIL: Expected string, but found "3".
! CONTEXT: JSON data, line 1: {"abc":1,3...
-- Miscellaneous stuff.
SELECT 'true'::json; -- OK
json
*************** SELECT ' true '::json; -- OK, even wit
*** 236,270 ****
(1 row)
SELECT 'true false'::json; -- ERROR, too many values
! ERROR: invalid input syntax for type json: "true false"
LINE 1: SELECT 'true false'::json;
^
! DETAIL: line 1: Expected end of input, but found "false".
SELECT 'true, false'::json; -- ERROR, too many values
! ERROR: invalid input syntax for type json: "true, false"
LINE 1: SELECT 'true, false'::json;
^
! DETAIL: line 1: Expected end of input, but found ",".
SELECT 'truf'::json; -- ERROR, not a keyword
ERROR: invalid input syntax for type json
LINE 1: SELECT 'truf'::json;
^
! DETAIL: line 1: Token "truf" is invalid.
SELECT 'trues'::json; -- ERROR, not a keyword
ERROR: invalid input syntax for type json
LINE 1: SELECT 'trues'::json;
^
! DETAIL: line 1: Token "trues" is invalid.
SELECT ''::json; -- ERROR, no value
! ERROR: invalid input syntax for type json: ""
LINE 1: SELECT ''::json;
^
DETAIL: The input string ended unexpectedly.
SELECT ' '::json; -- ERROR, no value
! ERROR: invalid input syntax for type json: " "
LINE 1: SELECT ' '::json;
^
DETAIL: The input string ended unexpectedly.
--constructors
-- array_to_json
SELECT array_to_json(array(select 1 as a));
--- 258,298 ----
(1 row)
SELECT 'true false'::json; -- ERROR, too many values
! ERROR: invalid input syntax for type json
LINE 1: SELECT 'true false'::json;
^
! DETAIL: Expected end of input, but found "false".
! CONTEXT: JSON data, line 1: true false
SELECT 'true, false'::json; -- ERROR, too many values
! ERROR: invalid input syntax for type json
LINE 1: SELECT 'true, false'::json;
^
! DETAIL: Expected end of input, but found ",".
! CONTEXT: JSON data, line 1: true,...
SELECT 'truf'::json; -- ERROR, not a keyword
ERROR: invalid input syntax for type json
LINE 1: SELECT 'truf'::json;
^
! DETAIL: Token "truf" is invalid.
! CONTEXT: JSON data, line 1: truf
SELECT 'trues'::json; -- ERROR, not a keyword
ERROR: invalid input syntax for type json
LINE 1: SELECT 'trues'::json;
^
! DETAIL: Token "trues" is invalid.
! CONTEXT: JSON data, line 1: trues
SELECT ''::json; -- ERROR, no value
! ERROR: invalid input syntax for type json
LINE 1: SELECT ''::json;
^
DETAIL: The input string ended unexpectedly.
+ CONTEXT: JSON data, line 1:
SELECT ' '::json; -- ERROR, no value
! ERROR: invalid input syntax for type json
LINE 1: SELECT ' '::json;
^
DETAIL: The input string ended unexpectedly.
+ CONTEXT: JSON data, line 1:
--constructors
-- array_to_json
SELECT array_to_json(array(select 1 as a));