@ -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,25 +127,13 @@ 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 )
{
@ -202,23 +189,6 @@ pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
return result ;
}
/*
* 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
*
@ -1038,27 +1008,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 .
*/
@ -1118,78 +1067,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 .
*/