]> git.8kb.co.uk Git - postgresql/pg_jsonb_opx/blobdiff - jsonb_utilsx.c
Amend operations on scalar arrays
[postgresql/pg_jsonb_opx] / jsonb_utilsx.c
index c000609a86747dbc380aa040fdd3d9e2a4bbf68b..a08829c21f9ff4cfbaa84a7caf71401ce03d295a 100755 (executable)
@@ -18,7 +18,7 @@
 #include "jsonb_opx.h"
 
 JsonbValue * 
-pushJsonbBinary(JsonbParseState *pstate, JsonbContainer *jsonb_container)
+pushJsonbBinary(JsonbParseState **pstate, JsonbContainer *jsonb_container)
 {
     JsonbIterator *jsonb_iterator;
     JsonbValue jsonb_iterator_value;
@@ -28,11 +28,29 @@ pushJsonbBinary(JsonbParseState *pstate, JsonbContainer *jsonb_container)
     jsonb_iterator = JsonbIteratorInit((void *)jsonb_container);
     while ((jsonb_iterator_token = JsonbIteratorNext(&jsonb_iterator, &jsonb_iterator_value, false)) != WJB_DONE)
     {
-        return_jsonb_value = pushJsonbValue(&pstate, jsonb_iterator_token, &jsonb_iterator_value);
+        return_jsonb_value = pushJsonbValueBlind(pstate, jsonb_iterator_token, &jsonb_iterator_value);
     }
     return return_jsonb_value;
 }
 
+JsonbValue *
+pushJsonbValueBlind(JsonbParseState **pstate, JsonbIteratorToken jsonb_iterator_token, JsonbValue *jsonb_iterator_value)
+{
+    JsonbValue *return_jsonb_value = NULL;
+
+    if ((jsonb_iterator_token == WJB_KEY) ||
+            (jsonb_iterator_token == WJB_VALUE) ||
+            (jsonb_iterator_token == WJB_ELEM) ||
+            (jsonb_iterator_token == WJB_BEGIN_ARRAY && jsonb_iterator_value->val.array.rawScalar))
+            {
+            return_jsonb_value = pushJsonbValue(pstate, jsonb_iterator_token, jsonb_iterator_value);
+            }
+        else
+            return_jsonb_value = pushJsonbValue(pstate, jsonb_iterator_token, NULL);
+
+    return return_jsonb_value;
+}
+
 Jsonb * 
 jsonbModifyPath(Jsonb *jsonb_a, ArrayType *array_path, Jsonb *jsonb_b)
 {
@@ -60,7 +78,6 @@ jsonbModifyPath(Jsonb *jsonb_a, ArrayType *array_path, Jsonb *jsonb_b)
 
     /* the current key we are looking for, starting with the first key */
     text *key_on = NULL;
-    //text *key_on;
     int32 index_on = 0; 
     int32 nest_level = 0;
     int32 array_level = 0;
@@ -141,20 +158,19 @@ jsonbModifyPath(Jsonb *jsonb_a, ArrayType *array_path, Jsonb *jsonb_b)
                                 while ((jsonb_replacement_iterator_token = JsonbIteratorNext(&jsonb_replacement_iterator, &jsonb_replacement_iterator_value, false)) != WJB_DONE)
                                 {
                                     if (((jsonb_last_token == jsonb_replacement_iterator_token) && 
-                                            (jsonb_last_token != WJB_VALUE)) || 
+                                        (jsonb_last_token != WJB_VALUE)) || 
                                         ((jsonb_last_token == WJB_VALUE) && 
-                                            ((jsonb_replacement_iterator_token == WJB_BEGIN_OBJECT) || 
-                                            (jsonb_replacement_iterator_token == WJB_BEGIN_ARRAY)))) 
+                                        ((jsonb_replacement_iterator_token == WJB_BEGIN_OBJECT) || 
+                                        (jsonb_replacement_iterator_token == WJB_BEGIN_ARRAY)))) 
                                     {
                                         push_nest_level++;
                                     }
 
                                     if ((jsonb_replacement_iterator_token == WJB_KEY) || 
                                         (jsonb_replacement_iterator_token == WJB_VALUE) || 
-                                        (jsonb_replacement_iterator_token == WJB_ELEM) || 
-                                        (push_nest_level != 1))
+                                        (jsonb_replacement_iterator_token == WJB_ELEM) || (push_nest_level != 1))
                                     {
-                                        return_jsonb_value = pushJsonbValue(&state, jsonb_replacement_iterator_token, &jsonb_replacement_iterator_value);
+                                        return_jsonb_value = pushJsonbValueBlind(&state, jsonb_replacement_iterator_token, &jsonb_replacement_iterator_value);
                                     }
 
                                     if (((jsonb_last_token == WJB_BEGIN_ARRAY) || 
@@ -182,7 +198,7 @@ jsonbModifyPath(Jsonb *jsonb_a, ArrayType *array_path, Jsonb *jsonb_b)
 
         if (push && (skip_level == 0 || nest_level < skip_level)) 
         {
-            return_jsonb_value = pushJsonbValue(&state, jsonb_iterator_token, &jsonb_iterator_value);
+            return_jsonb_value = pushJsonbValueBlind(&state, jsonb_iterator_token, &jsonb_iterator_value);
             jsonb_last_token = jsonb_iterator_token;
         }
 
@@ -204,5 +220,11 @@ jsonbModifyPath(Jsonb *jsonb_a, ArrayType *array_path, Jsonb *jsonb_b)
         }
     }
 
+    if (return_jsonb_value->type == jbvArray && return_jsonb_value->val.array.rawScalar && return_jsonb_value->val.array.nElems == 0)
+    {
+        return_jsonb_value->val.array.rawScalar = false;
+    }
+
     return JsonbValueToJsonb(return_jsonb_value);
+    
 }