36 #define DT_INFINITY "\"infinity\""
86 Datum *vals,
bool *nulls,
int *valcount,
98 Oid val_type,
bool key_scalar);
145 char *tokstr =
palloc(len + 1);
172 #define JSON_ALPHANUMERIC_CHAR(c) \
173 (((c) >= 'a' && (c) <= 'z') || \
174 ((c) >= 'A' && (c) <= 'Z') || \
175 ((c) >= '0' && (c) <= '9') || \
195 dummy_lex.
input = (
char *) str + 1;
200 dummy_lex.
input = (
char *) str;
206 return !numeric_error;
440 char **fnameaddr =
NULL;
455 (*ostart) (sem->
semstate, fname, isnull);
470 (*oend) (sem->
semstate, fname, isnull);
602 len = s - lex->
input;
603 while (len < lex->input_length &&
604 (*s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r'))
716 if (memcmp(s,
"true", 4) == 0)
718 else if (memcmp(s,
"null", 4) == 0)
723 else if (p - s == 5 && memcmp(s,
"false", 5) == 0)
740 int hi_surrogate = -1;
760 else if ((
unsigned char) *s < 32)
766 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
767 errmsg(
"invalid input syntax for type json"),
768 errdetail(
"Character with value 0x%02x must be escaped.",
787 for (i = 1; i <= 4; i++)
796 else if (*s >=
'0' && *s <=
'9')
797 ch = (ch * 16) + (*s -
'0');
798 else if (*s >=
'a' && *s <=
'f')
799 ch = (ch * 16) + (*s -
'a') + 10;
800 else if (*s >=
'A' && *s <=
'F')
801 ch = (ch * 16) + (*s -
'A') + 10;
806 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
807 errmsg(
"invalid input syntax for type json"),
808 errdetail(
"\"\\u\" must be followed by four hexadecimal digits."),
817 if (ch >= 0xd800 && ch <= 0xdbff)
819 if (hi_surrogate != -1)
821 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
822 errmsg(
"invalid input syntax for type json"),
823 errdetail(
"Unicode high surrogate must not follow a high surrogate."),
825 hi_surrogate = (ch & 0x3ff) << 10;
828 else if (ch >= 0xdc00 && ch <= 0xdfff)
830 if (hi_surrogate == -1)
832 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
833 errmsg(
"invalid input syntax for type json"),
834 errdetail(
"Unicode low surrogate must follow a high surrogate."),
836 ch = 0x10000 + hi_surrogate + (ch & 0x3ff);
840 if (hi_surrogate != -1)
842 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
843 errmsg(
"invalid input syntax for type json"),
844 errdetail(
"Unicode low surrogate must follow a high surrogate."),
858 (
errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
859 errmsg(
"unsupported Unicode escape sequence"),
860 errdetail(
"\\u0000 cannot be converted to text."),
869 else if (ch <= 0x007f)
881 (
errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
882 errmsg(
"unsupported Unicode escape sequence"),
883 errdetail(
"Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8."),
891 if (hi_surrogate != -1)
893 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
894 errmsg(
"invalid input syntax for type json"),
895 errdetail(
"Unicode low surrogate must follow a high surrogate."),
924 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
925 errmsg(
"invalid input syntax for type json"),
926 errdetail(
"Escape sequence \"\\%s\" is invalid.",
931 else if (strchr(
"\"\\/bfnrt", *s) ==
NULL)
942 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
943 errmsg(
"invalid input syntax for type json"),
944 errdetail(
"Escape sequence \"\\%s\" is invalid.",
952 if (hi_surrogate != -1)
954 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
955 errmsg(
"invalid input syntax for type json"),
956 errdetail(
"Unicode low surrogate must follow a high surrogate."),
964 if (hi_surrogate != -1)
966 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
967 errmsg(
"invalid input syntax for type json"),
968 errdetail(
"Unicode low surrogate must follow a high surrogate."),
1009 len = s - lex->
input;
1019 else if (*s >=
'1' && *s <=
'9')
1025 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
1031 if (len < lex->input_length && *s ==
'.')
1043 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
1048 if (len < lex->input_length && (*s ==
'e' || *s ==
'E'))
1052 if (len < lex->input_length && (*s ==
'+' || *s ==
'-'))
1065 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
1077 if (num_err !=
NULL)
1105 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1106 errmsg(
"invalid input syntax for type json"),
1107 errdetail(
"The input string ended unexpectedly."),
1112 token =
palloc(toklen + 1);
1114 token[toklen] =
'\0';
1119 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1120 errmsg(
"invalid input syntax for type json"),
1121 errdetail(
"Expected end of input, but found \"%s\".",
1130 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1131 errmsg(
"invalid input syntax for type json"),
1132 errdetail(
"Expected JSON value, but found \"%s\".",
1138 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1139 errmsg(
"invalid input syntax for type json"),
1140 errdetail(
"Expected string, but found \"%s\".",
1146 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1147 errmsg(
"invalid input syntax for type json"),
1148 errdetail(
"Expected array element or \"]\", but found \"%s\".",
1154 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1155 errmsg(
"invalid input syntax for type json"),
1156 errdetail(
"Expected \",\" or \"]\", but found \"%s\".",
1162 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1163 errmsg(
"invalid input syntax for type json"),
1164 errdetail(
"Expected string or \"}\", but found \"%s\".",
1170 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1171 errmsg(
"invalid input syntax for type json"),
1172 errdetail(
"Expected \":\", but found \"%s\".",
1178 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1179 errmsg(
"invalid input syntax for type json"),
1180 errdetail(
"Expected \",\" or \"}\", but found \"%s\".",
1186 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1187 errmsg(
"invalid input syntax for type json"),
1188 errdetail(
"Expected string, but found \"%s\".",
1193 elog(
ERROR,
"unexpected json parse state: %d", ctx);
1211 token =
palloc(toklen + 1);
1213 token[toklen] =
'\0';
1216 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1217 errmsg(
"invalid input syntax for type json"),
1218 errdetail(
"Token \"%s\" is invalid.", token),
1235 const char *context_start;
1236 const char *context_end;
1237 const char *line_start;
1245 context_start = lex->
input;
1247 line_start = context_start;
1252 if (context_start < context_end && *context_start ==
'\n')
1255 line_start = context_start;
1260 if (context_end - context_start < 50)
1264 context_start +=
pg_mblen(context_start);
1274 if (context_start - line_start <= 3)
1275 context_start = line_start;
1278 ctxtlen = context_end - context_start;
1279 ctxt =
palloc(ctxtlen + 1);
1280 memcpy(ctxt, context_start, ctxtlen);
1281 ctxt[ctxtlen] =
'\0';
1287 prefix = (context_start > line_start) ?
"..." :
"";
1290 return errcontext(
"JSON data, line %d: %s%s%s",
1291 line_number, prefix, ctxt, suffix);
1305 memcpy(res, s, len);
1392 *outfuncoid = castfunc;
1428 Assert(!(key_scalar && is_null));
1442 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1443 errmsg(
"key value must be scalar, not array, composite, or json")));
1516 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1517 errmsg(
"timestamp out of range")));
1526 const char *tzn =
NULL;
1543 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1544 errmsg(
"timestamp out of range")));
1577 Oid outfuncoid,
bool use_line_feeds)
1584 sep = use_line_feeds ?
",\n " :
",";
1588 for (i = 1; i <= dims[dim]; i++)
1593 if (dim + 1 == ndims)
1595 datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
1606 valcount, tcategory, outfuncoid,
false);
1644 &typlen, &typbyval, &typalign);
1647 &tcategory, &outfuncoid);
1650 typalign, &elements, &nulls,
1654 outfuncoid, use_line_feeds);
1673 bool needsep =
false;
1676 sep = use_line_feeds ?
",\n " :
",";
1692 for (i = 0; i < tupdesc->
natts; i++)
1700 if (tupdesc->
attrs[i]->attisdropped)
1720 &tcategory, &outfuncoid);
1722 datum_to_json(val, isnull, result, tcategory, outfuncoid,
false);
1738 Oid val_type,
bool key_scalar)
1745 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1746 errmsg(
"could not determine input data type")));
1755 &tcategory, &outfuncoid);
1757 datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
1840 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1841 errmsg(
"could not determine input data type")));
1844 &tcategory, &outfuncoid);
1848 datum_to_json(val,
false, result, tcategory, outfuncoid,
false);
1871 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1872 errmsg(
"could not determine input data type")));
1877 elog(
ERROR,
"json_agg_transfn called in non-aggregate context");
1911 &tcategory, &outfuncoid);
1920 datum_to_json(val,
false, state, tcategory, outfuncoid,
false);
1968 elog(
ERROR,
"json_object_agg_transfn called in non-aggregate context");
2002 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2003 errmsg(
"could not determine data type for argument %d", 1)));
2007 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2008 errmsg(
"field name must not be null")));
2012 add_json(arg,
false, state, val_type,
true);
2020 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2021 errmsg(
"could not determine data type for argument %d", 2)));
2063 int buflen = buffer->
len;
2064 int addlen = strlen(addon);
2069 memcpy(
VARDATA(result) + buflen, addon, addlen);
2083 const char *sep =
"";
2089 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2090 errmsg(
"argument list must have even number of elements"),
2091 errhint(
"The arguments of json_build_object() must consist of alternating keys and values.")));
2097 for (i = 0; i < nargs; i += 2)
2114 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2115 errmsg(
"could not determine data type for argument %d",
2120 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2121 errmsg(
"argument %d cannot be null", i + 1),
2122 errhint(
"Object keys should be text.")));
2126 add_json(arg,
false, result, val_type,
true);
2135 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2136 errmsg(
"could not determine data type for argument %d",
2170 const char *sep =
"";
2178 for (i = 0; i < nargs; i++)
2194 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2195 errmsg(
"could not determine data type for argument %d",
2249 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2250 errmsg(
"array must have even number of elements")));
2256 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2257 errmsg(
"array must have two columns")));
2262 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2263 errmsg(
"wrong number of array subscripts")));
2268 &in_datums, &in_nulls, &in_count);
2270 count = in_count / 2;
2276 for (i = 0; i < count; ++
i)
2278 if (in_nulls[i * 2])
2280 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2281 errmsg(
"null value not allowed for object key")));
2289 if (in_nulls[i * 2 + 1])
2335 if (nkdims > 1 || nkdims != nvdims)
2337 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2338 errmsg(
"wrong number of array subscripts")));
2345 &key_datums, &key_nulls, &key_count);
2349 &val_datums, &val_nulls, &val_count);
2351 if (key_count != val_count)
2353 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2354 errmsg(
"mismatched array dimensions")));
2360 for (i = 0; i < key_count; ++
i)
2364 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2365 errmsg(
"null value not allowed for object key")));
2406 for (p = str; *p; p++)
2432 if ((
unsigned char) *p <
' ')
2491 elog(
ERROR,
"unexpected json token: %d", tok);
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
json_struct_action array_end
#define PG_RETURN_POINTER(x)
Datum to_json(PG_FUNCTION_ARGS)
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
#define DatumGetDateADT(X)
int errhint(const char *fmt,...)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
void escape_json(StringInfo buf, const char *str)
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
json_struct_action object_end
Datum json_object_two_arg(PG_FUNCTION_ARGS)
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Oid get_element_type(Oid typid)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
#define PG_GETARG_DATUM(n)
char * pstrdup(const char *in)
static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Datum json_in(PG_FUNCTION_ARGS)
StringInfo makeStringInfo(void)
StringInfoData * StringInfo
int ArrayGetNItems(int ndim, const int *dims)
Form_pg_attribute * attrs
json_struct_action object_start
char * prev_token_terminator
static void lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
#define JSON_ALPHANUMERIC_CHAR(c)
static char * extract_mb_char(char *s)
Datum json_agg_finalfn(PG_FUNCTION_ARGS)
Datum array_to_json_pretty(PG_FUNCTION_ARGS)
int errcode(int sqlerrcode)
void(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)
json_scalar_action scalar
#define PG_GETARG_POINTER(n)
#define PG_GETARG_BOOL(n)
#define PG_RETURN_BYTEA_P(x)
static bool lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
#define OidIsValid(objectId)
#define DatumGetHeapTupleHeader(X)
#define FirstNormalObjectId
#define PG_GETARG_TEXT_PP(n)
#define HeapTupleHeaderGetTypMod(tup)
static text * catenate_stringinfo_string(StringInfo buffer, const char *addon)
#define PG_GETARG_ARRAYTYPE_P(n)
#define appendStringInfoCharMacro(str, ch)
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
#define TIMESTAMP_NOT_FINITE(j)
void pfree(void *pointer)
Datum json_build_object_noargs(PG_FUNCTION_ARGS)
#define IS_HIGHBIT_SET(ch)
void appendStringInfo(StringInfo str, const char *fmt,...)
static void parse_array(JsonLexContext *lex, JsonSemAction *sem)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Datum array_to_json(PG_FUNCTION_ARGS)
bool IsValidJsonNumber(const char *str, int len)
Datum json_build_object(PG_FUNCTION_ARGS)
#define DATE_NOT_FINITE(j)
Datum row_to_json_pretty(PG_FUNCTION_ARGS)
Datum json_typeof(PG_FUNCTION_ARGS)
void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
#define OidFunctionCall1(functionId, arg1)
void(* json_struct_action)(void *state)
void appendStringInfoString(StringInfo str, const char *s)
void(* json_ofield_action)(void *state, char *fname, bool isnull)
text * cstring_to_text_with_len(const char *s, int len)
MemoryContext MemoryContextSwitchTo(MemoryContext context)
int json_count_array_elements(JsonLexContext *lex)
int errdetail(const char *fmt,...)
static void parse_array_element(JsonLexContext *lex, JsonSemAction *sem)
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
void resetStringInfo(StringInfo str)
bool type_is_rowtype(Oid typid)
static void report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
#define ereport(elevel, rest)
void j2date(int jd, int *year, int *month, int *day)
json_ofield_action object_field_end
Datum json_object(PG_FUNCTION_ARGS)
static JsonTokenType lex_peek(JsonLexContext *lex)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Datum json_object_agg_finalfn(PG_FUNCTION_ARGS)
#define TextDatumGetCString(d)
void * palloc0(Size size)
#define PG_RETURN_DATUM(x)
int GetDatabaseEncoding(void)
json_aelem_action array_element_start
#define HeapTupleHeaderGetTypeId(tup)
static void json_lex_number(JsonLexContext *lex, char *s, bool *num_err)
Datum json_out(PG_FUNCTION_ARGS)
Datum json_object_agg_transfn(PG_FUNCTION_ARGS)
static void add_json(Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
#define PG_RETURN_TEXT_P(x)
text * cstring_to_text(const char *s)
static void json_lex(JsonLexContext *lex)
#define Assert(condition)
json_struct_action array_start
static void report_invalid_token(JsonLexContext *lex)
static void parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
#define PG_RETURN_CSTRING(x)
static void json_lex_string(JsonLexContext *lex)
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Datum json_recv(PG_FUNCTION_ARGS)
int pg_mblen(const char *mbstr)
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
Datum json_agg_transfn(PG_FUNCTION_ARGS)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
char * text_to_cstring(const text *t)
int pg_utf_mblen(const unsigned char *s)
Datum json_build_array_noargs(PG_FUNCTION_ARGS)
char * OidOutputFunctionCall(Oid functionId, Datum val)
#define VARSIZE_ANY_EXHDR(PTR)
int errmsg(const char *fmt,...)
#define PG_GETARG_TEXT_P(n)
static JsonSemAction nullSemAction
Datum json_build_array(PG_FUNCTION_ARGS)
CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
#define CStringGetTextDatum(s)
#define PG_GETARG_CSTRING(n)
#define POSTGRES_EPOCH_JDATE
json_ofield_action object_field_start
#define SET_VARSIZE(PTR, len)
static void parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
Datum row_to_json(PG_FUNCTION_ARGS)
#define ReleaseTupleDesc(tupdesc)
Oid getBaseType(Oid typid)
void(* json_aelem_action)(void *state, bool isnull)
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
static void parse_object(JsonLexContext *lex, JsonSemAction *sem)
json_aelem_action array_element_end
Datum json_send(PG_FUNCTION_ARGS)
static int report_json_context(JsonLexContext *lex)
#define DatumGetTimestamp(X)
#define HeapTupleHeaderGetDatumLength(tup)
#define DatumGetArrayTypeP(X)