aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-08-20 16:48:35 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-08-20 16:48:53 -0400
commit9bac66020db75871463bafdb394568bf946e8991 (patch)
tree65739cdc72d038e5960a8d642f162f6bcdfd8a77 /src/backend/utils/adt/jsonfuncs.c
parent7567d94910c100a28a79122e86297cd7a4c90df6 (diff)
downloadpostgresql-9bac66020db75871463bafdb394568bf946e8991.tar.gz
postgresql-9bac66020db75871463bafdb394568bf946e8991.zip
Fix core dump in jsonb #> operator, and add regression test cases.
jsonb's #> operator segfaulted (dereferencing a null pointer) if the RHS was a zero-length array, as reported in bug #11207 from Justin Van Winkle. json's #> operator returns NULL in such cases, so for the moment let's make jsonb act likewise. Also add a bunch of regression test queries memorializing the -> and #> operators' behavior for this and other corner cases. There is a good argument for changing some of these behaviors, as they are not very consistent with each other, and throwing an error isn't necessarily a desirable behavior for operators that are likely to be used in indexes. However, everybody can agree that a core dump is the Wrong Thing, and we need test cases even if we decide to change their expected output later.
Diffstat (limited to 'src/backend/utils/adt/jsonfuncs.c')
-rw-r--r--src/backend/utils/adt/jsonfuncs.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index 6c16a953dd3..5fabef0de96 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -726,6 +726,13 @@ get_path_all(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
deconstruct_array(path, TEXTOID, -1, false, 'i',
&pathtext, &pathnulls, &npath);
+ /*
+ * If the array is empty, return NULL; this is dubious but it's what 9.3
+ * did.
+ */
+ if (npath <= 0)
+ PG_RETURN_NULL();
+
tpath = palloc(npath * sizeof(char *));
ipath = palloc(npath * sizeof(int));
@@ -1100,11 +1107,11 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
{
Jsonb *jb = PG_GETARG_JSONB(0);
ArrayType *path = PG_GETARG_ARRAYTYPE_P(1);
+ Jsonb *res;
Datum *pathtext;
bool *pathnulls;
int npath;
int i;
- Jsonb *res;
bool have_object = false,
have_array = false;
JsonbValue *jbvp = NULL;
@@ -1120,6 +1127,13 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
deconstruct_array(path, TEXTOID, -1, false, 'i',
&pathtext, &pathnulls, &npath);
+ /*
+ * If the array is empty, return NULL; this is dubious but it's what 9.3
+ * did.
+ */
+ if (npath <= 0)
+ PG_RETURN_NULL();
+
if (JB_ROOT_IS_OBJECT(jb))
have_object = true;
else if (JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb))