14
14
15
15
#include "lib/stringinfo.h"
16
16
#include "utils/array.h"
17
+ #include "utils/builtins.h"
17
18
#include "utils/numeric.h"
18
19
19
20
/* Tokens used when sequentially processing a jsonb value */
@@ -229,8 +230,7 @@ typedef struct
229
230
#define JB_ROOT_IS_OBJECT (jbp_ ) ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0)
230
231
#define JB_ROOT_IS_ARRAY (jbp_ ) ((*(uint32 *) VARDATA(jbp_) & JB_FARRAY) != 0)
231
232
232
-
233
- enum jbvType
233
+ typedef enum jbvType
234
234
{
235
235
/* Scalar types */
236
236
jbvNull = 0x0 ,
@@ -250,7 +250,7 @@ enum jbvType
250
250
* into JSON strings when outputted to json/jsonb.
251
251
*/
252
252
jbvDatetime = 0x20 ,
253
- };
253
+ } JsonbValueType ;
254
254
255
255
/*
256
256
* JsonbValue: In-memory representation of Jsonb. This is a convenient
@@ -269,7 +269,7 @@ struct JsonbValue
269
269
struct
270
270
{
271
271
int len ;
272
- char * val ; /* Not necessarily null-terminated */
272
+ const char * val ; /* Not necessarily null-terminated */
273
273
} string ; /* String primitive type */
274
274
275
275
struct
@@ -382,6 +382,10 @@ extern int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b);
382
382
extern JsonbValue * findJsonbValueFromContainer (JsonbContainer * sheader ,
383
383
uint32 flags ,
384
384
JsonbValue * key );
385
+ extern JsonbValue * findJsonbValueFromContainerLen (JsonbContainer * container ,
386
+ uint32 flags ,
387
+ const char * key ,
388
+ uint32 keylen );
385
389
extern JsonbValue * getKeyJsonValueFromContainer (JsonbContainer * container ,
386
390
const char * keyVal , int keyLen ,
387
391
JsonbValue * res );
@@ -399,6 +403,7 @@ extern bool JsonbDeepContains(JsonbIterator **val,
399
403
extern void JsonbHashScalarValue (const JsonbValue * scalarVal , uint32 * hash );
400
404
extern void JsonbHashScalarValueExtended (const JsonbValue * scalarVal ,
401
405
uint64 * hash , uint64 seed );
406
+ extern bool JsonbExtractScalar (JsonbContainer * jbc , JsonbValue * res );
402
407
403
408
/* jsonb.c support functions */
404
409
extern char * JsonbToCString (StringInfo out , JsonbContainer * in ,
@@ -412,4 +417,157 @@ extern Datum jsonb_set_element(Jsonb *jb, Datum *path, int path_len,
412
417
JsonbValue * newval );
413
418
extern Datum jsonb_get_element (Jsonb * jb , Datum * path , int npath ,
414
419
bool * isnull , bool as_text );
420
+
421
+ /*
422
+ * XXX Not sure we want to add these functions to jsonb.h, which is the
423
+ * public API. Maybe it belongs rather to jsonb_typanalyze.c or elsewhere,
424
+ * closer to how it's used?
425
+ */
426
+
427
+ /* helper inline functions for JsonbValue initialization */
428
+ static inline JsonbValue *
429
+ JsonValueInitObject (JsonbValue * val , int nPairs , int nPairsAllocated )
430
+ {
431
+ val -> type = jbvObject ;
432
+ val -> val .object .nPairs = nPairs ;
433
+ val -> val .object .pairs = nPairsAllocated ?
434
+ palloc (sizeof (JsonbPair ) * nPairsAllocated ) : NULL ;
435
+
436
+ return val ;
437
+ }
438
+
439
+ static inline JsonbValue *
440
+ JsonValueInitArray (JsonbValue * val , int nElems , int nElemsAllocated ,
441
+ bool rawScalar )
442
+ {
443
+ val -> type = jbvArray ;
444
+ val -> val .array .nElems = nElems ;
445
+ val -> val .array .elems = nElemsAllocated ?
446
+ palloc (sizeof (JsonbValue ) * nElemsAllocated ) : NULL ;
447
+ val -> val .array .rawScalar = rawScalar ;
448
+
449
+ return val ;
450
+ }
451
+
452
+ static inline JsonbValue *
453
+ JsonValueInitBinary (JsonbValue * val , Jsonb * jb )
454
+ {
455
+ val -> type = jbvBinary ;
456
+ val -> val .binary .data = & (jb )-> root ;
457
+ val -> val .binary .len = VARSIZE_ANY_EXHDR (jb );
458
+ return val ;
459
+ }
460
+
461
+
462
+ static inline JsonbValue *
463
+ JsonValueInitString (JsonbValue * jbv , const char * str )
464
+ {
465
+ jbv -> type = jbvString ;
466
+ jbv -> val .string .len = strlen (str );
467
+ jbv -> val .string .val = memcpy (palloc (jbv -> val .string .len + 1 ), str ,
468
+ jbv -> val .string .len + 1 );
469
+ return jbv ;
470
+ }
471
+
472
+ static inline JsonbValue *
473
+ JsonValueInitStringWithLen (JsonbValue * jbv , const char * str , int len )
474
+ {
475
+ jbv -> type = jbvString ;
476
+ jbv -> val .string .val = str ;
477
+ jbv -> val .string .len = len ;
478
+ return jbv ;
479
+ }
480
+
481
+ static inline JsonbValue *
482
+ JsonValueInitText (JsonbValue * jbv , text * txt )
483
+ {
484
+ jbv -> type = jbvString ;
485
+ jbv -> val .string .val = VARDATA_ANY (txt );
486
+ jbv -> val .string .len = VARSIZE_ANY_EXHDR (txt );
487
+ return jbv ;
488
+ }
489
+
490
+ static inline JsonbValue *
491
+ JsonValueInitNumeric (JsonbValue * jbv , Numeric num )
492
+ {
493
+ jbv -> type = jbvNumeric ;
494
+ jbv -> val .numeric = num ;
495
+ return jbv ;
496
+ }
497
+
498
+ static inline JsonbValue *
499
+ JsonValueInitInteger (JsonbValue * jbv , int64 i )
500
+ {
501
+ jbv -> type = jbvNumeric ;
502
+ jbv -> val .numeric = DatumGetNumeric (DirectFunctionCall1 (
503
+ int8_numeric , Int64GetDatum (i )));
504
+ return jbv ;
505
+ }
506
+
507
+ static inline JsonbValue *
508
+ JsonValueInitFloat (JsonbValue * jbv , float4 f )
509
+ {
510
+ jbv -> type = jbvNumeric ;
511
+ jbv -> val .numeric = DatumGetNumeric (DirectFunctionCall1 (
512
+ float4_numeric , Float4GetDatum (f )));
513
+ return jbv ;
514
+ }
515
+
516
+ static inline JsonbValue *
517
+ JsonValueInitDouble (JsonbValue * jbv , float8 f )
518
+ {
519
+ jbv -> type = jbvNumeric ;
520
+ jbv -> val .numeric = DatumGetNumeric (DirectFunctionCall1 (
521
+ float8_numeric , Float8GetDatum (f )));
522
+ return jbv ;
523
+ }
524
+
525
+ /* helper macros for jsonb building */
526
+ #define pushJsonbKey (pstate , jbv , key ) \
527
+ pushJsonbValue(pstate, WJB_KEY, JsonValueInitString(jbv, key))
528
+
529
+ #define pushJsonbValueGeneric (Type , pstate , jbv , val ) \
530
+ pushJsonbValue(pstate, WJB_VALUE, JsonValueInit##Type(jbv, val))
531
+
532
+ #define pushJsonbElemGeneric (Type , pstate , jbv , val ) \
533
+ pushJsonbValue(pstate, WJB_ELEM, JsonValueInit##Type(jbv, val))
534
+
535
+ #define pushJsonbValueInteger (pstate , jbv , i ) \
536
+ pushJsonbValueGeneric(Integer, pstate, jbv, i)
537
+
538
+ #define pushJsonbValueFloat (pstate , jbv , f ) \
539
+ pushJsonbValueGeneric(Float, pstate, jbv, f)
540
+
541
+ #define pushJsonbElemFloat (pstate , jbv , f ) \
542
+ pushJsonbElemGeneric(Float, pstate, jbv, f)
543
+
544
+ #define pushJsonbElemString (pstate , jbv , txt ) \
545
+ pushJsonbElemGeneric(String, pstate, jbv, txt)
546
+
547
+ #define pushJsonbElemText (pstate , jbv , txt ) \
548
+ pushJsonbElemGeneric(Text, pstate, jbv, txt)
549
+
550
+ #define pushJsonbElemNumeric (pstate , jbv , num ) \
551
+ pushJsonbElemGeneric(Numeric, pstate, jbv, num)
552
+
553
+ #define pushJsonbElemInteger (pstate , jbv , num ) \
554
+ pushJsonbElemGeneric(Integer, pstate, jbv, num)
555
+
556
+ #define pushJsonbElemBinary (pstate , jbv , jbcont ) \
557
+ pushJsonbElemGeneric(Binary, pstate, jbv, jbcont)
558
+
559
+ #define pushJsonbKeyValueGeneric (Type , pstate , jbv , key , val ) ( \
560
+ pushJsonbKey(pstate, jbv, key), \
561
+ pushJsonbValueGeneric(Type, pstate, jbv, val) \
562
+ )
563
+
564
+ #define pushJsonbKeyValueString (pstate , jbv , key , val ) \
565
+ pushJsonbKeyValueGeneric(String, pstate, jbv, key, val)
566
+
567
+ #define pushJsonbKeyValueFloat (pstate , jbv , key , val ) \
568
+ pushJsonbKeyValueGeneric(Float, pstate, jbv, key, val)
569
+
570
+ #define pushJsonbKeyValueInteger (pstate , jbv , key , val ) \
571
+ pushJsonbKeyValueGeneric(Integer, pstate, jbv, key, val)
572
+
415
573
#endif /* __JSONB_H__ */
0 commit comments