@@ -139,8 +139,10 @@ static JsonbValue *findJsonbValueFromContainerLen(JsonbContainer *container,
139139/* functions supporting jsonb_delete, jsonb_set and jsonb_concat */
140140static JsonbValue * IteratorConcat (JsonbIterator * * it1 , JsonbIterator * * it2 ,
141141 JsonbParseState * * state );
142- static Datum jsonb_set_element (Datum datum , text * * path , int path_len , Datum sourceData , Oid source_type );
143- static Datum jsonb_get_element (Datum datum , text * * path , int path_len , bool * isNull );
142+ static Datum jsonb_set_element (Datum datum , Datum * path , int path_len ,
143+ Datum sourceData , Oid source_type );
144+ static Datum jsonb_get_element (Jsonb * jb , Datum * path , int npath ,
145+ bool * isnull , bool as_text );
144146static JsonbValue * setPath (JsonbIterator * * it , Datum * path_elems ,
145147 bool * path_nulls , int path_len ,
146148 JsonbParseState * * st , int level , JsonbValue * newval , int op_type );
@@ -1175,16 +1177,11 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
11751177{
11761178 Jsonb * jb = PG_GETARG_JSONB (0 );
11771179 ArrayType * path = PG_GETARG_ARRAYTYPE_P (1 );
1178- Jsonb * res ;
11791180 Datum * pathtext ;
11801181 bool * pathnulls ;
1182+ bool isnull ;
11811183 int npath ;
1182- int i ;
1183- bool have_object = false,
1184- have_array = false;
1185- JsonbValue * jbvp = NULL ;
1186- JsonbValue tv ;
1187- JsonbContainer * container ;
1184+ Datum res ;
11881185
11891186 /*
11901187 * If the array contains any null elements, return NULL, on the grounds
@@ -1199,9 +1196,28 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
11991196 deconstruct_array (path , TEXTOID , -1 , false, 'i' ,
12001197 & pathtext , & pathnulls , & npath );
12011198
1202- /* Identify whether we have object, array, or scalar at top-level */
1203- container = & jb -> root ;
1199+ res = jsonb_get_element (jb , pathtext , npath , & isnull , as_text );
1200+
1201+ if (isnull )
1202+ PG_RETURN_NULL ();
1203+ else
1204+ PG_RETURN_DATUM (res );
1205+ }
12041206
1207+ static Datum
1208+ jsonb_get_element (Jsonb * jb , Datum * path , int npath , bool * isnull , bool as_text )
1209+ {
1210+ Jsonb * res ;
1211+ JsonbContainer * container = & jb -> root ;
1212+ JsonbValue * jbvp = NULL ;
1213+ JsonbValue tv ;
1214+ int i ;
1215+ bool have_object = false,
1216+ have_array = false;
1217+
1218+ * isnull = false;
1219+
1220+ /* Identify whether we have object, array, or scalar at top-level */
12051221 if (JB_ROOT_IS_OBJECT (jb ))
12061222 have_object = true;
12071223 else if (JB_ROOT_IS_ARRAY (jb ) && !JB_ROOT_IS_SCALAR (jb ))
@@ -1226,14 +1242,14 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
12261242 {
12271243 if (as_text )
12281244 {
1229- PG_RETURN_TEXT_P (cstring_to_text (JsonbToCString (NULL ,
1245+ return PointerGetDatum (cstring_to_text (JsonbToCString (NULL ,
12301246 container ,
12311247 VARSIZE (jb ))));
12321248 }
12331249 else
12341250 {
12351251 /* not text mode - just hand back the jsonb */
1236- PG_RETURN_JSONB (jb );
1252+ return JsonbGetDatum (jb );
12371253 }
12381254 }
12391255
@@ -1243,21 +1259,24 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
12431259 {
12441260 jbvp = findJsonbValueFromContainerLen (container ,
12451261 JB_FOBJECT ,
1246- VARDATA_ANY (pathtext [i ]),
1247- VARSIZE_ANY_EXHDR (pathtext [i ]));
1262+ VARDATA_ANY (path [i ]),
1263+ VARSIZE_ANY_EXHDR (path [i ]));
12481264 }
12491265 else if (have_array )
12501266 {
12511267 long lindex ;
12521268 uint32 index ;
1253- char * indextext = TextDatumGetCString (pathtext [i ]);
1269+ char * indextext = TextDatumGetCString (path [i ]);
12541270 char * endptr ;
12551271
12561272 errno = 0 ;
12571273 lindex = strtol (indextext , & endptr , 10 );
12581274 if (endptr == indextext || * endptr != '\0' || errno != 0 ||
12591275 lindex > INT_MAX || lindex < INT_MIN )
1260- PG_RETURN_NULL ();
1276+ {
1277+ * isnull = true;
1278+ return PointerGetDatum (NULL );
1279+ }
12611280
12621281 if (lindex >= 0 )
12631282 {
@@ -1275,7 +1294,10 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
12751294 nelements = container -> header & JB_CMASK ;
12761295
12771296 if (- lindex > nelements )
1278- PG_RETURN_NULL ();
1297+ {
1298+ * isnull = true;
1299+ return PointerGetDatum (NULL );
1300+ }
12791301 else
12801302 index = nelements + lindex ;
12811303 }
@@ -1285,11 +1307,15 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
12851307 else
12861308 {
12871309 /* scalar, extraction yields a null */
1288- PG_RETURN_NULL ();
1310+ * isnull = true;
1311+ return PointerGetDatum (NULL );
12891312 }
12901313
12911314 if (jbvp == NULL )
1292- PG_RETURN_NULL ();
1315+ {
1316+ * isnull = true;
1317+ return PointerGetDatum (NULL );
1318+ }
12931319 else if (i == npath - 1 )
12941320 break ;
12951321
@@ -1314,24 +1340,28 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
13141340 {
13151341 /* special-case outputs for string and null values */
13161342 if (jbvp -> type == jbvString )
1317- PG_RETURN_TEXT_P (cstring_to_text_with_len (jbvp -> val .string .val ,
1318- jbvp -> val .string .len ));
1343+ return PointerGetDatum (
1344+ cstring_to_text_with_len (jbvp -> val .string .val ,
1345+ jbvp -> val .string .len ));
13191346 if (jbvp -> type == jbvNull )
1320- PG_RETURN_NULL ();
1347+ {
1348+ * isnull = true;
1349+ return PointerGetDatum (NULL );
1350+ }
13211351 }
13221352
13231353 res = JsonbValueToJsonb (jbvp );
13241354
13251355 if (as_text )
13261356 {
1327- PG_RETURN_TEXT_P (cstring_to_text (JsonbToCString (NULL ,
1357+ return PointerGetDatum (cstring_to_text (JsonbToCString (NULL ,
13281358 & res -> root ,
13291359 VARSIZE (res ))));
13301360 }
13311361 else
13321362 {
13331363 /* not text mode - just hand back the jsonb */
1334- PG_RETURN_JSONB (res );
1364+ return JsonbGetDatum (res );
13351365 }
13361366}
13371367
@@ -4009,29 +4039,6 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls,
40094039 }
40104040}
40114041
4012- Datum
4013- jsonb_get_element (Datum jsonbdatum , text * * path , int path_len , bool * is_null )
4014- {
4015- Jsonb * jb = DatumGetJsonb (jsonbdatum );
4016- JsonbValue vbuf ;
4017- JsonbValue * v = JsonbToJsonbValue (jb , & vbuf );
4018- int level ;
4019-
4020- for (level = 0 ; level < path_len ; level ++ )
4021- {
4022- if (v -> type != jbvBinary ||
4023- !(v = findJsonbValueFromContainerLen (v -> val .binary .data , JB_FOBJECT ,
4024- VARDATA_ANY (path [level ]),
4025- VARSIZE_ANY_EXHDR (path [level ]))))
4026- {
4027- * is_null = true;
4028- return (Datum ) 0 ;
4029- }
4030- }
4031-
4032- PG_RETURN_JSONB (JsonbValueToJsonb (v ));
4033- }
4034-
40354042Datum
40364043jsonb_subscription_evaluate (PG_FUNCTION_ARGS )
40374044{
@@ -4040,12 +4047,6 @@ jsonb_subscription_evaluate(PG_FUNCTION_ARGS)
40404047 SubscriptionRef * jsonb_ref = (SubscriptionRef * ) sbstate -> xprstate .expr ;
40414048 bool * is_null = sbsdata -> isNull ;
40424049 bool is_assignment = (jsonb_ref -> refassgnexpr != NULL );
4043- text * * path ;
4044- int i = 0 ;
4045-
4046- path = (text * * ) palloc (sbsdata -> indexprNumber * sizeof (text * ));
4047- for (i = 0 ; i < sbsdata -> indexprNumber ; i ++ )
4048- path [i ] = DatumGetTextP (sbsdata -> upper [i ]);
40494050
40504051 if (is_assignment )
40514052 {
@@ -4105,14 +4106,18 @@ jsonb_subscription_evaluate(PG_FUNCTION_ARGS)
41054106 * is_null = false;
41064107 }
41074108
4108- return jsonb_set_element (sbsdata -> containerSource , path ,
4109+ return jsonb_set_element (sbsdata -> containerSource ,
4110+ sbsdata -> upper ,
41094111 sbsdata -> indexprNumber ,
41104112 sourceData ,
41114113 jsonb_ref -> refelemtype );
41124114 }
41134115 else
4114- return jsonb_get_element (sbsdata -> containerSource , path ,
4115- sbsdata -> indexprNumber , is_null );
4116+ return jsonb_get_element (DatumGetJsonb (sbsdata -> containerSource ),
4117+ sbsdata -> upper ,
4118+ sbsdata -> indexprNumber ,
4119+ is_null ,
4120+ false);
41164121}
41174122
41184123Datum
@@ -4180,7 +4185,7 @@ jsonb_subscription(PG_FUNCTION_ARGS)
41804185}
41814186
41824187Datum
4183- jsonb_set_element (Datum jsonbdatum , text * * path , int path_len ,
4188+ jsonb_set_element (Datum jsonbdatum , Datum * path , int path_len ,
41844189 Datum sourceData , Oid source_type )
41854190{
41864191 Jsonb * jb = DatumGetJsonb (jsonbdatum );
@@ -4197,7 +4202,7 @@ jsonb_set_element(Datum jsonbdatum, text **path, int path_len,
41974202
41984203 it = JsonbIteratorInit (& jb -> root );
41994204
4200- res = setPath (& it , ( Datum * ) path , path_nulls , path_len , & state , 0 ,
4205+ res = setPath (& it , path , path_nulls , path_len , & state , 0 ,
42014206 newval , JB_PATH_CREATE );
42024207
42034208 pfree (path_nulls );
0 commit comments