aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-01-25 13:28:38 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2017-01-25 13:28:38 -0500
commitf7c62462402972b13d10e43f104ca0c0fecb6d08 (patch)
tree6bf90792ec1a9ada9a5f0ca2f670d36c37260f77
parent049ac809a790a9bde478e371da2b68d6b18c5df7 (diff)
downloadpostgresql-f7c62462402972b13d10e43f104ca0c0fecb6d08.tar.gz
postgresql-f7c62462402972b13d10e43f104ca0c0fecb6d08.zip
Introduce convenience macros to hide JsonbContainer header accesses better.
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
-rw-r--r--src/backend/utils/adt/jsonb_util.c14
-rw-r--r--src/backend/utils/adt/jsonfuncs.c4
-rw-r--r--src/include/utils/jsonb.h16
3 files changed, 20 insertions, 14 deletions
diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c
index 11a13950383..0d2abb35b96 100644
--- a/src/backend/utils/adt/jsonb_util.c
+++ b/src/backend/utils/adt/jsonb_util.c
@@ -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);
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index a75df62d2a0..6a7aab2f432 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -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();
diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h
index e402b9e3a70..411e158d6c1 100644
--- a/src/include/utils/jsonb.h
+++ b/src/include/utils/jsonb.h
@@ -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
{