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;
+ line_start = lex->line_start;
+ context_start = line_start;
context_end = lex->token_terminator;
- line_start = context_start;
- line_number = 1;
- for (;;)
+
+ /* Advance until we are close enough to context_end */
+ while (context_end - context_start >= 50 && context_start < context_end)
{
- /* 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);
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);
+ lex->line_number, prefix, ctxt, suffix);
}
while (len < lex->input_length &&
(*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
{
- if (*s == '\n')
+ if (*s++ == '\n')
+ {
++lex->line_number;
- ++s;
- ++len;
+ lex->line_start = s;
+ }
+ len++;
}
lex->token_start = s;
char *prev_token_terminator;
JsonTokenType token_type;
int lex_level;
- int line_number;
- char *line_start;
+ int line_number; /* line number, starting from 1 */
+ char *line_start; /* where that line starts within input */
StringInfo strval;
} JsonLexContext;
^
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1:
+-- Multi-line JSON input to check ERROR reporting
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "three":
+ true}'::json; -- OK
+ json
+------------------------------
+ { +
+ "one": 1, +
+ "two":"two",+
+ "three": +
+ true}
+(1 row)
+
+SELECT '{
+ "one": 1,
+ "two":,"two", -- ERROR extraneous comma before field "two"
+ "three":
+ true}'::json;
+ERROR: invalid input syntax for type json
+LINE 1: SELECT '{
+ ^
+DETAIL: Expected JSON value, but found ",".
+CONTEXT: JSON data, line 3: "two":,...
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::json;
+ERROR: invalid input syntax for type json
+LINE 1: SELECT '{
+ ^
+DETAIL: Expected JSON value, but found "}".
+CONTEXT: JSON data, line 4: ...yveryveryveryveryveryveryveryverylongfieldname":}
+-- ERROR missing value for last field
--constructors
-- array_to_json
SELECT array_to_json(array(select 1 as a));
^
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1:
+-- Multi-line JSON input to check ERROR reporting
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "three":
+ true}'::jsonb; -- OK
+ jsonb
+-----------------------------------------
+ {"one": 1, "two": "two", "three": true}
+(1 row)
+
+SELECT '{
+ "one": 1,
+ "two":,"two", -- ERROR extraneous comma before field "two"
+ "three":
+ true}'::jsonb;
+ERROR: invalid input syntax for type json
+LINE 1: SELECT '{
+ ^
+DETAIL: Expected JSON value, but found ",".
+CONTEXT: JSON data, line 3: "two":,...
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::jsonb;
+ERROR: invalid input syntax for type json
+LINE 1: SELECT '{
+ ^
+DETAIL: Expected JSON value, but found "}".
+CONTEXT: JSON data, line 4: ...yveryveryveryveryveryveryveryverylongfieldname":}
+-- ERROR missing value for last field
-- make sure jsonb is passed through json generators without being escaped
SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']);
array_to_json
SELECT ''::json; -- ERROR, no value
SELECT ' '::json; -- ERROR, no value
+-- Multi-line JSON input to check ERROR reporting
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "three":
+ true}'::json; -- OK
+SELECT '{
+ "one": 1,
+ "two":,"two", -- ERROR extraneous comma before field "two"
+ "three":
+ true}'::json;
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::json;
+-- ERROR missing value for last field
+
--constructors
-- array_to_json
SELECT ''::jsonb; -- ERROR, no value
SELECT ' '::jsonb; -- ERROR, no value
+-- Multi-line JSON input to check ERROR reporting
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "three":
+ true}'::jsonb; -- OK
+SELECT '{
+ "one": 1,
+ "two":,"two", -- ERROR extraneous comma before field "two"
+ "three":
+ true}'::jsonb;
+SELECT '{
+ "one": 1,
+ "two":"two",
+ "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::jsonb;
+-- ERROR missing value for last field
+
-- make sure jsonb is passed through json generators without being escaped
SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']);