3
3
* jsonb.c
4
4
* I/O routines for jsonb type
5
5
*
6
- * Copyright (c) 2014-2017, PostgreSQL Global Development Group
6
+ * COPYRIGHT (c) 2014-2017, PostgreSQL Global Development Group
7
7
*
8
8
* IDENTIFICATION
9
9
* src/backend/utils/adt/jsonb.c
16
16
#include "access/htup_details.h"
17
17
#include "access/transam.h"
18
18
#include "catalog/pg_type.h"
19
+ #include "funcapi.h"
19
20
#include "libpq/pqformat.h"
20
21
#include "parser/parse_coerce.h"
21
22
#include "utils/builtins.h"
@@ -1171,16 +1172,24 @@ to_jsonb(PG_FUNCTION_ARGS)
1171
1172
Datum
1172
1173
jsonb_build_object (PG_FUNCTION_ARGS )
1173
1174
{
1174
- int nargs = PG_NARGS () ;
1175
+ int nargs ;
1175
1176
int i ;
1176
- Datum arg ;
1177
- Oid val_type ;
1178
1177
JsonbInState result ;
1178
+ Datum * args ;
1179
+ bool * nulls ;
1180
+ Oid * types ;
1181
+
1182
+ /* build argument values to build the object */
1183
+ nargs = extract_variadic_args (fcinfo , 0 , true, & args , & types , & nulls );
1184
+
1185
+ if (nargs < 0 )
1186
+ PG_RETURN_NULL ();
1179
1187
1180
1188
if (nargs % 2 != 0 )
1181
1189
ereport (ERROR ,
1182
1190
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1183
- errmsg ("invalid number of arguments: object must be matched key value pairs" )));
1191
+ errmsg ("argument list must have even number of elements" ),
1192
+ errhint ("The arguments of jsonb_build_object() must consist of alternating keys and values." )));
1184
1193
1185
1194
memset (& result , 0 , sizeof (JsonbInState ));
1186
1195
@@ -1189,54 +1198,15 @@ jsonb_build_object(PG_FUNCTION_ARGS)
1189
1198
for (i = 0 ; i < nargs ; i += 2 )
1190
1199
{
1191
1200
/* process key */
1192
-
1193
- if (PG_ARGISNULL (i ))
1201
+ if (nulls [i ])
1194
1202
ereport (ERROR ,
1195
1203
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1196
1204
errmsg ("argument %d: key must not be null" , i + 1 )));
1197
- val_type = get_fn_expr_argtype (fcinfo -> flinfo , i );
1198
-
1199
- /*
1200
- * turn a constant (more or less literal) value that's of unknown type
1201
- * into text. Unknowns come in as a cstring pointer.
1202
- */
1203
- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo , i ))
1204
- {
1205
- val_type = TEXTOID ;
1206
- arg = CStringGetTextDatum (PG_GETARG_POINTER (i ));
1207
- }
1208
- else
1209
- {
1210
- arg = PG_GETARG_DATUM (i );
1211
- }
1212
- if (val_type == InvalidOid || val_type == UNKNOWNOID )
1213
- ereport (ERROR ,
1214
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1215
- errmsg ("could not determine data type for argument %d" , i + 1 )));
1216
1205
1217
- add_jsonb (arg , false, & result , val_type , true);
1206
+ add_jsonb (args [ i ] , false, & result , types [ i ] , true);
1218
1207
1219
1208
/* process value */
1220
-
1221
- val_type = get_fn_expr_argtype (fcinfo -> flinfo , i + 1 );
1222
- /* see comments above */
1223
- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo , i + 1 ))
1224
- {
1225
- val_type = TEXTOID ;
1226
- if (PG_ARGISNULL (i + 1 ))
1227
- arg = (Datum ) 0 ;
1228
- else
1229
- arg = CStringGetTextDatum (PG_GETARG_POINTER (i + 1 ));
1230
- }
1231
- else
1232
- {
1233
- arg = PG_GETARG_DATUM (i + 1 );
1234
- }
1235
- if (val_type == InvalidOid || val_type == UNKNOWNOID )
1236
- ereport (ERROR ,
1237
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1238
- errmsg ("could not determine data type for argument %d" , i + 2 )));
1239
- add_jsonb (arg , PG_ARGISNULL (i + 1 ), & result , val_type , false);
1209
+ add_jsonb (args [i + 1 ], nulls [i + 1 ], & result , types [i + 1 ], false);
1240
1210
}
1241
1211
1242
1212
result .res = pushJsonbValue (& result .parseState , WJB_END_OBJECT , NULL );
@@ -1266,38 +1236,25 @@ jsonb_build_object_noargs(PG_FUNCTION_ARGS)
1266
1236
Datum
1267
1237
jsonb_build_array (PG_FUNCTION_ARGS )
1268
1238
{
1269
- int nargs = PG_NARGS () ;
1239
+ int nargs ;
1270
1240
int i ;
1271
- Datum arg ;
1272
- Oid val_type ;
1273
1241
JsonbInState result ;
1242
+ Datum * args ;
1243
+ bool * nulls ;
1244
+ Oid * types ;
1245
+
1246
+ /* build argument values to build the array */
1247
+ nargs = extract_variadic_args (fcinfo , 0 , true, & args , & types , & nulls );
1248
+
1249
+ if (nargs < 0 )
1250
+ PG_RETURN_NULL ();
1274
1251
1275
1252
memset (& result , 0 , sizeof (JsonbInState ));
1276
1253
1277
1254
result .res = pushJsonbValue (& result .parseState , WJB_BEGIN_ARRAY , NULL );
1278
1255
1279
1256
for (i = 0 ; i < nargs ; i ++ )
1280
- {
1281
- val_type = get_fn_expr_argtype (fcinfo -> flinfo , i );
1282
- /* see comments in jsonb_build_object above */
1283
- if (val_type == UNKNOWNOID && get_fn_expr_arg_stable (fcinfo -> flinfo , i ))
1284
- {
1285
- val_type = TEXTOID ;
1286
- if (PG_ARGISNULL (i ))
1287
- arg = (Datum ) 0 ;
1288
- else
1289
- arg = CStringGetTextDatum (PG_GETARG_POINTER (i ));
1290
- }
1291
- else
1292
- {
1293
- arg = PG_GETARG_DATUM (i );
1294
- }
1295
- if (val_type == InvalidOid || val_type == UNKNOWNOID )
1296
- ereport (ERROR ,
1297
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1298
- errmsg ("could not determine data type for argument %d" , i + 1 )));
1299
- add_jsonb (arg , PG_ARGISNULL (i ), & result , val_type , false);
1300
- }
1257
+ add_jsonb (args [i ], nulls [i ], & result , types [i ], false);
1301
1258
1302
1259
result .res = pushJsonbValue (& result .parseState , WJB_END_ARRAY , NULL );
1303
1260
0 commit comments