80 bool *num_err,
int *total_len);
93 Datum *vals,
bool *nulls,
int *valcount,
105 Oid val_type,
bool key_scalar);
152 char *tokstr =
palloc(len + 1);
179 #define JSON_ALPHANUMERIC_CHAR(c) \
180 (((c) >= 'a' && (c) <= 'z') || \
181 ((c) >= 'A' && (c) <= 'Z') || \
182 ((c) >= '0' && (c) <= '9') || \
209 dummy_lex.
input = (
char *) str + 1;
214 dummy_lex.
input = (
char *) str;
220 return (!numeric_error) && (total_len == dummy_lex.
input_length);
454 char **fnameaddr =
NULL;
469 (*ostart) (sem->
semstate, fname, isnull);
484 (*oend) (sem->
semstate, fname, isnull);
620 len = s - lex->
input;
621 while (len < lex->input_length &&
622 (*s ==
' ' || *s ==
'\t' || *s ==
'\n' || *s ==
'\r'))
734 if (memcmp(s,
"true", 4) == 0)
736 else if (memcmp(s,
"null", 4) == 0)
741 else if (p - s == 5 && memcmp(s,
"false", 5) == 0)
758 int hi_surrogate = -1;
778 else if ((
unsigned char) *s < 32)
784 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
785 errmsg(
"invalid input syntax for type json"),
786 errdetail(
"Character with value 0x%02x must be escaped.",
805 for (i = 1; i <= 4; i++)
814 else if (*s >=
'0' && *s <=
'9')
815 ch = (ch * 16) + (*s -
'0');
816 else if (*s >=
'a' && *s <=
'f')
817 ch = (ch * 16) + (*s -
'a') + 10;
818 else if (*s >=
'A' && *s <=
'F')
819 ch = (ch * 16) + (*s -
'A') + 10;
824 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
825 errmsg(
"invalid input syntax for type json"),
826 errdetail(
"\"\\u\" must be followed by four hexadecimal digits."),
835 if (ch >= 0xd800 && ch <= 0xdbff)
837 if (hi_surrogate != -1)
839 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
840 errmsg(
"invalid input syntax for type json"),
841 errdetail(
"Unicode high surrogate must not follow a high surrogate."),
843 hi_surrogate = (ch & 0x3ff) << 10;
846 else if (ch >= 0xdc00 && ch <= 0xdfff)
848 if (hi_surrogate == -1)
850 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
851 errmsg(
"invalid input syntax for type json"),
852 errdetail(
"Unicode low surrogate must follow a high surrogate."),
854 ch = 0x10000 + hi_surrogate + (ch & 0x3ff);
858 if (hi_surrogate != -1)
860 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
861 errmsg(
"invalid input syntax for type json"),
862 errdetail(
"Unicode low surrogate must follow a high surrogate."),
876 (
errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
877 errmsg(
"unsupported Unicode escape sequence"),
878 errdetail(
"\\u0000 cannot be converted to text."),
887 else if (ch <= 0x007f)
899 (
errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
900 errmsg(
"unsupported Unicode escape sequence"),
901 errdetail(
"Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8."),
909 if (hi_surrogate != -1)
911 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
912 errmsg(
"invalid input syntax for type json"),
913 errdetail(
"Unicode low surrogate must follow a high surrogate."),
942 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
943 errmsg(
"invalid input syntax for type json"),
944 errdetail(
"Escape sequence \"\\%s\" is invalid.",
949 else if (strchr(
"\"\\/bfnrt", *s) ==
NULL)
960 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
961 errmsg(
"invalid input syntax for type json"),
962 errdetail(
"Escape sequence \"\\%s\" is invalid.",
970 if (hi_surrogate != -1)
972 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
973 errmsg(
"invalid input syntax for type json"),
974 errdetail(
"Unicode low surrogate must follow a high surrogate."),
982 if (hi_surrogate != -1)
984 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
985 errmsg(
"invalid input syntax for type json"),
986 errdetail(
"Unicode low surrogate must follow a high surrogate."),
1024 bool *num_err,
int *total_len)
1027 int len = s - lex->
input;
1033 if (len < lex->input_length && *s ==
'0')
1038 else if (len < lex->input_length && *s >=
'1' && *s <=
'9')
1044 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
1050 if (len < lex->input_length && *s ==
'.')
1062 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
1067 if (len < lex->input_length && (*s ==
'e' || *s ==
'E'))
1071 if (len < lex->input_length && (*s ==
'+' || *s ==
'-'))
1084 }
while (len < lex->input_length && *s >=
'0' && *s <=
'9');
1096 if (total_len !=
NULL)
1099 if (num_err !=
NULL)
1129 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1130 errmsg(
"invalid input syntax for type json"),
1131 errdetail(
"The input string ended unexpectedly."),
1136 token =
palloc(toklen + 1);
1138 token[toklen] =
'\0';
1143 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1144 errmsg(
"invalid input syntax for type json"),
1145 errdetail(
"Expected end of input, but found \"%s\".",
1154 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1155 errmsg(
"invalid input syntax for type json"),
1156 errdetail(
"Expected JSON value, but found \"%s\".",
1162 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1163 errmsg(
"invalid input syntax for type json"),
1164 errdetail(
"Expected string, but found \"%s\".",
1170 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1171 errmsg(
"invalid input syntax for type json"),
1172 errdetail(
"Expected array element or \"]\", 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 or \"}\", but found \"%s\".",
1194 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1195 errmsg(
"invalid input syntax for type json"),
1196 errdetail(
"Expected \":\", but found \"%s\".",
1202 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1203 errmsg(
"invalid input syntax for type json"),
1204 errdetail(
"Expected \",\" or \"}\", but found \"%s\".",
1210 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1211 errmsg(
"invalid input syntax for type json"),
1212 errdetail(
"Expected string, but found \"%s\".",
1217 elog(
ERROR,
"unexpected json parse state: %d", ctx);
1235 token =
palloc(toklen + 1);
1237 token[toklen] =
'\0';
1240 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1241 errmsg(
"invalid input syntax for type json"),
1242 errdetail(
"Token \"%s\" is invalid.", token),
1259 const char *context_start;
1260 const char *context_end;
1261 const char *line_start;
1269 context_start = lex->
input;
1271 line_start = context_start;
1276 if (context_start < context_end && *context_start ==
'\n')
1279 line_start = context_start;
1284 if (context_end - context_start < 50)
1288 context_start +=
pg_mblen(context_start);
1298 if (context_start - line_start <= 3)
1299 context_start = line_start;
1302 ctxtlen = context_end - context_start;
1303 ctxt =
palloc(ctxtlen + 1);
1304 memcpy(ctxt, context_start, ctxtlen);
1305 ctxt[ctxtlen] =
'\0';
1311 prefix = (context_start > line_start) ?
"..." :
"";
1314 return errcontext(
"JSON data, line %d: %s%s%s",
1315 line_number, prefix, ctxt, suffix);
1329 memcpy(res, s, len);
1416 *outfuncoid = castfunc;
1454 Assert(!(key_scalar && is_null));
1468 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1469 errmsg(
"key value must be scalar, not array, composite, or json")));
1533 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1534 errmsg(
"timestamp out of range")));
1544 const char *tzn =
NULL;
1555 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1556 errmsg(
"timestamp out of range")));
1590 Oid outfuncoid,
bool use_line_feeds)
1597 sep = use_line_feeds ?
",\n " :
",";
1601 for (i = 1; i <= dims[dim]; i++)
1606 if (dim + 1 == ndims)
1608 datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
1619 valcount, tcategory, outfuncoid,
false);
1657 &typlen, &typbyval, &typalign);
1660 &tcategory, &outfuncoid);
1663 typalign, &elements, &nulls,
1667 outfuncoid, use_line_feeds);
1686 bool needsep =
false;
1689 sep = use_line_feeds ?
",\n " :
",";
1705 for (i = 0; i < tupdesc->
natts; i++)
1713 if (tupdesc->
attrs[i]->attisdropped)
1733 &tcategory, &outfuncoid);
1735 datum_to_json(val, isnull, result, tcategory, outfuncoid,
false);
1751 Oid val_type,
bool key_scalar)
1758 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1759 errmsg(
"could not determine input data type")));
1768 &tcategory, &outfuncoid);
1770 datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
1853 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1854 errmsg(
"could not determine input data type")));
1857 &tcategory, &outfuncoid);
1861 datum_to_json(val,
false, result, tcategory, outfuncoid,
false);
1882 elog(
ERROR,
"json_agg_transfn called in non-aggregate context");
1891 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1892 errmsg(
"could not determine input data type")));
1983 elog(
ERROR,
"json_object_agg_transfn called in non-aggregate context");
2005 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2006 errmsg(
"could not determine data type for argument 1")));
2015 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2016 errmsg(
"could not determine data type for argument 2")));
2039 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2040 errmsg(
"field name must not be null")));
2090 int buflen = buffer->
len;
2091 int addlen = strlen(addon);
2096 memcpy(
VARDATA(result) + buflen, addon, addlen);
2110 const char *sep =
"";
2116 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2117 errmsg(
"argument list must have even number of elements"),
2118 errhint(
"The arguments of json_build_object() must consist of alternating keys and values.")));
2124 for (i = 0; i < nargs; i += 2)
2141 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2142 errmsg(
"could not determine data type for argument %d",
2147 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2148 errmsg(
"argument %d cannot be null", i + 1),
2149 errhint(
"Object keys should be text.")));
2153 add_json(arg,
false, result, val_type,
true);
2162 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2163 errmsg(
"could not determine data type for argument %d",
2197 const char *sep =
"";
2205 for (i = 0; i < nargs; i++)
2221 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2222 errmsg(
"could not determine data type for argument %d",
2276 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2277 errmsg(
"array must have even number of elements")));
2283 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2284 errmsg(
"array must have two columns")));
2289 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2290 errmsg(
"wrong number of array subscripts")));
2295 &in_datums, &in_nulls, &in_count);
2297 count = in_count / 2;
2303 for (i = 0; i < count; ++
i)
2305 if (in_nulls[i * 2])
2307 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2308 errmsg(
"null value not allowed for object key")));
2316 if (in_nulls[i * 2 + 1])
2362 if (nkdims > 1 || nkdims != nvdims)
2364 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2365 errmsg(
"wrong number of array subscripts")));
2372 &key_datums, &key_nulls, &key_count);
2376 &val_datums, &val_nulls, &val_count);
2378 if (key_count != val_count)
2380 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2381 errmsg(
"mismatched array dimensions")));
2387 for (i = 0; i < key_count; ++
i)
2391 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2392 errmsg(
"null value not allowed for object key")));
2433 for (p = str; *p; p++)
2459 if ((
unsigned char) *p <
' ')
2518 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
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
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
static void json_lex_number(JsonLexContext *lex, char *s, bool *num_err, int *total_len)
#define PG_GETARG_POINTER(n)
void EncodeSpecialTimestamp(Timestamp dt, char *str)
#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
struct JsonAggState JsonAggState
#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)
void check_stack_depth(void)
#define DatumGetTimestampTz(X)
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)
void EncodeSpecialDate(DateADT dt, char *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
JsonTypeCategory key_category
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)
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)
JsonTypeCategory val_category
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)