Skip to content

Commit c30f001

Browse files
author
Nikita Glukhov
committed
Add variable-length JsonContainer data
1 parent 3874abf commit c30f001

File tree

4 files changed

+37
-23
lines changed

4 files changed

+37
-23
lines changed

src/backend/utils/adt/json_generic.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ JsonInit(Json *json)
7777
const void *data = DatumGetPointer(json->obj.value);
7878
struct varlena *detoasted_data;
7979

80-
Assert(json->root.data || data);
80+
Assert(JsonContainerDataPtr(&json->root) || data);
8181

82-
if (json->root.data || !data)
82+
if (JsonContainerDataPtr(&json->root) || !data) /* FIXME */
8383
return;
8484

8585
detoasted_data = PG_DETOAST_DATUM(json->obj.value);
@@ -92,18 +92,19 @@ JsonInit(Json *json)
9292
static Json *
9393
JsonExpand(Json *tmp, Datum value, bool freeValue, JsonContainerOps *ops)
9494
{
95-
Json *json = tmp ? tmp : (Json *) palloc(sizeof(Json));
95+
Json *json = tmp ? tmp : (Json *) palloc(JsonAllocSize(ops->data_size));
9696

9797
json->obj.value = value;
9898
json->obj.freeValue = freeValue;
9999
json->obj.isTemporary = tmp != NULL;
100-
json->root.data = NULL;
101100
json->root.len = 0;
102101
json->root.ops = ops;
103102
json->root.size = -1;
104103
json->root.type = jbvBinary;
105104
json->is_json = false;
106105

106+
memset(json->root._data, 0, ops->data_size);
107+
107108
return json;
108109
}
109110

@@ -148,6 +149,8 @@ JsonValueToJson(JsonValue *val)
148149
jc->ops);
149150

150151
json->root = *jc;
152+
memcpy(json->root._data, jc->_data, jc->ops->data_size);
153+
151154
return json;
152155
}
153156
else
@@ -161,11 +164,11 @@ JsonValueToJson(JsonValue *val)
161164
JsonContainer *
162165
JsonCopyFlat(JsonContainer *jc)
163166
{
164-
JsonContainerData *res = JsonContainerAlloc();
167+
JsonContainerData *res = JsonContainerAlloc(jc->ops);
165168

166169
*res = *jc;
167-
res->data = palloc(jc->len);
168-
memcpy(res->data, jc->data, jc->len);
170+
JsonContainerDataPtr(res) = palloc(jc->len);
171+
memcpy(JsonContainerDataPtr(res), JsonContainerDataPtr(jc), jc->len);
169172

170173
return res;
171174
}

src/backend/utils/adt/jsonb_util.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ JsonContainerFlatten(JsonContainer *jc, JsonValueEncoder encoder,
123123

124124
if (jc->ops == ops)
125125
{
126-
int size = jc->len;
127-
void *out = palloc(VARHDRSZ + size);
126+
int size = jc->len;
127+
void *out = palloc(VARHDRSZ + size);
128+
128129
SET_VARSIZE(out, VARHDRSZ + size);
129-
memcpy(VARDATA(out), jc->data, size);
130+
memcpy(VARDATA(out), JsonContainerDataPtr(jc), size);
131+
130132
return out;
131133
}
132134

@@ -429,7 +431,7 @@ JsonbArrayIteratorGetIth(JsonbArrayIterator *it, uint32 i)
429431
static JsonbValue *
430432
jsonbFindValueInArray(JsonContainer *jsc, const JsonbValue *key)
431433
{
432-
const JsonbContainerHeader *container = jsc->data;
434+
const JsonbContainerHeader *container = JsonContainerDataPtr(jsc);
433435
JsonbArrayIterator it;
434436
JsonbValue *result = palloc(sizeof(JsonbValue));
435437

@@ -508,7 +510,7 @@ static JsonbValue *
508510
jsonbFindKeyInObject(JsonContainer *jsc, const char *keyVal, int keyLen,
509511
JsonValue *res)
510512
{
511-
const JsonbContainerHeader *container = jsc->data;
513+
const JsonbContainerHeader *container = JsonContainerDataPtr(jsc);
512514
const JEntry *children = container->children;
513515
int count = JsonContainerSize(jsc);
514516
char *baseAddr;
@@ -583,7 +585,7 @@ jsonbGetArrayElement(JsonContainer *jsc, uint32 i)
583585
if (!JsonContainerIsArray(jsc))
584586
elog(ERROR, "not a jsonb array");
585587

586-
JsonbArrayIteratorInit(&it, jsc->data);
588+
JsonbArrayIteratorInit(&it, JsonContainerDataPtr(jsc));
587589

588590
return JsonbArrayIteratorGetIth(&it, i);
589591
}
@@ -637,7 +639,7 @@ fillJsonbValue(const JsonbContainerHeader *container, int index,
637639
{
638640
Assert(JBE_ISCONTAINER(entry));
639641
result->type = jbvBinary;
640-
result->val.binary.data = JsonContainerAlloc();
642+
result->val.binary.data = JsonContainerAlloc(&jsonbContainerOps);
641643
jsonbInitContainer((JsonContainerData *) result->val.binary.data,
642644
/* Remove alignment padding from data pointer and length */
643645
(JsonbContainerHeader *)(base_addr + INTALIGN(offset)),
@@ -1199,7 +1201,7 @@ iteratorFromContainer(JsonContainer *container, jsonbIterator *parent)
11991201
static JsonIterator *
12001202
jsonbIteratorInit(JsonContainer *cont)
12011203
{
1202-
const JsonbContainerHeader *container = cont->data;
1204+
const JsonbContainerHeader *container = JsonContainerDataPtr(cont);
12031205
jsonbIterator *it;
12041206

12051207
it = palloc0(sizeof(jsonbIterator));
@@ -2069,7 +2071,7 @@ convertJsonbBinary(StringInfo buffer, JEntry *pheader, const JsonbValue *val,
20692071
{
20702072
int base_offset = buffer->len;
20712073
padBufferToInt(buffer);
2072-
appendToBuffer(buffer, jc->data, jc->len);
2074+
appendToBuffer(buffer, JsonContainerDataPtr(jc), jc->len);
20732075
*pheader = JENTRY_ISCONTAINER | (buffer->len - base_offset);
20742076
}
20752077
else
@@ -2201,12 +2203,11 @@ uniqueifyJsonbObject(JsonbValue *object, bool unique_keys, bool skip_nulls)
22012203
}
22022204
}
22032205

2204-
22052206
static void
22062207
jsonbInitContainer(JsonContainerData *jc, JsonbContainerHeader *jbc, int len)
22072208
{
22082209
jc->ops = &jsonbContainerOps;
2209-
jc->data = jbc;
2210+
JsonContainerDataPtr(jc) = jbc;
22102211
jc->len = len;
22112212
jc->size = jbc->header & JBC_CMASK;
22122213
jc->type = jbc->header & JBC_FOBJECT ? jbvObject :
@@ -2224,6 +2225,7 @@ jsonbInit(JsonContainerData *jc, Datum value)
22242225
JsonContainerOps
22252226
jsonbContainerOps =
22262227
{
2228+
sizeof(JsonbContainerHeader *),
22272229
jsonbInit,
22282230
jsonbIteratorInit,
22292231
jsonbFindKeyInObject,

src/backend/utils/adt/jsonpath_exec.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2049,7 +2049,8 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp,
20492049

20502050
/* construct object id from its base object and offset inside that */
20512051
id = jb->type != jbvBinary ? 0 :
2052-
(int64) ((char *) jbc->data - (char *) cxt->baseObject.jbc->data); /* FIXME */
2052+
(int64) ((char *) JsonContainerDataPtr(jbc) -
2053+
(char *) JsonContainerDataPtr(cxt->baseObject.jbc)); /* FIXME */
20532054
id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
20542055

20552056
idval.type = jbvNumeric;

src/include/utils/json_generic.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ typedef struct JsonContainerOps JsonContainerOps;
2626
typedef struct JsonContainerData
2727
{
2828
JsonContainerOps *ops;
29-
void *data;
3029
int len;
3130
int size;
3231
JsonbValueType type;
32+
void *_data[FLEXIBLE_ARRAY_MEMBER];
3333
} JsonContainerData;
3434

3535
typedef const JsonContainerData JsonContainer;
@@ -49,6 +49,7 @@ struct JsonIteratorData
4949

5050
struct JsonContainerOps
5151
{
52+
int data_size;
5253
void (*init)(JsonContainerData *jc, Datum value);
5354
JsonIterator *(*iteratorInit)(JsonContainer *jc);
5455
JsonValue *(*findKeyInObject)(JsonContainer *object,
@@ -73,13 +74,14 @@ typedef struct CompressedObject
7374
typedef struct Json
7475
{
7576
CompressedObject obj;
76-
JsonContainerData root;
7777
bool is_json; /* json or jsonb */
78+
JsonContainerData root;
7879
} Json;
7980

8081
typedef Json Jsonb;
8182
typedef JsonContainer JsonbContainer;
8283

84+
#define JsonContainerDataPtr(jc) ((jc)->_data[0])
8385

8486
#define JsonIsTemporary(json) ((json)->obj.isTemporary)
8587

@@ -189,8 +191,14 @@ extern Json *DatumGetJson(Datum val, JsonContainerOps *ops, Json *tmp);
189191
extern void JsonFree(Json *json);
190192
extern Json *JsonCopyTemporary(Json *tmp);
191193

192-
#define JsonContainerAlloc() \
193-
((JsonContainerData *) palloc(sizeof(JsonContainerData)))
194+
#define JsonAllocSize(data_size) \
195+
(offsetof(Json, root._data) + (data_size))
196+
197+
#define JsonContainerAllocSize(data_size) \
198+
(offsetof(JsonContainerData, _data) + (data_size))
199+
200+
#define JsonContainerAlloc(ops) \
201+
((JsonContainerData *) palloc(JsonContainerAllocSize((ops)->data_size)))
194202

195203
extern JsonValue *JsonFindValueInContainer(JsonContainer *json, uint32 flags,
196204
JsonValue *key);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy