From 956cc4434c3a8e69813b325618402508d1dbdcd9 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <andrew@dunslane.net>
Date: Tue, 26 May 2015 22:54:11 -0400
Subject: [PATCH] Revert "Simplify addJsonbToParseState()"

This reverts commit fba12c8c6c4159e1923958a4006b26f3cf873254.

This relied on a commit that is also being reverted.
---
 src/backend/utils/adt/jsonfuncs.c | 35 +++++++++++++++++++------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index 514349310e..fa059c4d6c 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -3225,9 +3225,8 @@ jsonb_strip_nulls(PG_FUNCTION_ARGS)
  * If the parse state container is an object, the jsonb is pushed as
  * a value, not a key.
  *
- * If the new value is a root scalar, extract the value using an iterator, and
- * just add that. Otherwise, add the value as the type appropriate for
- * the container.
+ * This needs to be done using an iterator because pushJsonbValue doesn't
+ * like getting jbvBinary values, so we can't just push jb as a whole.
  */
 static void
 addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb)
@@ -3237,26 +3236,36 @@ addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb)
 	int			type;
 	JsonbValue	v;
 
+	it = JsonbIteratorInit(&jb->root);
+
 	Assert(o->type == jbvArray || o->type == jbvObject);
 
 	if (JB_ROOT_IS_SCALAR(jb))
 	{
-		it = JsonbIteratorInit(&jb->root);
-
 		(void) JsonbIteratorNext(&it, &v, false);		/* skip array header */
 		(void) JsonbIteratorNext(&it, &v, false);		/* fetch scalar value */
 
-		if (o->type == jbvArray)
-			(void) pushJsonbValue(jbps, WJB_ELEM, &v);
-		else
-			(void) pushJsonbValue(jbps, WJB_VALUE, &v);
+		switch (o->type)
+		{
+			case jbvArray:
+				(void) pushJsonbValue(jbps, WJB_ELEM, &v);
+				break;
+			case jbvObject:
+				(void) pushJsonbValue(jbps, WJB_VALUE, &v);
+				break;
+			default:
+				elog(ERROR, "unexpected parent of nested structure");
+		}
 	}
 	else
 	{
-		if (o->type == jbvArray)
-			(void) pushJsonbValue(jbps, WJB_ELEM, &jb->root);
-		else
-			(void) pushJsonbValue(jbps, WJB_VALUE, &jb->root);
+		while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
+		{
+			if (type == WJB_KEY || type == WJB_VALUE || type == WJB_ELEM)
+				(void) pushJsonbValue(jbps, type, &v);
+			else
+				(void) pushJsonbValue(jbps, type, NULL);
+		}
 	}
 
 }
-- 
2.49.0