]> granicus.if.org Git - postgresql/commitdiff
Introduce convenience macros to hide JsonbContainer header accesses better.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 25 Jan 2017 18:28:38 +0000 (13:28 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 25 Jan 2017 18:28:38 +0000 (13:28 -0500)
This improves readability a bit and may make future improvements easier.

In passing, make sure that the JB_ROOT_IS_XXX macros deliver boolean (0/1)
results; the previous coding was a bug hazard, though no actual bugs are
known.

Nikita Glukhov, extended a bit by me

Discussion: https://postgr.es/m/9e21a39c-c1d7-b9b5-44a0-c5345a5029f6@postgrespro.ru

src/backend/utils/adt/jsonb_util.c
src/backend/utils/adt/jsonfuncs.c
src/include/utils/jsonb.h

index 11a139503836e534ae8a3700e9443e138e44c30c..0d2abb35b96afcbc5a85946f341a5667e98fad36 100644 (file)
@@ -328,7 +328,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
                                                        JsonbValue *key)
 {
        JEntry     *children = container->children;
-       int                     count = (container->header & JB_CMASK);
+       int                     count = JsonContainerSize(container);
        JsonbValue *result;
 
        Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
@@ -339,7 +339,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
 
        result = palloc(sizeof(JsonbValue));
 
-       if (flags & JB_FARRAY & container->header)
+       if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
        {
                char       *base_addr = (char *) (children + count);
                uint32          offset = 0;
@@ -358,7 +358,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
                        JBE_ADVANCE_OFFSET(offset, children[i]);
                }
        }
-       else if (flags & JB_FOBJECT & container->header)
+       else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container))
        {
                /* Since this is an object, account for *Pairs* of Jentrys */
                char       *base_addr = (char *) (children + count * 2);
@@ -422,10 +422,10 @@ getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
        char       *base_addr;
        uint32          nelements;
 
-       if ((container->header & JB_FARRAY) == 0)
+       if (!JsonContainerIsArray(container))
                elog(ERROR, "not a jsonb array");
 
-       nelements = container->header & JB_CMASK;
+       nelements = JsonContainerSize(container);
        base_addr = (char *) &container->children[nelements];
 
        if (i >= nelements)
@@ -904,7 +904,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
        it = palloc(sizeof(JsonbIterator));
        it->container = container;
        it->parent = parent;
-       it->nElems = container->header & JB_CMASK;
+       it->nElems = JsonContainerSize(container);
 
        /* Array starts just after header */
        it->children = container->children;
@@ -914,7 +914,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
                case JB_FARRAY:
                        it->dataProper =
                                (char *) it->children + it->nElems * sizeof(JEntry);
-                       it->isScalar = (container->header & JB_FSCALAR) != 0;
+                       it->isScalar = JsonContainerIsScalar(container);
                        /* This is either a "raw scalar", or an array */
                        Assert(!it->isScalar || it->nElems == 1);
 
index a75df62d2a0d3f1caa1dd6ccc7b3b678c8579eb8..6a7aab2f432e44d70520f1725bb14463f94ac293 100644 (file)
@@ -1266,10 +1266,10 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
                                uint32          nelements;
 
                                /* Container must be array, but make sure */
-                               if ((container->header & JB_FARRAY) == 0)
+                               if (!JsonContainerIsArray(container))
                                        elog(ERROR, "not a jsonb array");
 
-                               nelements = container->header & JB_CMASK;
+                               nelements = JsonContainerSize(container);
 
                                if (-lindex > nelements)
                                        PG_RETURN_NULL();
index e402b9e3a703698d43710de2c04fe077cac0a597..411e158d6c13c4d01b9f15f4ed6d37830560bb13 100644 (file)
@@ -205,6 +205,12 @@ typedef struct JsonbContainer
 #define JB_FOBJECT                             0x20000000
 #define JB_FARRAY                              0x40000000
 
+/* convenience macros for accessing a JsonbContainer struct */
+#define JsonContainerSize(jc)          ((jc)->header & JB_CMASK)
+#define JsonContainerIsScalar(jc)      (((jc)->header & JB_FSCALAR) != 0)
+#define JsonContainerIsObject(jc)      (((jc)->header & JB_FOBJECT) != 0)
+#define JsonContainerIsArray(jc)       (((jc)->header & JB_FARRAY) != 0)
+
 /* The top-level on-disk format for a jsonb datum. */
 typedef struct
 {
@@ -213,10 +219,10 @@ typedef struct
 } Jsonb;
 
 /* convenience macros for accessing the root container in a Jsonb datum */
-#define JB_ROOT_COUNT(jbp_)            ( *(uint32*) VARDATA(jbp_) & JB_CMASK)
-#define JB_ROOT_IS_SCALAR(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FSCALAR)
-#define JB_ROOT_IS_OBJECT(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FOBJECT)
-#define JB_ROOT_IS_ARRAY(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FARRAY)
+#define JB_ROOT_COUNT(jbp_)            (*(uint32 *) VARDATA(jbp_) & JB_CMASK)
+#define JB_ROOT_IS_SCALAR(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FSCALAR) != 0)
+#define JB_ROOT_IS_OBJECT(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0)
+#define JB_ROOT_IS_ARRAY(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FARRAY) != 0)
 
 
 enum jbvType
@@ -241,7 +247,7 @@ enum jbvType
  */
 struct JsonbValue
 {
-       enum jbvType    type;                   /* Influences sort order */
+       enum jbvType type;                      /* Influences sort order */
 
        union
        {