@@ -68,18 +68,25 @@ static JsonbValue *pushJsonbValueScalar(JsonbParseState **pstate,
68
68
JsonbIteratorToken seq ,
69
69
JsonbValue * scalarVal );
70
70
71
+ void
72
+ JsonbToJsonbValue (Jsonb * jsonb , JsonbValue * val )
73
+ {
74
+ val -> type = jbvBinary ;
75
+ val -> val .binary .data = & jsonb -> root ;
76
+ val -> val .binary .len = VARSIZE (jsonb ) - VARHDRSZ ;
77
+ }
78
+
71
79
/*
72
80
* Turn an in-memory JsonbValue into a Jsonb for on-disk storage.
73
81
*
74
- * There isn't a JsonbToJsonbValue(), because generally we find it more
75
- * convenient to directly iterate through the Jsonb representation and only
76
- * really convert nested scalar values. JsonbIteratorNext() does this, so that
77
- * clients of the iteration code don't have to directly deal with the binary
78
- * representation (JsonbDeepContains() is a notable exception, although all
79
- * exceptions are internal to this module). In general, functions that accept
80
- * a JsonbValue argument are concerned with the manipulation of scalar values,
81
- * or simple containers of scalar values, where it would be inconvenient to
82
- * deal with a great amount of other state.
82
+ * Generally we find it more convenient to directly iterate through the Jsonb
83
+ * representation and only really convert nested scalar values.
84
+ * JsonbIteratorNext() does this, so that clients of the iteration code don't
85
+ * have to directly deal with the binary representation (JsonbDeepContains() is
86
+ * a notable exception, although all exceptions are internal to this module).
87
+ * In general, functions that accept a JsonbValue argument are concerned with
88
+ * the manipulation of scalar values, or simple containers of scalar values,
89
+ * where it would be inconvenient to deal with a great amount of other state.
83
90
*/
84
91
Jsonb *
85
92
JsonbValueToJsonb (JsonbValue * val )
@@ -563,6 +570,30 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
563
570
JsonbValue * res = NULL ;
564
571
JsonbValue v ;
565
572
JsonbIteratorToken tok ;
573
+ int i ;
574
+
575
+ if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE ) && jbval -> type == jbvObject )
576
+ {
577
+ pushJsonbValue (pstate , WJB_BEGIN_OBJECT , NULL );
578
+ for (i = 0 ; i < jbval -> val .object .nPairs ; i ++ )
579
+ {
580
+ pushJsonbValue (pstate , WJB_KEY , & jbval -> val .object .pairs [i ].key );
581
+ pushJsonbValue (pstate , WJB_VALUE , & jbval -> val .object .pairs [i ].value );
582
+ }
583
+
584
+ return pushJsonbValue (pstate , WJB_END_OBJECT , NULL );
585
+ }
586
+
587
+ if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE ) && jbval -> type == jbvArray )
588
+ {
589
+ pushJsonbValue (pstate , WJB_BEGIN_ARRAY , NULL );
590
+ for (i = 0 ; i < jbval -> val .array .nElems ; i ++ )
591
+ {
592
+ pushJsonbValue (pstate , WJB_ELEM , & jbval -> val .array .elems [i ]);
593
+ }
594
+
595
+ return pushJsonbValue (pstate , WJB_END_ARRAY , NULL );
596
+ }
566
597
567
598
if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE ) ||
568
599
jbval -> type != jbvBinary )
@@ -573,9 +604,30 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
573
604
574
605
/* unpack the binary and add each piece to the pstate */
575
606
it = JsonbIteratorInit (jbval -> val .binary .data );
607
+
608
+ if ((jbval -> val .binary .data -> header & JB_FSCALAR ) && * pstate )
609
+ {
610
+ tok = JsonbIteratorNext (& it , & v , true);
611
+ Assert (tok == WJB_BEGIN_ARRAY );
612
+ Assert (v .type == jbvArray && v .val .array .rawScalar );
613
+
614
+ tok = JsonbIteratorNext (& it , & v , true);
615
+ Assert (tok == WJB_ELEM );
616
+
617
+ res = pushJsonbValueScalar (pstate , seq , & v );
618
+
619
+ tok = JsonbIteratorNext (& it , & v , true);
620
+ Assert (tok == WJB_END_ARRAY );
621
+ Assert (it == NULL );
622
+
623
+ return res ;
624
+ }
625
+
576
626
while ((tok = JsonbIteratorNext (& it , & v , false)) != WJB_DONE )
577
627
res = pushJsonbValueScalar (pstate , tok ,
578
- tok < WJB_BEGIN_ARRAY ? & v : NULL );
628
+ tok < WJB_BEGIN_ARRAY ||
629
+ (tok == WJB_BEGIN_ARRAY &&
630
+ v .val .array .rawScalar ) ? & v : NULL );
579
631
580
632
return res ;
581
633
}
0 commit comments