Commit ea4b8bd6 authored by Tom Lane's avatar Tom Lane

Code review for error reports in jsonb_set().

User-facing (even tested by regression tests) error conditions were thrown
with elog(), hence had wrong SQLSTATE and were untranslatable.  And the
error message texts weren't up to project style, either.
parent 384dfbde
...@@ -3722,12 +3722,15 @@ setPath(JsonbIterator **it, Datum *path_elems, ...@@ -3722,12 +3722,15 @@ setPath(JsonbIterator **it, Datum *path_elems,
{ {
JsonbValue v; JsonbValue v;
JsonbIteratorToken r; JsonbIteratorToken r;
JsonbValue *res = NULL; JsonbValue *res;
check_stack_depth(); check_stack_depth();
if (path_nulls[level]) if (path_nulls[level])
elog(ERROR, "path element at the position %d is NULL", level + 1); ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("path element at position %d is null",
level + 1)));
r = JsonbIteratorNext(it, &v, false); r = JsonbIteratorNext(it, &v, false);
...@@ -3740,7 +3743,6 @@ setPath(JsonbIterator **it, Datum *path_elems, ...@@ -3740,7 +3743,6 @@ setPath(JsonbIterator **it, Datum *path_elems,
r = JsonbIteratorNext(it, &v, false); r = JsonbIteratorNext(it, &v, false);
Assert(r == WJB_END_ARRAY); Assert(r == WJB_END_ARRAY);
res = pushJsonbValue(st, r, NULL); res = pushJsonbValue(st, r, NULL);
break; break;
case WJB_BEGIN_OBJECT: case WJB_BEGIN_OBJECT:
(void) pushJsonbValue(st, r, NULL); (void) pushJsonbValue(st, r, NULL);
...@@ -3749,14 +3751,15 @@ setPath(JsonbIterator **it, Datum *path_elems, ...@@ -3749,14 +3751,15 @@ setPath(JsonbIterator **it, Datum *path_elems,
r = JsonbIteratorNext(it, &v, true); r = JsonbIteratorNext(it, &v, true);
Assert(r == WJB_END_OBJECT); Assert(r == WJB_END_OBJECT);
res = pushJsonbValue(st, r, NULL); res = pushJsonbValue(st, r, NULL);
break; break;
case WJB_ELEM: case WJB_ELEM:
case WJB_VALUE: case WJB_VALUE:
res = pushJsonbValue(st, r, &v); res = pushJsonbValue(st, r, &v);
break; break;
default: default:
elog(ERROR, "impossible state"); elog(ERROR, "unrecognized iterator result: %d", (int) r);
res = NULL; /* keep compiler quiet */
break;
} }
return res; return res;
...@@ -3867,7 +3870,6 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, ...@@ -3867,7 +3870,6 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
JsonbValue v; JsonbValue v;
int idx, int idx,
i; i;
char *badp;
bool done = false; bool done = false;
/* pick correct index */ /* pick correct index */
...@@ -3875,14 +3877,17 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, ...@@ -3875,14 +3877,17 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
{ {
char *c = TextDatumGetCString(path_elems[level]); char *c = TextDatumGetCString(path_elems[level]);
long lindex; long lindex;
char *badp;
errno = 0; errno = 0;
lindex = strtol(c, &badp, 10); lindex = strtol(c, &badp, 10);
if (errno != 0 || badp == c || *badp != '\0' || lindex > INT_MAX || if (errno != 0 || badp == c || *badp != '\0' || lindex > INT_MAX ||
lindex < INT_MIN) lindex < INT_MIN)
elog(ERROR, "path element at the position %d is not an integer", level + 1); ereport(ERROR,
else (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
idx = lindex; errmsg("path element at position %d is not an integer: \"%s\"",
level + 1, c)));
idx = lindex;
} }
else else
idx = nelems; idx = nelems;
...@@ -3957,7 +3962,6 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, ...@@ -3957,7 +3962,6 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
{ {
addJsonbToParseState(st, newval); addJsonbToParseState(st, newval);
} }
} }
} }
} }
...@@ -3114,7 +3114,7 @@ select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::j ...@@ -3114,7 +3114,7 @@ select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::j
(1 row) (1 row)
select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '[1,2,3]'); select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '[1,2,3]');
ERROR: path element at the position 2 is NULL ERROR: path element at position 2 is null
select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '{"1": 2}'); select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '{"1": 2}');
jsonb_set jsonb_set
------------------------------------------------------------------------- -------------------------------------------------------------------------
...@@ -3134,7 +3134,7 @@ select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::j ...@@ -3134,7 +3134,7 @@ select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::j
(1 row) (1 row)
select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '{"1": 2}'); select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,NULL,0}', '{"1": 2}');
ERROR: path element at the position 2 is NULL ERROR: path element at position 2 is null
select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '"test"'); select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '"test"');
jsonb_set jsonb_set
-------------------------------------------------------------------------- --------------------------------------------------------------------------
...@@ -3178,7 +3178,7 @@ select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{ ...@@ -3178,7 +3178,7 @@ select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{
(1 row) (1 row)
select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1e}'; -- invalid array subscript select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{b,-1e}'; -- invalid array subscript
ERROR: path element at the position 2 is not an integer ERROR: path element at position 2 is not an integer: "-1e"
select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{d,1,0}'; select '{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb #- '{d,1,0}';
?column? ?column?
------------------------------------------------------------------ ------------------------------------------------------------------
...@@ -3307,8 +3307,8 @@ select jsonb_set('[]','{-99}','{"foo":123}'); ...@@ -3307,8 +3307,8 @@ select jsonb_set('[]','{-99}','{"foo":123}');
(1 row) (1 row)
select jsonb_set('{"a": [1, 2, 3]}', '{a, non_integer}', '"new_value"'); select jsonb_set('{"a": [1, 2, 3]}', '{a, non_integer}', '"new_value"');
ERROR: path element at the position 2 is not an integer ERROR: path element at position 2 is not an integer: "non_integer"
select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, non_integer}', '"new_value"'); select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, non_integer}', '"new_value"');
ERROR: path element at the position 3 is not an integer ERROR: path element at position 3 is not an integer: "non_integer"
select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, NULL}', '"new_value"'); select jsonb_set('{"a": {"b": [1, 2, 3]}}', '{a, b, NULL}', '"new_value"');
ERROR: path element at the position 3 is NULL ERROR: path element at position 3 is null
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment