Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit73ce2a0

Browse files
committed
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 allowingjsonapi.c to be used from frontend code.A few cases where elog(ERROR, ...) is used for can't-happenconditions are left alone; we can handle those in some otherway in frontend code.Reviewed by Mark Dilger and Andrew Dunstan.Discussion:http://postgr.es/m/CA+TgmoYfOXhd27MUDGioVh6QtpD0C1K-f6ObSA10AWiHBAL5bA@mail.gmail.com
1 parent1f3a021 commit73ce2a0

File tree

6 files changed

+140
-141
lines changed

6 files changed

+140
-141
lines changed

‎src/backend/utils/adt/json.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include"utils/date.h"
2424
#include"utils/datetime.h"
2525
#include"utils/json.h"
26-
#include"utils/jsonapi.h"
26+
#include"utils/jsonfuncs.h"
2727
#include"utils/lsyscache.h"
2828
#include"utils/typcache.h"
2929

‎src/backend/utils/adt/jsonapi.c

Lines changed: 2 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ static JsonParseErrorType parse_object(JsonLexContext *lex, JsonSemAction *sem);
4444
staticJsonParseErrorTypeparse_array_element(JsonLexContext*lex,JsonSemAction*sem);
4545
staticJsonParseErrorTypeparse_array(JsonLexContext*lex,JsonSemAction*sem);
4646
staticJsonParseErrorTypereport_parse_error(JsonParseContextctx,JsonLexContext*lex);
47-
staticintreport_json_context(JsonLexContext*lex);
4847
staticchar*extract_token(JsonLexContext*lex);
4948

5049
/* the null action object used for pure validation */
@@ -128,25 +127,13 @@ IsValidJsonNumber(const char *str, int len)
128127
}
129128

130129
/*
131-
*makeJsonLexContext
130+
*makeJsonLexContextCstringLen
132131
*
133-
* lex constructor, with or without StringInfo object
134-
* for de-escaped lexemes.
132+
* lex constructor, with or without StringInfo object for de-escaped lexemes.
135133
*
136134
* Without is better as it makes the processing faster, so only make one
137135
* if really required.
138-
*
139-
* If you already have the json as a text* value, use the first of these
140-
* functions, otherwise use makeJsonLexContextCstringLen().
141136
*/
142-
JsonLexContext*
143-
makeJsonLexContext(text*json,boolneed_escapes)
144-
{
145-
returnmakeJsonLexContextCstringLen(VARDATA_ANY(json),
146-
VARSIZE_ANY_EXHDR(json),
147-
need_escapes);
148-
}
149-
150137
JsonLexContext*
151138
makeJsonLexContextCstringLen(char*json,intlen,boolneed_escapes)
152139
{
@@ -202,23 +189,6 @@ pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
202189
returnresult;
203190
}
204191

205-
/*
206-
* pg_parse_json_or_ereport
207-
*
208-
* This fuction is like pg_parse_json, except that it does not return a
209-
* JsonParseErrorType. Instead, in case of any failure, this function will
210-
* ereport(ERROR).
211-
*/
212-
void
213-
pg_parse_json_or_ereport(JsonLexContext*lex,JsonSemAction*sem)
214-
{
215-
JsonParseErrorTyperesult;
216-
217-
result=pg_parse_json(lex,sem);
218-
if (result!=JSON_SUCCESS)
219-
json_ereport_error(result,lex);
220-
}
221-
222192
/*
223193
* json_count_array_elements
224194
*
@@ -1038,27 +1008,6 @@ report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
10381008
}
10391009
}
10401010

1041-
/*
1042-
* Report a JSON error.
1043-
*/
1044-
void
1045-
json_ereport_error(JsonParseErrorTypeerror,JsonLexContext*lex)
1046-
{
1047-
if (error==JSON_UNICODE_HIGH_ESCAPE||
1048-
error==JSON_UNICODE_CODE_POINT_ZERO)
1049-
ereport(ERROR,
1050-
(errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
1051-
errmsg("unsupported Unicode escape sequence"),
1052-
errdetail("%s",json_errdetail(error,lex)),
1053-
report_json_context(lex)));
1054-
else
1055-
ereport(ERROR,
1056-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1057-
errmsg("invalid input syntax for type %s","json"),
1058-
errdetail("%s",json_errdetail(error,lex)),
1059-
report_json_context(lex)));
1060-
}
1061-
10621011
/*
10631012
* Construct a detail message for a JSON error.
10641013
*/
@@ -1118,78 +1067,6 @@ json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
11181067
}
11191068
}
11201069

1121-
/*
1122-
* Report a CONTEXT line for bogus JSON input.
1123-
*
1124-
* lex->token_terminator must be set to identify the spot where we detected
1125-
* the error. Note that lex->token_start might be NULL, in case we recognized
1126-
* error at EOF.
1127-
*
1128-
* The return value isn't meaningful, but we make it non-void so that this
1129-
* can be invoked inside ereport().
1130-
*/
1131-
staticint
1132-
report_json_context(JsonLexContext*lex)
1133-
{
1134-
constchar*context_start;
1135-
constchar*context_end;
1136-
constchar*line_start;
1137-
intline_number;
1138-
char*ctxt;
1139-
intctxtlen;
1140-
constchar*prefix;
1141-
constchar*suffix;
1142-
1143-
/* Choose boundaries for the part of the input we will display */
1144-
context_start=lex->input;
1145-
context_end=lex->token_terminator;
1146-
line_start=context_start;
1147-
line_number=1;
1148-
for (;;)
1149-
{
1150-
/* Always advance over newlines */
1151-
if (context_start<context_end&&*context_start=='\n')
1152-
{
1153-
context_start++;
1154-
line_start=context_start;
1155-
line_number++;
1156-
continue;
1157-
}
1158-
/* Otherwise, done as soon as we are close enough to context_end */
1159-
if (context_end-context_start<50)
1160-
break;
1161-
/* Advance to next multibyte character */
1162-
if (IS_HIGHBIT_SET(*context_start))
1163-
context_start+=pg_mblen(context_start);
1164-
else
1165-
context_start++;
1166-
}
1167-
1168-
/*
1169-
* We add "..." to indicate that the excerpt doesn't start at the
1170-
* beginning of the line ... but if we're within 3 characters of the
1171-
* beginning of the line, we might as well just show the whole line.
1172-
*/
1173-
if (context_start-line_start <=3)
1174-
context_start=line_start;
1175-
1176-
/* Get a null-terminated copy of the data to present */
1177-
ctxtlen=context_end-context_start;
1178-
ctxt=palloc(ctxtlen+1);
1179-
memcpy(ctxt,context_start,ctxtlen);
1180-
ctxt[ctxtlen]='\0';
1181-
1182-
/*
1183-
* Show the context, prefixing "..." if not starting at start of line, and
1184-
* suffixing "..." if not ending at end of line.
1185-
*/
1186-
prefix= (context_start>line_start) ?"..." :"";
1187-
suffix= (lex->token_type!=JSON_TOKEN_END&&context_end-lex->input<lex->input_length&&*context_end!='\n'&&*context_end!='\r') ?"..." :"";
1188-
1189-
returnerrcontext("JSON data, line %d: %s%s%s",
1190-
line_number,prefix,ctxt,suffix);
1191-
}
1192-
11931070
/*
11941071
* Extract the current token from a lexing context, for error reporting.
11951072
*/

‎src/backend/utils/adt/jsonb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
#include"utils/date.h"
2424
#include"utils/datetime.h"
2525
#include"utils/json.h"
26-
#include"utils/jsonapi.h"
2726
#include"utils/jsonb.h"
27+
#include"utils/jsonfuncs.h"
2828
#include"utils/lsyscache.h"
2929
#include"utils/syscache.h"
3030
#include"utils/typcache.h"

‎src/backend/utils/adt/jsonfuncs.c

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ typedef struct JsObject
329329
hash_destroy((jso)->val.json_hash); \
330330
} while (0)
331331

332+
staticintreport_json_context(JsonLexContext*lex);
333+
332334
/* semantic action functions for json_object_keys */
333335
staticvoidokeys_object_field_start(void*state,char*fname,boolisnull);
334336
staticvoidokeys_array_start(void*state);
@@ -484,6 +486,37 @@ static void transform_string_values_object_field_start(void *state, char *fname,
484486
staticvoidtransform_string_values_array_element_start(void*state,boolisnull);
485487
staticvoidtransform_string_values_scalar(void*state,char*token,JsonTokenTypetokentype);
486488

489+
/*
490+
* pg_parse_json_or_ereport
491+
*
492+
* This fuction is like pg_parse_json, except that it does not return a
493+
* JsonParseErrorType. Instead, in case of any failure, this function will
494+
* ereport(ERROR).
495+
*/
496+
void
497+
pg_parse_json_or_ereport(JsonLexContext*lex,JsonSemAction*sem)
498+
{
499+
JsonParseErrorTyperesult;
500+
501+
result=pg_parse_json(lex,sem);
502+
if (result!=JSON_SUCCESS)
503+
json_ereport_error(result,lex);
504+
}
505+
506+
/*
507+
* makeJsonLexContext
508+
*
509+
* This is like makeJsonLexContextCstringLen, but it accepts a text value
510+
* directly.
511+
*/
512+
JsonLexContext*
513+
makeJsonLexContext(text*json,boolneed_escapes)
514+
{
515+
returnmakeJsonLexContextCstringLen(VARDATA_ANY(json),
516+
VARSIZE_ANY_EXHDR(json),
517+
need_escapes);
518+
}
519+
487520
/*
488521
* SQL function json_object_keys
489522
*
@@ -573,6 +606,99 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
573606
SRF_RETURN_DONE(funcctx);
574607
}
575608

609+
/*
610+
* Report a JSON error.
611+
*/
612+
void
613+
json_ereport_error(JsonParseErrorTypeerror,JsonLexContext*lex)
614+
{
615+
if (error==JSON_UNICODE_HIGH_ESCAPE||
616+
error==JSON_UNICODE_CODE_POINT_ZERO)
617+
ereport(ERROR,
618+
(errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
619+
errmsg("unsupported Unicode escape sequence"),
620+
errdetail("%s",json_errdetail(error,lex)),
621+
report_json_context(lex)));
622+
else
623+
ereport(ERROR,
624+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
625+
errmsg("invalid input syntax for type %s","json"),
626+
errdetail("%s",json_errdetail(error,lex)),
627+
report_json_context(lex)));
628+
}
629+
630+
/*
631+
* Report a CONTEXT line for bogus JSON input.
632+
*
633+
* lex->token_terminator must be set to identify the spot where we detected
634+
* the error. Note that lex->token_start might be NULL, in case we recognized
635+
* error at EOF.
636+
*
637+
* The return value isn't meaningful, but we make it non-void so that this
638+
* can be invoked inside ereport().
639+
*/
640+
staticint
641+
report_json_context(JsonLexContext*lex)
642+
{
643+
constchar*context_start;
644+
constchar*context_end;
645+
constchar*line_start;
646+
intline_number;
647+
char*ctxt;
648+
intctxtlen;
649+
constchar*prefix;
650+
constchar*suffix;
651+
652+
/* Choose boundaries for the part of the input we will display */
653+
context_start=lex->input;
654+
context_end=lex->token_terminator;
655+
line_start=context_start;
656+
line_number=1;
657+
for (;;)
658+
{
659+
/* Always advance over newlines */
660+
if (context_start<context_end&&*context_start=='\n')
661+
{
662+
context_start++;
663+
line_start=context_start;
664+
line_number++;
665+
continue;
666+
}
667+
/* Otherwise, done as soon as we are close enough to context_end */
668+
if (context_end-context_start<50)
669+
break;
670+
/* Advance to next multibyte character */
671+
if (IS_HIGHBIT_SET(*context_start))
672+
context_start+=pg_mblen(context_start);
673+
else
674+
context_start++;
675+
}
676+
677+
/*
678+
* We add "..." to indicate that the excerpt doesn't start at the
679+
* beginning of the line ... but if we're within 3 characters of the
680+
* beginning of the line, we might as well just show the whole line.
681+
*/
682+
if (context_start-line_start <=3)
683+
context_start=line_start;
684+
685+
/* Get a null-terminated copy of the data to present */
686+
ctxtlen=context_end-context_start;
687+
ctxt=palloc(ctxtlen+1);
688+
memcpy(ctxt,context_start,ctxtlen);
689+
ctxt[ctxtlen]='\0';
690+
691+
/*
692+
* Show the context, prefixing "..." if not starting at start of line, and
693+
* suffixing "..." if not ending at end of line.
694+
*/
695+
prefix= (context_start>line_start) ?"..." :"";
696+
suffix= (lex->token_type!=JSON_TOKEN_END&&context_end-lex->input<lex->input_length&&*context_end!='\n'&&*context_end!='\r') ?"..." :"";
697+
698+
returnerrcontext("JSON data, line %d: %s%s%s",
699+
line_number,prefix,ctxt,suffix);
700+
}
701+
576702

577703
Datum
578704
json_object_keys(PG_FUNCTION_ARGS)

‎src/include/utils/jsonapi.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,6 @@ typedef struct JsonSemAction
126126
externJsonParseErrorTypepg_parse_json(JsonLexContext*lex,
127127
JsonSemAction*sem);
128128

129-
/*
130-
* Same thing, but signal errors via ereport(ERROR) instead of returning
131-
* a result code.
132-
*/
133-
externvoidpg_parse_json_or_ereport(JsonLexContext*lex,JsonSemAction*sem);
134-
135129
/* the null action object used for pure validation */
136130
externJsonSemActionnullSemAction;
137131

@@ -148,25 +142,18 @@ extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
148142
int*elements);
149143

150144
/*
151-
*constructors for JsonLexContext, with or without strval element.
145+
*constructor for JsonLexContext, with or without strval element.
152146
* If supplied, the strval element will contain a de-escaped version of
153147
* the lexeme. However, doing this imposes a performance penalty, so
154148
* it should be avoided if the de-escaped lexeme is not required.
155-
*
156-
* If you already have the json as a text* value, use the first of these
157-
* functions, otherwise use makeJsonLexContextCstringLen().
158149
*/
159-
externJsonLexContext*makeJsonLexContext(text*json,boolneed_escapes);
160150
externJsonLexContext*makeJsonLexContextCstringLen(char*json,
161151
intlen,
162152
boolneed_escapes);
163153

164154
/* lex one token */
165155
externJsonParseErrorTypejson_lex(JsonLexContext*lex);
166156

167-
/* report an error during json lexing or parsing */
168-
externvoidjson_ereport_error(JsonParseErrorTypeerror,JsonLexContext*lex);
169-
170157
/* construct an error detail string for a json error */
171158
externchar*json_errdetail(JsonParseErrorTypeerror,JsonLexContext*lex);
172159

‎src/include/utils/jsonfuncs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, in
3636
/* an action that will be applied to each value in transform_json(b)_values functions */
3737
typedeftext*(*JsonTransformStringValuesAction) (void*state,char*elem_value,intelem_len);
3838

39+
/* build a JsonLexContext from a text datum */
40+
externJsonLexContext*makeJsonLexContext(text*json,boolneed_escapes);
41+
42+
/* try to parse json, and ereport(ERROR) on failure */
43+
externvoidpg_parse_json_or_ereport(JsonLexContext*lex,JsonSemAction*sem);
44+
45+
/* report an error during json lexing or parsing */
46+
externvoidjson_ereport_error(JsonParseErrorTypeerror,JsonLexContext*lex);
47+
3948
externuint32parse_jsonb_index_flags(Jsonb*jb);
4049
externvoiditerate_jsonb_values(Jsonb*jb,uint32flags,void*state,
4150
JsonIterateStringValuesActionaction);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp