1 /*-------------------------------------------------------------------------
2  *
3  * jsonb.c
4  *		I/O routines for jsonb type
5  *
6  * Copyright (c) 2014-2019, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *	  src/backend/utils/adt/jsonb.c
10  *
11  *-------------------------------------------------------------------------
12  */
13 #include "postgres.h"
14 
15 #include "miscadmin.h"
16 #include "access/htup_details.h"
17 #include "access/transam.h"
18 #include "catalog/pg_type.h"
19 #include "funcapi.h"
20 #include "libpq/pqformat.h"
21 #include "parser/parse_coerce.h"
22 #include "utils/builtins.h"
23 #include "utils/date.h"
24 #include "utils/datetime.h"
25 #include "utils/lsyscache.h"
26 #include "utils/json.h"
27 #include "utils/jsonapi.h"
28 #include "utils/jsonb.h"
29 #include "utils/syscache.h"
30 #include "utils/typcache.h"
31 
32 typedef struct JsonbInState
33 {
34 	JsonbParseState *parseState;
35 	JsonbValue *res;
36 } JsonbInState;
37 
38 /* unlike with json categories, we need to treat json and jsonb differently */
39 typedef enum					/* type categories for datum_to_jsonb */
40 {
41 	JSONBTYPE_NULL,				/* null, so we didn't bother to identify */
42 	JSONBTYPE_BOOL,				/* boolean (built-in types only) */
43 	JSONBTYPE_NUMERIC,			/* numeric (ditto) */
44 	JSONBTYPE_DATE,				/* we use special formatting for datetimes */
45 	JSONBTYPE_TIMESTAMP,		/* we use special formatting for timestamp */
46 	JSONBTYPE_TIMESTAMPTZ,		/* ... and timestamptz */
47 	JSONBTYPE_JSON,				/* JSON */
48 	JSONBTYPE_JSONB,			/* JSONB */
49 	JSONBTYPE_ARRAY,			/* array */
50 	JSONBTYPE_COMPOSITE,		/* composite */
51 	JSONBTYPE_JSONCAST,			/* something with an explicit cast to JSON */
52 	JSONBTYPE_OTHER				/* all else */
53 } JsonbTypeCategory;
54 
55 typedef struct JsonbAggState
56 {
57 	JsonbInState *res;
58 	JsonbTypeCategory key_category;
59 	Oid			key_output_func;
60 	JsonbTypeCategory val_category;
61 	Oid			val_output_func;
62 } JsonbAggState;
63 
64 static inline Datum jsonb_from_cstring(char *json, int len);
65 static size_t checkStringLen(size_t len);
66 static void jsonb_in_object_start(void *pstate);
67 static void jsonb_in_object_end(void *pstate);
68 static void jsonb_in_array_start(void *pstate);
69 static void jsonb_in_array_end(void *pstate);
70 static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
71 static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal);
72 static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
73 static void jsonb_categorize_type(Oid typoid,
74 								  JsonbTypeCategory *tcategory,
75 								  Oid *outfuncoid);
76 static void composite_to_jsonb(Datum composite, JsonbInState *result);
77 static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims,
78 							   Datum *vals, bool *nulls, int *valcount,
79 							   JsonbTypeCategory tcategory, Oid outfuncoid);
80 static void array_to_jsonb_internal(Datum array, JsonbInState *result);
81 static void jsonb_categorize_type(Oid typoid,
82 								  JsonbTypeCategory *tcategory,
83 								  Oid *outfuncoid);
84 static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
85 						   JsonbTypeCategory tcategory, Oid outfuncoid,
86 						   bool key_scalar);
87 static void add_jsonb(Datum val, bool is_null, JsonbInState *result,
88 					  Oid val_type, bool key_scalar);
89 static JsonbParseState *clone_parse_state(JsonbParseState *state);
90 static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent);
91 static void add_indent(StringInfo out, bool indent, int level);
92 
93 /*
94  * jsonb type input function
95  */
96 Datum
97 jsonb_in(PG_FUNCTION_ARGS)
98 {
99 	char	   *json = PG_GETARG_CSTRING(0);
100 
101 	return jsonb_from_cstring(json, strlen(json));
102 }
103 
104 /*
105  * jsonb type recv function
106  *
107  * The type is sent as text in binary mode, so this is almost the same
108  * as the input function, but it's prefixed with a version number so we
109  * can change the binary format sent in future if necessary. For now,
110  * only version 1 is supported.
111  */
112 Datum
113 jsonb_recv(PG_FUNCTION_ARGS)
114 {
115 	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
116 	int			version = pq_getmsgint(buf, 1);
117 	char	   *str;
118 	int			nbytes;
119 
120 	if (version == 1)
121 		str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
122 	else
123 		elog(ERROR, "unsupported jsonb version number %d", version);
124 
125 	return jsonb_from_cstring(str, nbytes);
126 }
127 
128 /*
129  * jsonb type output function
130  */
131 Datum
132 jsonb_out(PG_FUNCTION_ARGS)
133 {
134 	Jsonb	   *jb = PG_GETARG_JSONB_P(0);
135 	char	   *out;
136 
137 	out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
138 
139 	PG_RETURN_CSTRING(out);
140 }
141 
142 /*
143  * jsonb type send function
144  *
145  * Just send jsonb as a version number, then a string of text
146  */
147 Datum
148 jsonb_send(PG_FUNCTION_ARGS)
149 {
150 	Jsonb	   *jb = PG_GETARG_JSONB_P(0);
151 	StringInfoData buf;
152 	StringInfo	jtext = makeStringInfo();
153 	int			version = 1;
154 
155 	(void) JsonbToCString(jtext, &jb->root, VARSIZE(jb));
156 
157 	pq_begintypsend(&buf);
158 	pq_sendint8(&buf, version);
159 	pq_sendtext(&buf, jtext->data, jtext->len);
160 	pfree(jtext->data);
161 	pfree(jtext);
162 
163 	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
164 }
165 
166 /*
167  * Get the type name of a jsonb container.
168  */
169 static const char *
170 JsonbContainerTypeName(JsonbContainer *jbc)
171 {
172 	JsonbValue	scalar;
173 
174 	if (JsonbExtractScalar(jbc, &scalar))
175 		return JsonbTypeName(&scalar);
176 	else if (JsonContainerIsArray(jbc))
177 		return "array";
178 	else if (JsonContainerIsObject(jbc))
179 		return "object";
180 	else
181 	{
182 		elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
183 		return "unknown";
184 	}
185 }
186 
187 /*
188  * Get the type name of a jsonb value.
189  */
190 const char *
191 JsonbTypeName(JsonbValue *jbv)
192 {
193 	switch (jbv->type)
194 	{
195 		case jbvBinary:
196 			return JsonbContainerTypeName(jbv->val.binary.data);
197 		case jbvObject:
198 			return "object";
199 		case jbvArray:
200 			return "array";
201 		case jbvNumeric:
202 			return "number";
203 		case jbvString:
204 			return "string";
205 		case jbvBool:
206 			return "boolean";
207 		case jbvNull:
208 			return "null";
209 		default:
210 			elog(ERROR, "unrecognized jsonb value type: %d", jbv->type);
211 			return "unknown";
212 	}
213 }
214 
215 /*
216  * SQL function jsonb_typeof(jsonb) -> text
217  *
218  * This function is here because the analog json function is in json.c, since
219  * it uses the json parser internals not exposed elsewhere.
220  */
221 Datum
222 jsonb_typeof(PG_FUNCTION_ARGS)
223 {
224 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
225 	const char *result = JsonbContainerTypeName(&in->root);
226 
227 	PG_RETURN_TEXT_P(cstring_to_text(result));
228 }
229 
230 /*
231  * jsonb_from_cstring
232  *
233  * Turns json string into a jsonb Datum.
234  *
235  * Uses the json parser (with hooks) to construct a jsonb.
236  */
237 static inline Datum
238 jsonb_from_cstring(char *json, int len)
239 {
240 	JsonLexContext *lex;
241 	JsonbInState state;
242 	JsonSemAction sem;
243 
244 	memset(&state, 0, sizeof(state));
245 	memset(&sem, 0, sizeof(sem));
246 	lex = makeJsonLexContextCstringLen(json, len, true);
247 
248 	sem.semstate = (void *) &state;
249 
250 	sem.object_start = jsonb_in_object_start;
251 	sem.array_start = jsonb_in_array_start;
252 	sem.object_end = jsonb_in_object_end;
253 	sem.array_end = jsonb_in_array_end;
254 	sem.scalar = jsonb_in_scalar;
255 	sem.object_field_start = jsonb_in_object_field_start;
256 
257 	pg_parse_json(lex, &sem);
258 
259 	/* after parsing, the item member has the composed jsonb structure */
260 	PG_RETURN_POINTER(JsonbValueToJsonb(state.res));
261 }
262 
263 static size_t
264 checkStringLen(size_t len)
265 {
266 	if (len > JENTRY_OFFLENMASK)
267 		ereport(ERROR,
268 				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
269 				 errmsg("string too long to represent as jsonb string"),
270 				 errdetail("Due to an implementation restriction, jsonb strings cannot exceed %d bytes.",
271 						   JENTRY_OFFLENMASK)));
272 
273 	return len;
274 }
275 
276 static void
277 jsonb_in_object_start(void *pstate)
278 {
279 	JsonbInState *_state = (JsonbInState *) pstate;
280 
281 	_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
282 }
283 
284 static void
285 jsonb_in_object_end(void *pstate)
286 {
287 	JsonbInState *_state = (JsonbInState *) pstate;
288 
289 	_state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
290 }
291 
292 static void
293 jsonb_in_array_start(void *pstate)
294 {
295 	JsonbInState *_state = (JsonbInState *) pstate;
296 
297 	_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
298 }
299 
300 static void
301 jsonb_in_array_end(void *pstate)
302 {
303 	JsonbInState *_state = (JsonbInState *) pstate;
304 
305 	_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
306 }
307 
308 static void
309 jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
310 {
311 	JsonbInState *_state = (JsonbInState *) pstate;
312 	JsonbValue	v;
313 
314 	Assert(fname != NULL);
315 	v.type = jbvString;
316 	v.val.string.len = checkStringLen(strlen(fname));
317 	v.val.string.val = fname;
318 
319 	_state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
320 }
321 
322 static void
323 jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
324 {
325 	switch (scalarVal->type)
326 	{
327 		case jbvNull:
328 			appendBinaryStringInfo(out, "null", 4);
329 			break;
330 		case jbvString:
331 			escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len));
332 			break;
333 		case jbvNumeric:
334 			appendStringInfoString(out,
335 								   DatumGetCString(DirectFunctionCall1(numeric_out,
336 																	   PointerGetDatum(scalarVal->val.numeric))));
337 			break;
338 		case jbvBool:
339 			if (scalarVal->val.boolean)
340 				appendBinaryStringInfo(out, "true", 4);
341 			else
342 				appendBinaryStringInfo(out, "false", 5);
343 			break;
344 		default:
345 			elog(ERROR, "unknown jsonb scalar type");
346 	}
347 }
348 
349 /*
350  * For jsonb we always want the de-escaped value - that's what's in token
351  */
352 static void
353 jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
354 {
355 	JsonbInState *_state = (JsonbInState *) pstate;
356 	JsonbValue	v;
357 	Datum		numd;
358 
359 	switch (tokentype)
360 	{
361 
362 		case JSON_TOKEN_STRING:
363 			Assert(token != NULL);
364 			v.type = jbvString;
365 			v.val.string.len = checkStringLen(strlen(token));
366 			v.val.string.val = token;
367 			break;
368 		case JSON_TOKEN_NUMBER:
369 
370 			/*
371 			 * No need to check size of numeric values, because maximum
372 			 * numeric size is well below the JsonbValue restriction
373 			 */
374 			Assert(token != NULL);
375 			v.type = jbvNumeric;
376 			numd = DirectFunctionCall3(numeric_in,
377 									   CStringGetDatum(token),
378 									   ObjectIdGetDatum(InvalidOid),
379 									   Int32GetDatum(-1));
380 			v.val.numeric = DatumGetNumeric(numd);
381 			break;
382 		case JSON_TOKEN_TRUE:
383 			v.type = jbvBool;
384 			v.val.boolean = true;
385 			break;
386 		case JSON_TOKEN_FALSE:
387 			v.type = jbvBool;
388 			v.val.boolean = false;
389 			break;
390 		case JSON_TOKEN_NULL:
391 			v.type = jbvNull;
392 			break;
393 		default:
394 			/* should not be possible */
395 			elog(ERROR, "invalid json token type");
396 			break;
397 	}
398 
399 	if (_state->parseState == NULL)
400 	{
401 		/* single scalar */
402 		JsonbValue	va;
403 
404 		va.type = jbvArray;
405 		va.val.array.rawScalar = true;
406 		va.val.array.nElems = 1;
407 
408 		_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va);
409 		_state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
410 		_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
411 	}
412 	else
413 	{
414 		JsonbValue *o = &_state->parseState->contVal;
415 
416 		switch (o->type)
417 		{
418 			case jbvArray:
419 				_state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
420 				break;
421 			case jbvObject:
422 				_state->res = pushJsonbValue(&_state->parseState, WJB_VALUE, &v);
423 				break;
424 			default:
425 				elog(ERROR, "unexpected parent of nested structure");
426 		}
427 	}
428 }
429 
430 /*
431  * JsonbToCString
432  *	   Converts jsonb value to a C-string.
433  *
434  * If 'out' argument is non-null, the resulting C-string is stored inside the
435  * StringBuffer.  The resulting string is always returned.
436  *
437  * A typical case for passing the StringInfo in rather than NULL is where the
438  * caller wants access to the len attribute without having to call strlen, e.g.
439  * if they are converting it to a text* object.
440  */
441 char *
442 JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
443 {
444 	return JsonbToCStringWorker(out, in, estimated_len, false);
445 }
446 
447 /*
448  * same thing but with indentation turned on
449  */
450 char *
451 JsonbToCStringIndent(StringInfo out, JsonbContainer *in, int estimated_len)
452 {
453 	return JsonbToCStringWorker(out, in, estimated_len, true);
454 }
455 
456 /*
457  * common worker for above two functions
458  */
459 static char *
460 JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
461 {
462 	bool		first = true;
463 	JsonbIterator *it;
464 	JsonbValue	v;
465 	JsonbIteratorToken type = WJB_DONE;
466 	int			level = 0;
467 	bool		redo_switch = false;
468 
469 	/* If we are indenting, don't add a space after a comma */
470 	int			ispaces = indent ? 1 : 2;
471 
472 	/*
473 	 * Don't indent the very first item. This gets set to the indent flag at
474 	 * the bottom of the loop.
475 	 */
476 	bool		use_indent = false;
477 	bool		raw_scalar = false;
478 	bool		last_was_key = false;
479 
480 	if (out == NULL)
481 		out = makeStringInfo();
482 
483 	enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);
484 
485 	it = JsonbIteratorInit(in);
486 
487 	while (redo_switch ||
488 		   ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE))
489 	{
490 		redo_switch = false;
491 		switch (type)
492 		{
493 			case WJB_BEGIN_ARRAY:
494 				if (!first)
495 					appendBinaryStringInfo(out, ", ", ispaces);
496 
497 				if (!v.val.array.rawScalar)
498 				{
499 					add_indent(out, use_indent && !last_was_key, level);
500 					appendStringInfoCharMacro(out, '[');
501 				}
502 				else
503 					raw_scalar = true;
504 
505 				first = true;
506 				level++;
507 				break;
508 			case WJB_BEGIN_OBJECT:
509 				if (!first)
510 					appendBinaryStringInfo(out, ", ", ispaces);
511 
512 				add_indent(out, use_indent && !last_was_key, level);
513 				appendStringInfoCharMacro(out, '{');
514 
515 				first = true;
516 				level++;
517 				break;
518 			case WJB_KEY:
519 				if (!first)
520 					appendBinaryStringInfo(out, ", ", ispaces);
521 				first = true;
522 
523 				add_indent(out, use_indent, level);
524 
525 				/* json rules guarantee this is a string */
526 				jsonb_put_escaped_value(out, &v);
527 				appendBinaryStringInfo(out, ": ", 2);
528 
529 				type = JsonbIteratorNext(&it, &v, false);
530 				if (type == WJB_VALUE)
531 				{
532 					first = false;
533 					jsonb_put_escaped_value(out, &v);
534 				}
535 				else
536 				{
537 					Assert(type == WJB_BEGIN_OBJECT || type == WJB_BEGIN_ARRAY);
538 
539 					/*
540 					 * We need to rerun the current switch() since we need to
541 					 * output the object which we just got from the iterator
542 					 * before calling the iterator again.
543 					 */
544 					redo_switch = true;
545 				}
546 				break;
547 			case WJB_ELEM:
548 				if (!first)
549 					appendBinaryStringInfo(out, ", ", ispaces);
550 				first = false;
551 
552 				if (!raw_scalar)
553 					add_indent(out, use_indent, level);
554 				jsonb_put_escaped_value(out, &v);
555 				break;
556 			case WJB_END_ARRAY:
557 				level--;
558 				if (!raw_scalar)
559 				{
560 					add_indent(out, use_indent, level);
561 					appendStringInfoCharMacro(out, ']');
562 				}
563 				first = false;
564 				break;
565 			case WJB_END_OBJECT:
566 				level--;
567 				add_indent(out, use_indent, level);
568 				appendStringInfoCharMacro(out, '}');
569 				first = false;
570 				break;
571 			default:
572 				elog(ERROR, "unknown jsonb iterator token type");
573 		}
574 		use_indent = indent;
575 		last_was_key = redo_switch;
576 	}
577 
578 	Assert(level == 0);
579 
580 	return out->data;
581 }
582 
583 static void
584 add_indent(StringInfo out, bool indent, int level)
585 {
586 	if (indent)
587 	{
588 		int			i;
589 
590 		appendStringInfoCharMacro(out, '\n');
591 		for (i = 0; i < level; i++)
592 			appendBinaryStringInfo(out, "    ", 4);
593 	}
594 }
595 
596 
597 /*
598  * Determine how we want to render values of a given type in datum_to_jsonb.
599  *
600  * Given the datatype OID, return its JsonbTypeCategory, as well as the type's
601  * output function OID.  If the returned category is JSONBTYPE_JSONCAST,
602  * we return the OID of the relevant cast function instead.
603  */
604 static void
605 jsonb_categorize_type(Oid typoid,
606 					  JsonbTypeCategory *tcategory,
607 					  Oid *outfuncoid)
608 {
609 	bool		typisvarlena;
610 
611 	/* Look through any domain */
612 	typoid = getBaseType(typoid);
613 
614 	*outfuncoid = InvalidOid;
615 
616 	/*
617 	 * We need to get the output function for everything except date and
618 	 * timestamp types, booleans, array and composite types, json and jsonb,
619 	 * and non-builtin types where there's a cast to json. In this last case
620 	 * we return the oid of the cast function instead.
621 	 */
622 
623 	switch (typoid)
624 	{
625 		case BOOLOID:
626 			*tcategory = JSONBTYPE_BOOL;
627 			break;
628 
629 		case INT2OID:
630 		case INT4OID:
631 		case INT8OID:
632 		case FLOAT4OID:
633 		case FLOAT8OID:
634 		case NUMERICOID:
635 			getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
636 			*tcategory = JSONBTYPE_NUMERIC;
637 			break;
638 
639 		case DATEOID:
640 			*tcategory = JSONBTYPE_DATE;
641 			break;
642 
643 		case TIMESTAMPOID:
644 			*tcategory = JSONBTYPE_TIMESTAMP;
645 			break;
646 
647 		case TIMESTAMPTZOID:
648 			*tcategory = JSONBTYPE_TIMESTAMPTZ;
649 			break;
650 
651 		case JSONBOID:
652 			*tcategory = JSONBTYPE_JSONB;
653 			break;
654 
655 		case JSONOID:
656 			*tcategory = JSONBTYPE_JSON;
657 			break;
658 
659 		default:
660 			/* Check for arrays and composites */
661 			if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID
662 				|| typoid == RECORDARRAYOID)
663 				*tcategory = JSONBTYPE_ARRAY;
664 			else if (type_is_rowtype(typoid))	/* includes RECORDOID */
665 				*tcategory = JSONBTYPE_COMPOSITE;
666 			else
667 			{
668 				/* It's probably the general case ... */
669 				*tcategory = JSONBTYPE_OTHER;
670 
671 				/*
672 				 * but first let's look for a cast to json (note: not to
673 				 * jsonb) if it's not built-in.
674 				 */
675 				if (typoid >= FirstNormalObjectId)
676 				{
677 					Oid			castfunc;
678 					CoercionPathType ctype;
679 
680 					ctype = find_coercion_pathway(JSONOID, typoid,
681 												  COERCION_EXPLICIT, &castfunc);
682 					if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
683 					{
684 						*tcategory = JSONBTYPE_JSONCAST;
685 						*outfuncoid = castfunc;
686 					}
687 					else
688 					{
689 						/* not a cast type, so just get the usual output func */
690 						getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
691 					}
692 				}
693 				else
694 				{
695 					/* any other builtin type */
696 					getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
697 				}
698 				break;
699 			}
700 	}
701 }
702 
703 /*
704  * Turn a Datum into jsonb, adding it to the result JsonbInState.
705  *
706  * tcategory and outfuncoid are from a previous call to json_categorize_type,
707  * except that if is_null is true then they can be invalid.
708  *
709  * If key_scalar is true, the value is stored as a key, so insist
710  * it's of an acceptable type, and force it to be a jbvString.
711  */
712 static void
713 datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
714 			   JsonbTypeCategory tcategory, Oid outfuncoid,
715 			   bool key_scalar)
716 {
717 	char	   *outputstr;
718 	bool		numeric_error;
719 	JsonbValue	jb;
720 	bool		scalar_jsonb = false;
721 
722 	check_stack_depth();
723 
724 	/* Convert val to a JsonbValue in jb (in most cases) */
725 	if (is_null)
726 	{
727 		Assert(!key_scalar);
728 		jb.type = jbvNull;
729 	}
730 	else if (key_scalar &&
731 			 (tcategory == JSONBTYPE_ARRAY ||
732 			  tcategory == JSONBTYPE_COMPOSITE ||
733 			  tcategory == JSONBTYPE_JSON ||
734 			  tcategory == JSONBTYPE_JSONB ||
735 			  tcategory == JSONBTYPE_JSONCAST))
736 	{
737 		ereport(ERROR,
738 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
739 				 errmsg("key value must be scalar, not array, composite, or json")));
740 	}
741 	else
742 	{
743 		if (tcategory == JSONBTYPE_JSONCAST)
744 			val = OidFunctionCall1(outfuncoid, val);
745 
746 		switch (tcategory)
747 		{
748 			case JSONBTYPE_ARRAY:
749 				array_to_jsonb_internal(val, result);
750 				break;
751 			case JSONBTYPE_COMPOSITE:
752 				composite_to_jsonb(val, result);
753 				break;
754 			case JSONBTYPE_BOOL:
755 				if (key_scalar)
756 				{
757 					outputstr = DatumGetBool(val) ? "true" : "false";
758 					jb.type = jbvString;
759 					jb.val.string.len = strlen(outputstr);
760 					jb.val.string.val = outputstr;
761 				}
762 				else
763 				{
764 					jb.type = jbvBool;
765 					jb.val.boolean = DatumGetBool(val);
766 				}
767 				break;
768 			case JSONBTYPE_NUMERIC:
769 				outputstr = OidOutputFunctionCall(outfuncoid, val);
770 				if (key_scalar)
771 				{
772 					/* always quote keys */
773 					jb.type = jbvString;
774 					jb.val.string.len = strlen(outputstr);
775 					jb.val.string.val = outputstr;
776 				}
777 				else
778 				{
779 					/*
780 					 * Make it numeric if it's a valid JSON number, otherwise
781 					 * a string. Invalid numeric output will always have an
782 					 * 'N' or 'n' in it (I think).
783 					 */
784 					numeric_error = (strchr(outputstr, 'N') != NULL ||
785 									 strchr(outputstr, 'n') != NULL);
786 					if (!numeric_error)
787 					{
788 						Datum		numd;
789 
790 						jb.type = jbvNumeric;
791 						numd = DirectFunctionCall3(numeric_in,
792 												   CStringGetDatum(outputstr),
793 												   ObjectIdGetDatum(InvalidOid),
794 												   Int32GetDatum(-1));
795 						jb.val.numeric = DatumGetNumeric(numd);
796 						pfree(outputstr);
797 					}
798 					else
799 					{
800 						jb.type = jbvString;
801 						jb.val.string.len = strlen(outputstr);
802 						jb.val.string.val = outputstr;
803 					}
804 				}
805 				break;
806 			case JSONBTYPE_DATE:
807 				jb.type = jbvString;
808 				jb.val.string.val = JsonEncodeDateTime(NULL, val, DATEOID);
809 				jb.val.string.len = strlen(jb.val.string.val);
810 				break;
811 			case JSONBTYPE_TIMESTAMP:
812 				jb.type = jbvString;
813 				jb.val.string.val = JsonEncodeDateTime(NULL, val, TIMESTAMPOID);
814 				jb.val.string.len = strlen(jb.val.string.val);
815 				break;
816 			case JSONBTYPE_TIMESTAMPTZ:
817 				jb.type = jbvString;
818 				jb.val.string.val = JsonEncodeDateTime(NULL, val, TIMESTAMPTZOID);
819 				jb.val.string.len = strlen(jb.val.string.val);
820 				break;
821 			case JSONBTYPE_JSONCAST:
822 			case JSONBTYPE_JSON:
823 				{
824 					/* parse the json right into the existing result object */
825 					JsonLexContext *lex;
826 					JsonSemAction sem;
827 					text	   *json = DatumGetTextPP(val);
828 
829 					lex = makeJsonLexContext(json, true);
830 
831 					memset(&sem, 0, sizeof(sem));
832 
833 					sem.semstate = (void *) result;
834 
835 					sem.object_start = jsonb_in_object_start;
836 					sem.array_start = jsonb_in_array_start;
837 					sem.object_end = jsonb_in_object_end;
838 					sem.array_end = jsonb_in_array_end;
839 					sem.scalar = jsonb_in_scalar;
840 					sem.object_field_start = jsonb_in_object_field_start;
841 
842 					pg_parse_json(lex, &sem);
843 
844 				}
845 				break;
846 			case JSONBTYPE_JSONB:
847 				{
848 					Jsonb	   *jsonb = DatumGetJsonbP(val);
849 					JsonbIterator *it;
850 
851 					it = JsonbIteratorInit(&jsonb->root);
852 
853 					if (JB_ROOT_IS_SCALAR(jsonb))
854 					{
855 						(void) JsonbIteratorNext(&it, &jb, true);
856 						Assert(jb.type == jbvArray);
857 						(void) JsonbIteratorNext(&it, &jb, true);
858 						scalar_jsonb = true;
859 					}
860 					else
861 					{
862 						JsonbIteratorToken type;
863 
864 						while ((type = JsonbIteratorNext(&it, &jb, false))
865 							   != WJB_DONE)
866 						{
867 							if (type == WJB_END_ARRAY || type == WJB_END_OBJECT ||
868 								type == WJB_BEGIN_ARRAY || type == WJB_BEGIN_OBJECT)
869 								result->res = pushJsonbValue(&result->parseState,
870 															 type, NULL);
871 							else
872 								result->res = pushJsonbValue(&result->parseState,
873 															 type, &jb);
874 						}
875 					}
876 				}
877 				break;
878 			default:
879 				outputstr = OidOutputFunctionCall(outfuncoid, val);
880 				jb.type = jbvString;
881 				jb.val.string.len = checkStringLen(strlen(outputstr));
882 				jb.val.string.val = outputstr;
883 				break;
884 		}
885 	}
886 
887 	/* Now insert jb into result, unless we did it recursively */
888 	if (!is_null && !scalar_jsonb &&
889 		tcategory >= JSONBTYPE_JSON && tcategory <= JSONBTYPE_JSONCAST)
890 	{
891 		/* work has been done recursively */
892 		return;
893 	}
894 	else if (result->parseState == NULL)
895 	{
896 		/* single root scalar */
897 		JsonbValue	va;
898 
899 		va.type = jbvArray;
900 		va.val.array.rawScalar = true;
901 		va.val.array.nElems = 1;
902 
903 		result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, &va);
904 		result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
905 		result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
906 	}
907 	else
908 	{
909 		JsonbValue *o = &result->parseState->contVal;
910 
911 		switch (o->type)
912 		{
913 			case jbvArray:
914 				result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
915 				break;
916 			case jbvObject:
917 				result->res = pushJsonbValue(&result->parseState,
918 											 key_scalar ? WJB_KEY : WJB_VALUE,
919 											 &jb);
920 				break;
921 			default:
922 				elog(ERROR, "unexpected parent of nested structure");
923 		}
924 	}
925 }
926 
927 /*
928  * Process a single dimension of an array.
929  * If it's the innermost dimension, output the values, otherwise call
930  * ourselves recursively to process the next dimension.
931  */
932 static void
933 array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *vals,
934 				   bool *nulls, int *valcount, JsonbTypeCategory tcategory,
935 				   Oid outfuncoid)
936 {
937 	int			i;
938 
939 	Assert(dim < ndims);
940 
941 	result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
942 
943 	for (i = 1; i <= dims[dim]; i++)
944 	{
945 		if (dim + 1 == ndims)
946 		{
947 			datum_to_jsonb(vals[*valcount], nulls[*valcount], result, tcategory,
948 						   outfuncoid, false);
949 			(*valcount)++;
950 		}
951 		else
952 		{
953 			array_dim_to_jsonb(result, dim + 1, ndims, dims, vals, nulls,
954 							   valcount, tcategory, outfuncoid);
955 		}
956 	}
957 
958 	result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
959 }
960 
961 /*
962  * Turn an array into JSON.
963  */
964 static void
965 array_to_jsonb_internal(Datum array, JsonbInState *result)
966 {
967 	ArrayType  *v = DatumGetArrayTypeP(array);
968 	Oid			element_type = ARR_ELEMTYPE(v);
969 	int		   *dim;
970 	int			ndim;
971 	int			nitems;
972 	int			count = 0;
973 	Datum	   *elements;
974 	bool	   *nulls;
975 	int16		typlen;
976 	bool		typbyval;
977 	char		typalign;
978 	JsonbTypeCategory tcategory;
979 	Oid			outfuncoid;
980 
981 	ndim = ARR_NDIM(v);
982 	dim = ARR_DIMS(v);
983 	nitems = ArrayGetNItems(ndim, dim);
984 
985 	if (nitems <= 0)
986 	{
987 		result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
988 		result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
989 		return;
990 	}
991 
992 	get_typlenbyvalalign(element_type,
993 						 &typlen, &typbyval, &typalign);
994 
995 	jsonb_categorize_type(element_type,
996 						  &tcategory, &outfuncoid);
997 
998 	deconstruct_array(v, element_type, typlen, typbyval,
999 					  typalign, &elements, &nulls,
1000 					  &nitems);
1001 
1002 	array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
1003 					   outfuncoid);
1004 
1005 	pfree(elements);
1006 	pfree(nulls);
1007 }
1008 
1009 /*
1010  * Turn a composite / record into JSON.
1011  */
1012 static void
1013 composite_to_jsonb(Datum composite, JsonbInState *result)
1014 {
1015 	HeapTupleHeader td;
1016 	Oid			tupType;
1017 	int32		tupTypmod;
1018 	TupleDesc	tupdesc;
1019 	HeapTupleData tmptup,
1020 			   *tuple;
1021 	int			i;
1022 
1023 	td = DatumGetHeapTupleHeader(composite);
1024 
1025 	/* Extract rowtype info and find a tupdesc */
1026 	tupType = HeapTupleHeaderGetTypeId(td);
1027 	tupTypmod = HeapTupleHeaderGetTypMod(td);
1028 	tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1029 
1030 	/* Build a temporary HeapTuple control structure */
1031 	tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1032 	tmptup.t_data = td;
1033 	tuple = &tmptup;
1034 
1035 	result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_OBJECT, NULL);
1036 
1037 	for (i = 0; i < tupdesc->natts; i++)
1038 	{
1039 		Datum		val;
1040 		bool		isnull;
1041 		char	   *attname;
1042 		JsonbTypeCategory tcategory;
1043 		Oid			outfuncoid;
1044 		JsonbValue	v;
1045 		Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1046 
1047 		if (att->attisdropped)
1048 			continue;
1049 
1050 		attname = NameStr(att->attname);
1051 
1052 		v.type = jbvString;
1053 		/* don't need checkStringLen here - can't exceed maximum name length */
1054 		v.val.string.len = strlen(attname);
1055 		v.val.string.val = attname;
1056 
1057 		result->res = pushJsonbValue(&result->parseState, WJB_KEY, &v);
1058 
1059 		val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1060 
1061 		if (isnull)
1062 		{
1063 			tcategory = JSONBTYPE_NULL;
1064 			outfuncoid = InvalidOid;
1065 		}
1066 		else
1067 			jsonb_categorize_type(att->atttypid, &tcategory, &outfuncoid);
1068 
1069 		datum_to_jsonb(val, isnull, result, tcategory, outfuncoid, false);
1070 	}
1071 
1072 	result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL);
1073 	ReleaseTupleDesc(tupdesc);
1074 }
1075 
1076 /*
1077  * Append JSON text for "val" to "result".
1078  *
1079  * This is just a thin wrapper around datum_to_jsonb.  If the same type will be
1080  * printed many times, avoid using this; better to do the jsonb_categorize_type
1081  * lookups only once.
1082  */
1083 
1084 static void
1085 add_jsonb(Datum val, bool is_null, JsonbInState *result,
1086 		  Oid val_type, bool key_scalar)
1087 {
1088 	JsonbTypeCategory tcategory;
1089 	Oid			outfuncoid;
1090 
1091 	if (val_type == InvalidOid)
1092 		ereport(ERROR,
1093 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1094 				 errmsg("could not determine input data type")));
1095 
1096 	if (is_null)
1097 	{
1098 		tcategory = JSONBTYPE_NULL;
1099 		outfuncoid = InvalidOid;
1100 	}
1101 	else
1102 		jsonb_categorize_type(val_type,
1103 							  &tcategory, &outfuncoid);
1104 
1105 	datum_to_jsonb(val, is_null, result, tcategory, outfuncoid, key_scalar);
1106 }
1107 
1108 /*
1109  * SQL function to_jsonb(anyvalue)
1110  */
1111 Datum
1112 to_jsonb(PG_FUNCTION_ARGS)
1113 {
1114 	Datum		val = PG_GETARG_DATUM(0);
1115 	Oid			val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1116 	JsonbInState result;
1117 	JsonbTypeCategory tcategory;
1118 	Oid			outfuncoid;
1119 
1120 	if (val_type == InvalidOid)
1121 		ereport(ERROR,
1122 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1123 				 errmsg("could not determine input data type")));
1124 
1125 	jsonb_categorize_type(val_type,
1126 						  &tcategory, &outfuncoid);
1127 
1128 	memset(&result, 0, sizeof(JsonbInState));
1129 
1130 	datum_to_jsonb(val, false, &result, tcategory, outfuncoid, false);
1131 
1132 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1133 }
1134 
1135 /*
1136  * SQL function jsonb_build_object(variadic "any")
1137  */
1138 Datum
1139 jsonb_build_object(PG_FUNCTION_ARGS)
1140 {
1141 	int			nargs;
1142 	int			i;
1143 	JsonbInState result;
1144 	Datum	   *args;
1145 	bool	   *nulls;
1146 	Oid		   *types;
1147 
1148 	/* build argument values to build the object */
1149 	nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1150 
1151 	if (nargs < 0)
1152 		PG_RETURN_NULL();
1153 
1154 	if (nargs % 2 != 0)
1155 		ereport(ERROR,
1156 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1157 				 errmsg("argument list must have even number of elements"),
1158 		/* translator: %s is a SQL function name */
1159 				 errhint("The arguments of %s must consist of alternating keys and values.",
1160 						 "jsonb_build_object()")));
1161 
1162 	memset(&result, 0, sizeof(JsonbInState));
1163 
1164 	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1165 
1166 	for (i = 0; i < nargs; i += 2)
1167 	{
1168 		/* process key */
1169 		if (nulls[i])
1170 			ereport(ERROR,
1171 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1172 					 errmsg("argument %d: key must not be null", i + 1)));
1173 
1174 		add_jsonb(args[i], false, &result, types[i], true);
1175 
1176 		/* process value */
1177 		add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1178 	}
1179 
1180 	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1181 
1182 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1183 }
1184 
1185 /*
1186  * degenerate case of jsonb_build_object where it gets 0 arguments.
1187  */
1188 Datum
1189 jsonb_build_object_noargs(PG_FUNCTION_ARGS)
1190 {
1191 	JsonbInState result;
1192 
1193 	memset(&result, 0, sizeof(JsonbInState));
1194 
1195 	(void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1196 	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1197 
1198 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1199 }
1200 
1201 /*
1202  * SQL function jsonb_build_array(variadic "any")
1203  */
1204 Datum
1205 jsonb_build_array(PG_FUNCTION_ARGS)
1206 {
1207 	int			nargs;
1208 	int			i;
1209 	JsonbInState result;
1210 	Datum	   *args;
1211 	bool	   *nulls;
1212 	Oid		   *types;
1213 
1214 	/* build argument values to build the array */
1215 	nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1216 
1217 	if (nargs < 0)
1218 		PG_RETURN_NULL();
1219 
1220 	memset(&result, 0, sizeof(JsonbInState));
1221 
1222 	result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1223 
1224 	for (i = 0; i < nargs; i++)
1225 		add_jsonb(args[i], nulls[i], &result, types[i], false);
1226 
1227 	result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1228 
1229 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1230 }
1231 
1232 /*
1233  * degenerate case of jsonb_build_array where it gets 0 arguments.
1234  */
1235 Datum
1236 jsonb_build_array_noargs(PG_FUNCTION_ARGS)
1237 {
1238 	JsonbInState result;
1239 
1240 	memset(&result, 0, sizeof(JsonbInState));
1241 
1242 	(void) pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1243 	result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1244 
1245 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1246 }
1247 
1248 
1249 /*
1250  * SQL function jsonb_object(text[])
1251  *
1252  * take a one or two dimensional array of text as name value pairs
1253  * for a jsonb object.
1254  *
1255  */
1256 Datum
1257 jsonb_object(PG_FUNCTION_ARGS)
1258 {
1259 	ArrayType  *in_array = PG_GETARG_ARRAYTYPE_P(0);
1260 	int			ndims = ARR_NDIM(in_array);
1261 	Datum	   *in_datums;
1262 	bool	   *in_nulls;
1263 	int			in_count,
1264 				count,
1265 				i;
1266 	JsonbInState result;
1267 
1268 	memset(&result, 0, sizeof(JsonbInState));
1269 
1270 	(void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1271 
1272 	switch (ndims)
1273 	{
1274 		case 0:
1275 			goto close_object;
1276 			break;
1277 
1278 		case 1:
1279 			if ((ARR_DIMS(in_array)[0]) % 2)
1280 				ereport(ERROR,
1281 						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1282 						 errmsg("array must have even number of elements")));
1283 			break;
1284 
1285 		case 2:
1286 			if ((ARR_DIMS(in_array)[1]) != 2)
1287 				ereport(ERROR,
1288 						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1289 						 errmsg("array must have two columns")));
1290 			break;
1291 
1292 		default:
1293 			ereport(ERROR,
1294 					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1295 					 errmsg("wrong number of array subscripts")));
1296 	}
1297 
1298 	deconstruct_array(in_array,
1299 					  TEXTOID, -1, false, 'i',
1300 					  &in_datums, &in_nulls, &in_count);
1301 
1302 	count = in_count / 2;
1303 
1304 	for (i = 0; i < count; ++i)
1305 	{
1306 		JsonbValue	v;
1307 		char	   *str;
1308 		int			len;
1309 
1310 		if (in_nulls[i * 2])
1311 			ereport(ERROR,
1312 					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1313 					 errmsg("null value not allowed for object key")));
1314 
1315 		str = TextDatumGetCString(in_datums[i * 2]);
1316 		len = strlen(str);
1317 
1318 		v.type = jbvString;
1319 
1320 		v.val.string.len = len;
1321 		v.val.string.val = str;
1322 
1323 		(void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
1324 
1325 		if (in_nulls[i * 2 + 1])
1326 		{
1327 			v.type = jbvNull;
1328 		}
1329 		else
1330 		{
1331 			str = TextDatumGetCString(in_datums[i * 2 + 1]);
1332 			len = strlen(str);
1333 
1334 			v.type = jbvString;
1335 
1336 			v.val.string.len = len;
1337 			v.val.string.val = str;
1338 		}
1339 
1340 		(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
1341 	}
1342 
1343 	pfree(in_datums);
1344 	pfree(in_nulls);
1345 
1346 close_object:
1347 	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1348 
1349 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1350 }
1351 
1352 /*
1353  * SQL function jsonb_object(text[], text[])
1354  *
1355  * take separate name and value arrays of text to construct a jsonb object
1356  * pairwise.
1357  */
1358 Datum
1359 jsonb_object_two_arg(PG_FUNCTION_ARGS)
1360 {
1361 	ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(0);
1362 	ArrayType  *val_array = PG_GETARG_ARRAYTYPE_P(1);
1363 	int			nkdims = ARR_NDIM(key_array);
1364 	int			nvdims = ARR_NDIM(val_array);
1365 	Datum	   *key_datums,
1366 			   *val_datums;
1367 	bool	   *key_nulls,
1368 			   *val_nulls;
1369 	int			key_count,
1370 				val_count,
1371 				i;
1372 	JsonbInState result;
1373 
1374 	memset(&result, 0, sizeof(JsonbInState));
1375 
1376 	(void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1377 
1378 	if (nkdims > 1 || nkdims != nvdims)
1379 		ereport(ERROR,
1380 				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1381 				 errmsg("wrong number of array subscripts")));
1382 
1383 	if (nkdims == 0)
1384 		goto close_object;
1385 
1386 	deconstruct_array(key_array,
1387 					  TEXTOID, -1, false, 'i',
1388 					  &key_datums, &key_nulls, &key_count);
1389 
1390 	deconstruct_array(val_array,
1391 					  TEXTOID, -1, false, 'i',
1392 					  &val_datums, &val_nulls, &val_count);
1393 
1394 	if (key_count != val_count)
1395 		ereport(ERROR,
1396 				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1397 				 errmsg("mismatched array dimensions")));
1398 
1399 	for (i = 0; i < key_count; ++i)
1400 	{
1401 		JsonbValue	v;
1402 		char	   *str;
1403 		int			len;
1404 
1405 		if (key_nulls[i])
1406 			ereport(ERROR,
1407 					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1408 					 errmsg("null value not allowed for object key")));
1409 
1410 		str = TextDatumGetCString(key_datums[i]);
1411 		len = strlen(str);
1412 
1413 		v.type = jbvString;
1414 
1415 		v.val.string.len = len;
1416 		v.val.string.val = str;
1417 
1418 		(void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
1419 
1420 		if (val_nulls[i])
1421 		{
1422 			v.type = jbvNull;
1423 		}
1424 		else
1425 		{
1426 			str = TextDatumGetCString(val_datums[i]);
1427 			len = strlen(str);
1428 
1429 			v.type = jbvString;
1430 
1431 			v.val.string.len = len;
1432 			v.val.string.val = str;
1433 		}
1434 
1435 		(void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
1436 	}
1437 
1438 	pfree(key_datums);
1439 	pfree(key_nulls);
1440 	pfree(val_datums);
1441 	pfree(val_nulls);
1442 
1443 close_object:
1444 	result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1445 
1446 	PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1447 }
1448 
1449 
1450 /*
1451  * shallow clone of a parse state, suitable for use in aggregate
1452  * final functions that will only append to the values rather than
1453  * change them.
1454  */
1455 static JsonbParseState *
1456 clone_parse_state(JsonbParseState *state)
1457 {
1458 	JsonbParseState *result,
1459 			   *icursor,
1460 			   *ocursor;
1461 
1462 	if (state == NULL)
1463 		return NULL;
1464 
1465 	result = palloc(sizeof(JsonbParseState));
1466 	icursor = state;
1467 	ocursor = result;
1468 	for (;;)
1469 	{
1470 		ocursor->contVal = icursor->contVal;
1471 		ocursor->size = icursor->size;
1472 		icursor = icursor->next;
1473 		if (icursor == NULL)
1474 			break;
1475 		ocursor->next = palloc(sizeof(JsonbParseState));
1476 		ocursor = ocursor->next;
1477 	}
1478 	ocursor->next = NULL;
1479 
1480 	return result;
1481 }
1482 
1483 
1484 /*
1485  * jsonb_agg aggregate function
1486  */
1487 Datum
1488 jsonb_agg_transfn(PG_FUNCTION_ARGS)
1489 {
1490 	MemoryContext oldcontext,
1491 				aggcontext;
1492 	JsonbAggState *state;
1493 	JsonbInState elem;
1494 	Datum		val;
1495 	JsonbInState *result;
1496 	bool		single_scalar = false;
1497 	JsonbIterator *it;
1498 	Jsonb	   *jbelem;
1499 	JsonbValue	v;
1500 	JsonbIteratorToken type;
1501 
1502 	if (!AggCheckCallContext(fcinfo, &aggcontext))
1503 	{
1504 		/* cannot be called directly because of internal-type argument */
1505 		elog(ERROR, "jsonb_agg_transfn called in non-aggregate context");
1506 	}
1507 
1508 	/* set up the accumulator on the first go round */
1509 
1510 	if (PG_ARGISNULL(0))
1511 	{
1512 		Oid			arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1513 
1514 		if (arg_type == InvalidOid)
1515 			ereport(ERROR,
1516 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1517 					 errmsg("could not determine input data type")));
1518 
1519 		oldcontext = MemoryContextSwitchTo(aggcontext);
1520 		state = palloc(sizeof(JsonbAggState));
1521 		result = palloc0(sizeof(JsonbInState));
1522 		state->res = result;
1523 		result->res = pushJsonbValue(&result->parseState,
1524 									 WJB_BEGIN_ARRAY, NULL);
1525 		MemoryContextSwitchTo(oldcontext);
1526 
1527 		jsonb_categorize_type(arg_type, &state->val_category,
1528 							  &state->val_output_func);
1529 	}
1530 	else
1531 	{
1532 		state = (JsonbAggState *) PG_GETARG_POINTER(0);
1533 		result = state->res;
1534 	}
1535 
1536 	/* turn the argument into jsonb in the normal function context */
1537 
1538 	val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
1539 
1540 	memset(&elem, 0, sizeof(JsonbInState));
1541 
1542 	datum_to_jsonb(val, PG_ARGISNULL(1), &elem, state->val_category,
1543 				   state->val_output_func, false);
1544 
1545 	jbelem = JsonbValueToJsonb(elem.res);
1546 
1547 	/* switch to the aggregate context for accumulation operations */
1548 
1549 	oldcontext = MemoryContextSwitchTo(aggcontext);
1550 
1551 	it = JsonbIteratorInit(&jbelem->root);
1552 
1553 	while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1554 	{
1555 		switch (type)
1556 		{
1557 			case WJB_BEGIN_ARRAY:
1558 				if (v.val.array.rawScalar)
1559 					single_scalar = true;
1560 				else
1561 					result->res = pushJsonbValue(&result->parseState,
1562 												 type, NULL);
1563 				break;
1564 			case WJB_END_ARRAY:
1565 				if (!single_scalar)
1566 					result->res = pushJsonbValue(&result->parseState,
1567 												 type, NULL);
1568 				break;
1569 			case WJB_BEGIN_OBJECT:
1570 			case WJB_END_OBJECT:
1571 				result->res = pushJsonbValue(&result->parseState,
1572 											 type, NULL);
1573 				break;
1574 			case WJB_ELEM:
1575 			case WJB_KEY:
1576 			case WJB_VALUE:
1577 				if (v.type == jbvString)
1578 				{
1579 					/* copy string values in the aggregate context */
1580 					char	   *buf = palloc(v.val.string.len + 1);
1581 
1582 					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1583 					v.val.string.val = buf;
1584 				}
1585 				else if (v.type == jbvNumeric)
1586 				{
1587 					/* same for numeric */
1588 					v.val.numeric =
1589 						DatumGetNumeric(DirectFunctionCall1(numeric_uplus,
1590 															NumericGetDatum(v.val.numeric)));
1591 				}
1592 				result->res = pushJsonbValue(&result->parseState,
1593 											 type, &v);
1594 				break;
1595 			default:
1596 				elog(ERROR, "unknown jsonb iterator token type");
1597 		}
1598 	}
1599 
1600 	MemoryContextSwitchTo(oldcontext);
1601 
1602 	PG_RETURN_POINTER(state);
1603 }
1604 
1605 Datum
1606 jsonb_agg_finalfn(PG_FUNCTION_ARGS)
1607 {
1608 	JsonbAggState *arg;
1609 	JsonbInState result;
1610 	Jsonb	   *out;
1611 
1612 	/* cannot be called directly because of internal-type argument */
1613 	Assert(AggCheckCallContext(fcinfo, NULL));
1614 
1615 	if (PG_ARGISNULL(0))
1616 		PG_RETURN_NULL();		/* returns null iff no input values */
1617 
1618 	arg = (JsonbAggState *) PG_GETARG_POINTER(0);
1619 
1620 	/*
1621 	 * We need to do a shallow clone of the argument in case the final
1622 	 * function is called more than once, so we avoid changing the argument. A
1623 	 * shallow clone is sufficient as we aren't going to change any of the
1624 	 * values, just add the final array end marker.
1625 	 */
1626 
1627 	result.parseState = clone_parse_state(arg->res->parseState);
1628 
1629 	result.res = pushJsonbValue(&result.parseState,
1630 								WJB_END_ARRAY, NULL);
1631 
1632 	out = JsonbValueToJsonb(result.res);
1633 
1634 	PG_RETURN_POINTER(out);
1635 }
1636 
1637 /*
1638  * jsonb_object_agg aggregate function
1639  */
1640 Datum
1641 jsonb_object_agg_transfn(PG_FUNCTION_ARGS)
1642 {
1643 	MemoryContext oldcontext,
1644 				aggcontext;
1645 	JsonbInState elem;
1646 	JsonbAggState *state;
1647 	Datum		val;
1648 	JsonbInState *result;
1649 	bool		single_scalar;
1650 	JsonbIterator *it;
1651 	Jsonb	   *jbkey,
1652 			   *jbval;
1653 	JsonbValue	v;
1654 	JsonbIteratorToken type;
1655 
1656 	if (!AggCheckCallContext(fcinfo, &aggcontext))
1657 	{
1658 		/* cannot be called directly because of internal-type argument */
1659 		elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
1660 	}
1661 
1662 	/* set up the accumulator on the first go round */
1663 
1664 	if (PG_ARGISNULL(0))
1665 	{
1666 		Oid			arg_type;
1667 
1668 		oldcontext = MemoryContextSwitchTo(aggcontext);
1669 		state = palloc(sizeof(JsonbAggState));
1670 		result = palloc0(sizeof(JsonbInState));
1671 		state->res = result;
1672 		result->res = pushJsonbValue(&result->parseState,
1673 									 WJB_BEGIN_OBJECT, NULL);
1674 		MemoryContextSwitchTo(oldcontext);
1675 
1676 		arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1677 
1678 		if (arg_type == InvalidOid)
1679 			ereport(ERROR,
1680 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1681 					 errmsg("could not determine input data type")));
1682 
1683 		jsonb_categorize_type(arg_type, &state->key_category,
1684 							  &state->key_output_func);
1685 
1686 		arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1687 
1688 		if (arg_type == InvalidOid)
1689 			ereport(ERROR,
1690 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1691 					 errmsg("could not determine input data type")));
1692 
1693 		jsonb_categorize_type(arg_type, &state->val_category,
1694 							  &state->val_output_func);
1695 	}
1696 	else
1697 	{
1698 		state = (JsonbAggState *) PG_GETARG_POINTER(0);
1699 		result = state->res;
1700 	}
1701 
1702 	/* turn the argument into jsonb in the normal function context */
1703 
1704 	if (PG_ARGISNULL(1))
1705 		ereport(ERROR,
1706 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1707 				 errmsg("field name must not be null")));
1708 
1709 	val = PG_GETARG_DATUM(1);
1710 
1711 	memset(&elem, 0, sizeof(JsonbInState));
1712 
1713 	datum_to_jsonb(val, false, &elem, state->key_category,
1714 				   state->key_output_func, true);
1715 
1716 	jbkey = JsonbValueToJsonb(elem.res);
1717 
1718 	val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
1719 
1720 	memset(&elem, 0, sizeof(JsonbInState));
1721 
1722 	datum_to_jsonb(val, PG_ARGISNULL(2), &elem, state->val_category,
1723 				   state->val_output_func, false);
1724 
1725 	jbval = JsonbValueToJsonb(elem.res);
1726 
1727 	it = JsonbIteratorInit(&jbkey->root);
1728 
1729 	/* switch to the aggregate context for accumulation operations */
1730 
1731 	oldcontext = MemoryContextSwitchTo(aggcontext);
1732 
1733 	/*
1734 	 * keys should be scalar, and we should have already checked for that
1735 	 * above when calling datum_to_jsonb, so we only need to look for these
1736 	 * things.
1737 	 */
1738 
1739 	while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1740 	{
1741 		switch (type)
1742 		{
1743 			case WJB_BEGIN_ARRAY:
1744 				if (!v.val.array.rawScalar)
1745 					elog(ERROR, "unexpected structure for key");
1746 				break;
1747 			case WJB_ELEM:
1748 				if (v.type == jbvString)
1749 				{
1750 					/* copy string values in the aggregate context */
1751 					char	   *buf = palloc(v.val.string.len + 1);
1752 
1753 					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1754 					v.val.string.val = buf;
1755 				}
1756 				else
1757 				{
1758 					ereport(ERROR,
1759 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1760 							 errmsg("object keys must be strings")));
1761 				}
1762 				result->res = pushJsonbValue(&result->parseState,
1763 											 WJB_KEY, &v);
1764 				break;
1765 			case WJB_END_ARRAY:
1766 				break;
1767 			default:
1768 				elog(ERROR, "unexpected structure for key");
1769 				break;
1770 		}
1771 	}
1772 
1773 	it = JsonbIteratorInit(&jbval->root);
1774 
1775 	single_scalar = false;
1776 
1777 	/*
1778 	 * values can be anything, including structured and null, so we treat them
1779 	 * as in json_agg_transfn, except that single scalars are always pushed as
1780 	 * WJB_VALUE items.
1781 	 */
1782 
1783 	while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1784 	{
1785 		switch (type)
1786 		{
1787 			case WJB_BEGIN_ARRAY:
1788 				if (v.val.array.rawScalar)
1789 					single_scalar = true;
1790 				else
1791 					result->res = pushJsonbValue(&result->parseState,
1792 												 type, NULL);
1793 				break;
1794 			case WJB_END_ARRAY:
1795 				if (!single_scalar)
1796 					result->res = pushJsonbValue(&result->parseState,
1797 												 type, NULL);
1798 				break;
1799 			case WJB_BEGIN_OBJECT:
1800 			case WJB_END_OBJECT:
1801 				result->res = pushJsonbValue(&result->parseState,
1802 											 type, NULL);
1803 				break;
1804 			case WJB_ELEM:
1805 			case WJB_KEY:
1806 			case WJB_VALUE:
1807 				if (v.type == jbvString)
1808 				{
1809 					/* copy string values in the aggregate context */
1810 					char	   *buf = palloc(v.val.string.len + 1);
1811 
1812 					snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1813 					v.val.string.val = buf;
1814 				}
1815 				else if (v.type == jbvNumeric)
1816 				{
1817 					/* same for numeric */
1818 					v.val.numeric =
1819 						DatumGetNumeric(DirectFunctionCall1(numeric_uplus,
1820 															NumericGetDatum(v.val.numeric)));
1821 				}
1822 				result->res = pushJsonbValue(&result->parseState,
1823 											 single_scalar ? WJB_VALUE : type,
1824 											 &v);
1825 				break;
1826 			default:
1827 				elog(ERROR, "unknown jsonb iterator token type");
1828 		}
1829 	}
1830 
1831 	MemoryContextSwitchTo(oldcontext);
1832 
1833 	PG_RETURN_POINTER(state);
1834 }
1835 
1836 Datum
1837 jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
1838 {
1839 	JsonbAggState *arg;
1840 	JsonbInState result;
1841 	Jsonb	   *out;
1842 
1843 	/* cannot be called directly because of internal-type argument */
1844 	Assert(AggCheckCallContext(fcinfo, NULL));
1845 
1846 	if (PG_ARGISNULL(0))
1847 		PG_RETURN_NULL();		/* returns null iff no input values */
1848 
1849 	arg = (JsonbAggState *) PG_GETARG_POINTER(0);
1850 
1851 	/*
1852 	 * We need to do a shallow clone of the argument's res field in case the
1853 	 * final function is called more than once, so we avoid changing the
1854 	 * aggregate state value.  A shallow clone is sufficient as we aren't
1855 	 * going to change any of the values, just add the final object end
1856 	 * marker.
1857 	 */
1858 
1859 	result.parseState = clone_parse_state(arg->res->parseState);
1860 
1861 	result.res = pushJsonbValue(&result.parseState,
1862 								WJB_END_OBJECT, NULL);
1863 
1864 	out = JsonbValueToJsonb(result.res);
1865 
1866 	PG_RETURN_POINTER(out);
1867 }
1868 
1869 
1870 /*
1871  * Extract scalar value from raw-scalar pseudo-array jsonb.
1872  */
1873 bool
1874 JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
1875 {
1876 	JsonbIterator *it;
1877 	JsonbIteratorToken tok PG_USED_FOR_ASSERTS_ONLY;
1878 	JsonbValue	tmp;
1879 
1880 	if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1881 	{
1882 		/* inform caller about actual type of container */
1883 		res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1884 		return false;
1885 	}
1886 
1887 	/*
1888 	 * A root scalar is stored as an array of one element, so we get the array
1889 	 * and then its first (and only) member.
1890 	 */
1891 	it = JsonbIteratorInit(jbc);
1892 
1893 	tok = JsonbIteratorNext(&it, &tmp, true);
1894 	Assert(tok == WJB_BEGIN_ARRAY);
1895 	Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1896 
1897 	tok = JsonbIteratorNext(&it, res, true);
1898 	Assert(tok == WJB_ELEM);
1899 	Assert(IsAJsonbScalar(res));
1900 
1901 	tok = JsonbIteratorNext(&it, &tmp, true);
1902 	Assert(tok == WJB_END_ARRAY);
1903 
1904 	tok = JsonbIteratorNext(&it, &tmp, true);
1905 	Assert(tok == WJB_DONE);
1906 
1907 	return true;
1908 }
1909 
1910 /*
1911  * Emit correct, translatable cast error message
1912  */
1913 static void
1914 cannotCastJsonbValue(enum jbvType type, const char *sqltype)
1915 {
1916 	static const struct
1917 	{
1918 		enum jbvType type;
1919 		const char *msg;
1920 	}
1921 				messages[] =
1922 	{
1923 		{jbvNull, gettext_noop("cannot cast jsonb null to type %s")},
1924 		{jbvString, gettext_noop("cannot cast jsonb string to type %s")},
1925 		{jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")},
1926 		{jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")},
1927 		{jbvArray, gettext_noop("cannot cast jsonb array to type %s")},
1928 		{jbvObject, gettext_noop("cannot cast jsonb object to type %s")},
1929 		{jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")}
1930 	};
1931 	int			i;
1932 
1933 	for (i = 0; i < lengthof(messages); i++)
1934 		if (messages[i].type == type)
1935 			ereport(ERROR,
1936 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1937 					 errmsg(messages[i].msg, sqltype)));
1938 
1939 	/* should be unreachable */
1940 	elog(ERROR, "unknown jsonb type: %d", (int) type);
1941 }
1942 
1943 Datum
1944 jsonb_bool(PG_FUNCTION_ARGS)
1945 {
1946 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
1947 	JsonbValue	v;
1948 
1949 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
1950 		cannotCastJsonbValue(v.type, "boolean");
1951 
1952 	PG_FREE_IF_COPY(in, 0);
1953 
1954 	PG_RETURN_BOOL(v.val.boolean);
1955 }
1956 
1957 Datum
1958 jsonb_numeric(PG_FUNCTION_ARGS)
1959 {
1960 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
1961 	JsonbValue	v;
1962 	Numeric		retValue;
1963 
1964 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
1965 		cannotCastJsonbValue(v.type, "numeric");
1966 
1967 	/*
1968 	 * v.val.numeric points into jsonb body, so we need to make a copy to
1969 	 * return
1970 	 */
1971 	retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
1972 
1973 	PG_FREE_IF_COPY(in, 0);
1974 
1975 	PG_RETURN_NUMERIC(retValue);
1976 }
1977 
1978 Datum
1979 jsonb_int2(PG_FUNCTION_ARGS)
1980 {
1981 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
1982 	JsonbValue	v;
1983 	Datum		retValue;
1984 
1985 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
1986 		cannotCastJsonbValue(v.type, "smallint");
1987 
1988 	retValue = DirectFunctionCall1(numeric_int2,
1989 								   NumericGetDatum(v.val.numeric));
1990 
1991 	PG_FREE_IF_COPY(in, 0);
1992 
1993 	PG_RETURN_DATUM(retValue);
1994 }
1995 
1996 Datum
1997 jsonb_int4(PG_FUNCTION_ARGS)
1998 {
1999 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
2000 	JsonbValue	v;
2001 	Datum		retValue;
2002 
2003 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2004 		cannotCastJsonbValue(v.type, "integer");
2005 
2006 	retValue = DirectFunctionCall1(numeric_int4,
2007 								   NumericGetDatum(v.val.numeric));
2008 
2009 	PG_FREE_IF_COPY(in, 0);
2010 
2011 	PG_RETURN_DATUM(retValue);
2012 }
2013 
2014 Datum
2015 jsonb_int8(PG_FUNCTION_ARGS)
2016 {
2017 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
2018 	JsonbValue	v;
2019 	Datum		retValue;
2020 
2021 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2022 		cannotCastJsonbValue(v.type, "bigint");
2023 
2024 	retValue = DirectFunctionCall1(numeric_int8,
2025 								   NumericGetDatum(v.val.numeric));
2026 
2027 	PG_FREE_IF_COPY(in, 0);
2028 
2029 	PG_RETURN_DATUM(retValue);
2030 }
2031 
2032 Datum
2033 jsonb_float4(PG_FUNCTION_ARGS)
2034 {
2035 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
2036 	JsonbValue	v;
2037 	Datum		retValue;
2038 
2039 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2040 		cannotCastJsonbValue(v.type, "real");
2041 
2042 	retValue = DirectFunctionCall1(numeric_float4,
2043 								   NumericGetDatum(v.val.numeric));
2044 
2045 	PG_FREE_IF_COPY(in, 0);
2046 
2047 	PG_RETURN_DATUM(retValue);
2048 }
2049 
2050 Datum
2051 jsonb_float8(PG_FUNCTION_ARGS)
2052 {
2053 	Jsonb	   *in = PG_GETARG_JSONB_P(0);
2054 	JsonbValue	v;
2055 	Datum		retValue;
2056 
2057 	if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2058 		cannotCastJsonbValue(v.type, "double precision");
2059 
2060 	retValue = DirectFunctionCall1(numeric_float8,
2061 								   NumericGetDatum(v.val.numeric));
2062 
2063 	PG_FREE_IF_COPY(in, 0);
2064 
2065 	PG_RETURN_DATUM(retValue);
2066 }
2067