33 #include "utils/fmgroids.h"
44 #define JB_PATH_CREATE 0x0001
45 #define JB_PATH_DELETE 0x0002
46 #define JB_PATH_REPLACE 0x0004
47 #define JB_PATH_INSERT_BEFORE 0x0008
48 #define JB_PATH_INSERT_AFTER 0x0010
49 #define JB_PATH_CREATE_OR_INSERT \
50 (JB_PATH_INSERT_BEFORE | JB_PATH_INSERT_AFTER | JB_PATH_CREATE)
51 #define JB_PATH_FILL_GAPS 0x0020
52 #define JB_PATH_CONSISTENT_POSITION 0x0040
319 #define JsValueIsNull(jsv) \
321 (!(jsv)->val.json.str || (jsv)->val.json.type == JSON_TOKEN_NULL) : \
322 (!(jsv)->val.jsonb || (jsv)->val.jsonb->type == jbvNull))
324 #define JsValueIsString(jsv) \
325 ((jsv)->is_json ? (jsv)->val.json.type == JSON_TOKEN_STRING \
326 : ((jsv)->val.jsonb && (jsv)->val.jsonb->type == jbvString))
328 #define JsObjectIsEmpty(jso) \
330 ? hash_get_num_entries((jso)->val.json_hash) == 0 \
331 : ((jso)->val.jsonb_cont == NULL || \
332 JsonContainerSize((jso)->val.jsonb_cont) == 0))
334 #define JsObjectFree(jso) \
336 if ((jso)->is_json) \
337 hash_destroy((jso)->val.json_hash); \
361 bool normalize_results);
430 bool is_json,
bool have_record_arg);
432 bool is_json,
bool have_record_arg,
451 bool *isnull,
Node *escontext,
bool omit_quotes);
457 bool omit_scalar_quotes);
474 Node *escontext,
bool omit_quotes);
480 bool *path_nulls,
int path_len,
576 bool skipNested =
false;
583 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
584 errmsg(
"cannot call %s on a scalar",
585 "jsonb_object_keys")));
588 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
589 errmsg(
"cannot call %s on an array",
590 "jsonb_object_keys")));
598 state->result_count = 0;
599 state->sent_count = 0;
612 cstr =
palloc(v.
val.string.len + 1 *
sizeof(
char));
613 memcpy(cstr, v.
val.string.val, v.
val.string.len);
614 cstr[v.
val.string.len] =
'\0';
628 char *nxt =
state->result[
state->sent_count++];
647 (
errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
648 errmsg(
"unsupported Unicode escape sequence"),
655 elog(
ERROR,
"JSON semantic action function did not provide error information");
659 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
660 errmsg(
"invalid input syntax for type %s",
"json"),
678 const char *context_start;
679 const char *context_end;
680 const char *line_start;
688 context_start = line_start;
690 Assert(context_end >= context_start);
693 while (context_end - context_start >= 50)
697 context_start +=
pg_mblen(context_start);
707 if (context_start - line_start <= 3)
708 context_start = line_start;
711 ctxtlen = context_end - context_start;
712 ctxt =
palloc(ctxtlen + 1);
713 memcpy(ctxt, context_start, ctxtlen);
714 ctxt[ctxtlen] =
'\0';
720 prefix = (context_start > line_start) ?
"..." :
"";
723 *context_end !=
'\n' && *context_end !=
'\r') ?
"..." :
"";
725 return errcontext(
"JSON data, line %d: %s%s%s",
750 state->result_size = 256;
751 state->result_count = 0;
752 state->sent_count = 0;
776 char *nxt =
state->result[
state->sent_count++];
797 _state->
result = (
char **)
815 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
816 errmsg(
"cannot call %s on an array",
817 "json_object_keys")));
830 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
831 errmsg(
"cannot call %s on a scalar",
832 "json_object_keys")));
852 result =
get_worker(json, &fnamestr, NULL, 1,
false);
890 result =
get_worker(json, &fnamestr, NULL, 1,
true);
1047 tpath =
palloc(npath *
sizeof(
char *));
1048 ipath =
palloc(npath *
sizeof(
int));
1050 for (
i = 0;
i < npath;
i++)
1060 if (*tpath[
i] !=
'\0')
1067 if (endptr == tpath[
i] || *endptr !=
'\0' || errno != 0)
1076 result =
get_worker(json, tpath, ipath, npath, as_text);
1106 bool normalize_results)
1116 state->normalize_results = normalize_results;
1117 state->npath = npath;
1118 state->path_names = tpath;
1119 state->path_indexes = ipath;
1121 state->array_cur_index =
palloc(
sizeof(
int) * npath);
1124 state->pathok[0] =
true;
1155 return state->tresult;
1164 if (lex_level == 0 && _state->
npath == 0)
1183 if (lex_level == 0 && _state->
npath == 0)
1199 bool get_next =
false;
1202 if (lex_level <= _state->npath &&
1203 _state->
pathok[lex_level - 1] &&
1206 strcmp(fname, _state->
path_names[lex_level - 1]) == 0)
1208 if (lex_level < _state->npath)
1211 _state->
pathok[lex_level] =
true;
1246 bool get_last =
false;
1250 if (lex_level <= _state->npath &&
1251 _state->
pathok[lex_level - 1] &&
1254 strcmp(fname, _state->
path_names[lex_level - 1]) == 0)
1256 if (lex_level < _state->npath)
1259 _state->
pathok[lex_level] =
false;
1299 if (lex_level < _state->npath)
1320 else if (lex_level == 0 && _state->
npath == 0)
1339 if (lex_level == 0 && _state->
npath == 0)
1355 bool get_next =
false;
1359 if (lex_level <= _state->npath)
1362 if (lex_level <= _state->npath &&
1363 _state->
pathok[lex_level - 1] &&
1367 if (lex_level < _state->npath)
1370 _state->
pathok[lex_level] =
true;
1403 bool get_last =
false;
1407 if (lex_level <= _state->npath &&
1408 _state->
pathok[lex_level - 1] &&
1412 if (lex_level < _state->npath)
1415 _state->
pathok[lex_level] =
false;
1450 if (lex_level == 0 && _state->
npath == 0)
1535 bool have_object =
false,
1561 if (npath <= 0 && jbvp == NULL)
1576 for (
i = 0;
i < npath;
i++)
1587 else if (have_array)
1595 lindex =
strtoint(indextext, &endptr, 10);
1596 if (endptr == indextext || *endptr !=
'\0' || errno != 0)
1617 if (lindex == INT_MIN || -lindex > nelements)
1623 index = nelements + lindex;
1640 else if (
i == npath - 1)
1645 container = jbvp->
val.binary.data;
1653 have_object =
false;
1684 bool *path_nulls =
palloc0(path_len *
sizeof(
bool));
1737 for (
int i = level + 1;
i < path_len;
i++)
1753 if (badp ==
c || *badp !=
'\0' || errno != 0)
1757 newkey.
val.string.val =
c;
1758 newkey.
val.string.len = strlen(
c);
1777 if (tpath[(path_len - level) - 1] ==
jbvArray)
1788 for (
int i = path_len - 1;
i > level;
i--)
1812 return v->
val.boolean ?
1883 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1884 errmsg(
"cannot get array length of a scalar")));
1887 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1888 errmsg(
"cannot get array length of a non-array")));
1906 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1907 errmsg(
"cannot get array length of a non-array")));
1920 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1921 errmsg(
"cannot get array length of a scalar")));
1979 bool skipNested =
false;
1986 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1987 errmsg(
"cannot call %s on a non-object",
1994 "jsonb_each temporary cxt",
2007 bool nulls[2] = {
false,
false};
2080 state->normalize_results = as_text;
2081 state->next_scalar =
false;
2084 "json_each temporary cxt",
2127 bool nulls[2] = {
false,
false};
2174 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2175 errmsg(
"cannot deconstruct an array as an object")));
2188 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2189 errmsg(
"cannot deconstruct a scalar")));
2226 bool skipNested =
false;
2233 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2234 errmsg(
"cannot extract elements from a scalar")));
2237 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2238 errmsg(
"cannot extract elements from an object")));
2245 "jsonb_array_elements temporary cxt",
2257 bool nulls[1] = {
false};
2333 state->normalize_results = as_text;
2334 state->next_scalar =
false;
2337 "json_array_elements temporary cxt",
2379 bool nulls[1] = {
false};
2424 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2425 errmsg(
"cannot call %s on a non-array",
2439 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2440 errmsg(
"cannot call %s on a scalar",
2481 false,
true, (
Node *) &escontext);
2490 false,
false, NULL);
2515 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2516 errmsg(
"expected JSON array"),
2520 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2521 errmsg(
"expected JSON array")));
2533 for (
i = 0;
i < ndim;
i++)
2538 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2539 errmsg(
"expected JSON array"),
2540 errhint(
"See the array element %s of key \"%s\".",
2544 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2545 errmsg(
"expected JSON array"),
2546 errhint(
"See the array element %s.",
2577 for (
i = 0;
i < ndims;
i++)
2591 int dim = ctx->
sizes[ndim];
2593 if (ctx->
dims[ndim] == -1)
2594 ctx->
dims[ndim] = dim;
2595 else if (ctx->
dims[ndim] != dim)
2597 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2598 errmsg(
"malformed JSON array"),
2599 errdetail(
"Multidimensional arrays must have "
2600 "sub-arrays with matching dimensions.")));
2603 ctx->
sizes[ndim] = 0;
2607 ctx->
sizes[ndim - 1]++;
2620 bool element_isnull;
2637 ctx->
sizes[ndim - 1]++;
2647 int ndim =
state->lex->lex_level;
2649 if (
state->ctx->ndims <= 0)
2654 else if (ndim < state->ctx->ndims)
2671 int ndim =
state->lex->lex_level;
2673 if (ctx->
ndims <= 0)
2679 if (ndim < ctx->ndims)
2694 int ndim =
state->lex->lex_level;
2696 if (
state->ctx->ndims <= 0 || ndim ==
state->ctx->ndims)
2699 state->element_start =
state->lex->token_start;
2700 state->element_type =
state->lex->token_type;
2701 state->element_scalar = NULL;
2713 int ndim =
state->lex->lex_level;
2717 if (ndim == ctx->
ndims)
2730 else if (
state->element_scalar)
2738 jsv.
val.
json.len = (
state->lex->prev_token_terminator -
2739 state->element_start) *
sizeof(
char);
2756 int ndim =
state->lex->lex_level;
2758 if (ctx->
ndims <= 0)
2763 else if (ndim < ctx->ndims)
2771 if (ndim == ctx->
ndims)
2797 memset(&
sem, 0,
sizeof(
sem));
2858 if (ctx->
ndims <= 0 &&
2915 const char *colname,
2993 "populate_composite",
3014 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3016 ?
errmsg(
"cannot call %s on a scalar",
3017 "populate_composite")
3018 :
errmsg(
"cannot call %s on an array",
3019 "populate_composite")));
3059 const char *colname,
3087 defaultval, mcxt, &jso, escontext);
3104 if (typid != io->
base_typid && typid != RECORDOID)
3125 bool *isnull,
Node *escontext,
bool omit_quotes)
3129 const char *json = NULL;
3139 if ((typid == JSONOID || typid == JSONBOID) &&
3170 else if (typid == JSONBOID)
3196 jbv->
val.binary.len);
3198 elog(
ERROR,
"unrecognized jsonb type: %d", (
int) jbv->
type);
3218 const char *colname,
3234 jsv, isnull, escontext, omit_quotes);
3259 column->
typid = typid;
3264 elog(
ERROR,
"cache lookup failed for type %u", typid);
3268 if (
type->typtype == TYPTYPE_DOMAIN)
3275 int32 base_typmod = typmod;
3299 else if (
type->typtype == TYPTYPE_COMPOSITE || typid == RECORDOID)
3308 else if (IsTrueArrayType(
type))
3347 bool *isnull,
bool omit_quotes,
3353 jsv.
is_json = json_type == JSONOID;
3383 jbv.
val.string.len = strlen(
str);
3384 jbv.
val.string.val =
str;
3390 jbv.
val.binary.data = &jsonb->
root;
3400 escontext, omit_quotes);
3408 const char *colname,
3414 bool omit_scalar_quotes)
3448 isnull, escontext, omit_scalar_quotes);
3466 jsv, isnull, escontext, omit_scalar_quotes);
3469 elog(
ERROR,
"unrecognized type category '%c'", typcat);
3483 data->record_typmod = 0;
3484 data->ncolumns = ncolumns;
3505 return hashentry != NULL;
3530 int ncolumns = tupdesc->
natts;
3542 if (record == NULL ||
3558 nulls = (
bool *)
palloc(ncolumns *
sizeof(
bool));
3568 tuple.
t_data = defaultval;
3575 for (
i = 0;
i < ncolumns; ++
i)
3582 for (
i = 0;
i < ncolumns; ++
i)
3585 char *colname =
NameStr(att->attname);
3590 if (att->attisdropped)
3606 if (defaultval && !found)
3646 (
errcode(ERRCODE_DATATYPE_MISMATCH),
3648 errmsg(
"first argument of %s must be a row type",
3670 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3672 errmsg(
"could not determine row type for result of %s",
3674 errhint(
"Provide a non-null record argument, "
3675 "or call the function in the FROM clause "
3676 "using a column definition list.")));
3699 bool is_json,
bool have_record_arg,
3702 int json_arg_num = have_record_arg ? 1 : 0;
3722 if (have_record_arg)
3729 if (!have_record_arg)
3739 if (cache->
argtype == RECORDOID)
3753 if (cache->
argtype == RECORDOID)
3789 jbv.
val.binary.data = &jb->
root;
3795 NULL, fnmcxt, rec, &jsv, &isnull,
3935 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3948 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4041 bool is_json,
bool have_record_arg)
4043 int json_arg_num = have_record_arg ? 1 : 0;
4054 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4055 errmsg(
"set-valued function called in context that cannot accept a set")));
4059 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4060 errmsg(
"materialize mode required, but it is not allowed in this context")));
4075 if (have_record_arg)
4082 if (!have_record_arg)
4092 if (cache->
argtype == RECORDOID)
4106 if (cache->
argtype == RECORDOID)
4134 state->cache = cache;
4168 bool skipNested =
false;
4173 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4174 errmsg(
"cannot call %s on a non-array",
4190 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4191 errmsg(
"argument of %s must be an array of objects",
4223 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4224 errmsg(
"cannot call %s on an object",
4274 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4275 errmsg(
"argument of %s must be an array of objects",
4295 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4296 errmsg(
"cannot call %s on a scalar",
4505 state->skip_next_null =
false;
4519 state->strval->len));
4535 bool last_was_key =
false;
4550 last_was_key =
true;
4557 last_was_key =
false;
4651 bool skipNested =
false;
4656 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4657 errmsg(
"cannot delete from scalar")));
4670 memcmp(keyptr, v.
val.string.val, keylen) == 0))
4705 bool skipNested =
false;
4710 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4711 errmsg(
"wrong number of array subscripts")));
4715 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4716 errmsg(
"cannot delete from scalar")));
4737 for (
i = 0;
i < keys_len;
i++)
4748 if (keylen == v.
val.string.len &&
4749 memcmp(keyptr, v.
val.string.val, keylen) == 0)
4795 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4796 errmsg(
"cannot delete from scalar")));
4800 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4801 errmsg(
"cannot delete from object using integer index")));
4810 n = v.
val.array.nElems;
4863 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4864 errmsg(
"wrong number of array subscripts")));
4868 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4869 errmsg(
"cannot set path in scalar")));
4881 res =
setPath(&it, path_elems, path_nulls, path_len, &st,
4909 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4910 errmsg(
"null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"")));
4919 if (strcmp(handle_val,
"raise_exception") == 0)
4922 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
4923 errmsg(
"JSON value must not be null"),
4924 errdetail(
"Exception was raised because null_value_treatment is \"raise_exception\"."),
4925 errhint(
"To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed.")));
4928 else if (strcmp(handle_val,
"use_json_null") == 0)
4934 fcinfo->args[2].value =
newval;
4935 fcinfo->args[2].isnull =
false;
4938 else if (strcmp(handle_val,
"delete_key") == 0)
4942 else if (strcmp(handle_val,
"return_target") == 0)
4951 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4952 errmsg(
"null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"")));
4974 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
4975 errmsg(
"wrong number of array subscripts")));
4979 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4980 errmsg(
"cannot delete path in scalar")));
4992 res =
setPath(&it, path_elems, path_nulls, path_len, &st,
5022 (
errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
5023 errmsg(
"wrong number of array subscripts")));
5027 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5028 errmsg(
"cannot set path in scalar")));
5182 bool *path_nulls,
int path_len,
5191 if (path_nulls[level])
5193 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5194 errmsg(
"path element at position %d is null",
5210 v.
val.array.rawScalar)
5212 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5213 errmsg(
"cannot replace existing key"),
5214 errdetail(
"The path assumes key is a composite object, "
5215 "but it is a scalar value.")));
5218 setPathArray(it, path_elems, path_nulls, path_len, st, level,
5226 setPathObject(it, path_elems, path_nulls, path_len, st, level,