Commit f7c62462 authored by Tom Lane's avatar Tom Lane

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
parent 049ac809
...@@ -328,7 +328,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, ...@@ -328,7 +328,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
JsonbValue *key) JsonbValue *key)
{ {
JEntry *children = container->children; JEntry *children = container->children;
int count = (container->header & JB_CMASK); int count = JsonContainerSize(container);
JsonbValue *result; JsonbValue *result;
Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0); Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
...@@ -339,7 +339,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, ...@@ -339,7 +339,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
result = palloc(sizeof(JsonbValue)); result = palloc(sizeof(JsonbValue));
if (flags & JB_FARRAY & container->header) if ((flags & JB_FARRAY) && JsonContainerIsArray(container))
{ {
char *base_addr = (char *) (children + count); char *base_addr = (char *) (children + count);
uint32 offset = 0; uint32 offset = 0;
...@@ -358,7 +358,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, ...@@ -358,7 +358,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
JBE_ADVANCE_OFFSET(offset, children[i]); 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 */ /* Since this is an object, account for *Pairs* of Jentrys */
char *base_addr = (char *) (children + count * 2); char *base_addr = (char *) (children + count * 2);
...@@ -422,10 +422,10 @@ getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i) ...@@ -422,10 +422,10 @@ getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
char *base_addr; char *base_addr;
uint32 nelements; uint32 nelements;
if ((container->header & JB_FARRAY) == 0) if (!JsonContainerIsArray(container))
elog(ERROR, "not a jsonb array"); elog(ERROR, "not a jsonb array");
nelements = container->header & JB_CMASK; nelements = JsonContainerSize(container);
base_addr = (char *) &container->children[nelements]; base_addr = (char *) &container->children[nelements];
if (i >= nelements) if (i >= nelements)
...@@ -904,7 +904,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent) ...@@ -904,7 +904,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
it = palloc(sizeof(JsonbIterator)); it = palloc(sizeof(JsonbIterator));
it->container = container; it->container = container;
it->parent = parent; it->parent = parent;
it->nElems = container->header & JB_CMASK; it->nElems = JsonContainerSize(container);
/* Array starts just after header */ /* Array starts just after header */
it->children = container->children; it->children = container->children;
...@@ -914,7 +914,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent) ...@@ -914,7 +914,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent)
case JB_FARRAY: case JB_FARRAY:
it->dataProper = it->dataProper =
(char *) it->children + it->nElems * sizeof(JEntry); (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 */ /* This is either a "raw scalar", or an array */
Assert(!it->isScalar || it->nElems == 1); Assert(!it->isScalar || it->nElems == 1);
......
...@@ -1266,10 +1266,10 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) ...@@ -1266,10 +1266,10 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
uint32 nelements; uint32 nelements;
/* Container must be array, but make sure */ /* Container must be array, but make sure */
if ((container->header & JB_FARRAY) == 0) if (!JsonContainerIsArray(container))
elog(ERROR, "not a jsonb array"); elog(ERROR, "not a jsonb array");
nelements = container->header & JB_CMASK; nelements = JsonContainerSize(container);
if (-lindex > nelements) if (-lindex > nelements)
PG_RETURN_NULL(); PG_RETURN_NULL();
......
...@@ -205,6 +205,12 @@ typedef struct JsonbContainer ...@@ -205,6 +205,12 @@ typedef struct JsonbContainer
#define JB_FOBJECT 0x20000000 #define JB_FOBJECT 0x20000000
#define JB_FARRAY 0x40000000 #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. */ /* The top-level on-disk format for a jsonb datum. */
typedef struct typedef struct
{ {
...@@ -213,10 +219,10 @@ typedef struct ...@@ -213,10 +219,10 @@ typedef struct
} Jsonb; } Jsonb;
/* convenience macros for accessing the root container in a Jsonb datum */ /* convenience macros for accessing the root container in a Jsonb datum */
#define JB_ROOT_COUNT(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_CMASK) #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_SCALAR(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FSCALAR) != 0)
#define JB_ROOT_IS_OBJECT(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FOBJECT) #define JB_ROOT_IS_OBJECT(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FOBJECT) != 0)
#define JB_ROOT_IS_ARRAY(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FARRAY) #define JB_ROOT_IS_ARRAY(jbp_) ((*(uint32 *) VARDATA(jbp_) & JB_FARRAY) != 0)
enum jbvType enum jbvType
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment