mirror of
https://github.com/postgres/postgres.git
synced 2025-06-20 15:22:23 +03:00
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
This commit is contained in:
@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
#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
|
|||||||
} 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
|
||||||
@ -241,7 +247,7 @@ enum jbvType
|
|||||||
*/
|
*/
|
||||||
struct JsonbValue
|
struct JsonbValue
|
||||||
{
|
{
|
||||||
enum jbvType type; /* Influences sort order */
|
enum jbvType type; /* Influences sort order */
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user