Skip to content

Commit 876bb2e

Browse files
author
Nikita Glukhov
committed
Part of "In-place jsonb updates"
1 parent c54f7a1 commit 876bb2e

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

contrib/jsonb_toaster/jsonb_toaster.c

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static JsonbValue *fillCompressedJsonbValue(CompressedJsonb *cjb,
177177
uint32 offset, JsonValue *result);
178178
static JsonbContainerHeader *jsonxzDecompress(JsonContainer *jc);
179179
static bool JsonContainerIsToasted(JsonContainer *jc,
180-
JsonbToastedContainerPointer *jbcptr);
180+
JsonbToastedContainerPointerData *jbcptr);
181181
static bool JsonValueContainsToasted(const JsonValue *jv);
182182

183183
static bool jsonb_toast_fields = true; /* GUC */
@@ -187,12 +187,12 @@ static JsonContainerOps jsonxContainerOps;
187187
static JsonContainerOps jsonxzContainerOps;
188188

189189
static struct varlena *
190-
jsonxMakeToastPointer(struct varatt_external *ptr)
190+
jsonxMakeToastPointer(JsonbToastedContainerPointerData *ptr)
191191
{
192192
struct varlena *toast_ptr = palloc(TOAST_POINTER_SIZE);
193193

194194
SET_VARTAG_EXTERNAL(toast_ptr, VARTAG_ONDISK);
195-
memcpy(VARDATA_EXTERNAL(toast_ptr), ptr, sizeof(*ptr));
195+
memcpy(VARDATA_EXTERNAL(toast_ptr), &ptr->ptr, sizeof(ptr->ptr));
196196

197197
return toast_ptr;
198198
}
@@ -501,11 +501,14 @@ jsonxFillValue(const JsonbContainerHeader *container, int index,
501501
else if (JBE_ISCONTAINER_PTR(entry))
502502
{
503503
JsonbToastedContainerPointer *jbcptr = (JsonbToastedContainerPointer *)(base_addr + INTALIGN(offset));
504-
struct varlena *toast_ptr = jsonxMakeToastPointer(&jbcptr->ptr);
504+
JsonbToastedContainerPointerData jbcptr_data;
505+
struct varlena *toast_ptr;
505506
bool is_jsonx = (jbcptr->header & JBC_TOBJECT_TOASTED) != 0;
506507
JsonContainerData *cont =
507508
JsonContainerAlloc(is_jsonx ? &jsonxzContainerOps : &jsonbzContainerOps);
508509

510+
jbcptr_data.ptr = jbcptr->ptr;
511+
toast_ptr = jsonxMakeToastPointer(&jbcptr_data);
509512
jsonxzInitWithHeader(cont, PointerGetDatum(toast_ptr), &jbcptr->header);
510513
JsonValueInitBinary(result, cont);
511514

@@ -1010,19 +1013,21 @@ estimateJsonbValueSize(const JsonbValue *jbv)
10101013
}
10111014

10121015
static void
1013-
jsonxInitToastedContainerPointer(JsonbToastedContainerPointer *jbcptr,
1014-
JsonContainer *jc,
1015-
struct varatt_external *toast_ptr)
1016+
jsonxInitToastedContainerPointer(JsonbToastedContainerPointerData *jbcptr,
1017+
varatt_external *toast_ptr,
1018+
uint32 container_offset)
10161019
{
1020+
/*
10171021
jbcptr->header =
10181022
(JsonContainerIsArray(jc) ? JBC_TARRAY : JBC_TOBJECT) |
10191023
(jc->ops == &jsonxzContainerOps ? JBC_TOBJECT_TOASTED : 0) |
1020-
JsonContainerSize(jc);
1024+
JsonContainerSize(jc);*/
10211025
jbcptr->ptr = *toast_ptr;
1026+
jbcptr->container_offset = container_offset;
10221027
}
10231028

10241029
static bool
1025-
JsonContainerIsToasted(JsonContainer *jc, JsonbToastedContainerPointer *jbcptr)
1030+
JsonContainerIsToasted(JsonContainer *jc, JsonbToastedContainerPointerData *jbcptr)
10261031
{
10271032
if (jc->ops == &jsonbzContainerOps ||
10281033
jc->ops == &jsonxzContainerOps)
@@ -1034,8 +1039,9 @@ JsonContainerIsToasted(JsonContainer *jc, JsonbToastedContainerPointer *jbcptr)
10341039
cjb->offset == offsetof(JsonbDatum, root))
10351040
{
10361041
if (jbcptr)
1037-
jsonxInitToastedContainerPointer(jbcptr, jc, &fetch_iter->toast_pointer);
1038-
1042+
jsonxInitToastedContainerPointer(jbcptr,
1043+
&fetch_iter->toast_pointer,
1044+
cjb->offset);
10391045
return true;
10401046
}
10411047
}
@@ -1397,12 +1403,12 @@ convertJsonbBinary(StringInfo buffer, JEntry *pheader, const JsonbValue *val,
13971403

13981404
if (jsonb_toast_fields)
13991405
{
1400-
JsonbToastedContainerPointer jbcptr;
1406+
JsonbToastedContainerPointerData jbcptr;
14011407

14021408
if (JsonContainerIsToasted(jc, &jbcptr))
14031409
{
14041410
padBufferToInt(buffer);
1405-
appendToBuffer(buffer, (void *) &jbcptr, sizeof(jbcptr));
1411+
appendToBuffer(buffer, (void *) &jbcptr.ptr, sizeof(jbcptr.ptr));
14061412
*pheader = JENTRY_ISCONTAINER_PTR | (buffer->len - base_offset);
14071413
return;
14081414
}
@@ -1851,6 +1857,28 @@ jsonxContainerOps =
18511857
jsonxEncode
18521858
};
18531859

1860+
static JsonContainer *
1861+
jsonxzInitContainerFromDatum(JsonContainer *jc, Datum toasted_val)
1862+
{
1863+
JsonContainerData *tjc;
1864+
JsonbContainerHeader header;
1865+
bool is_jsonx;
1866+
1867+
Assert(VARATT_IS_EXTERNAL_ONDISK(toasted_val));
1868+
1869+
is_jsonx = jc->ops == &jsonxContainerOps || jc->ops == &jsonxzContainerOps;
1870+
1871+
header =
1872+
(JsonContainerIsArray(jc) ? JBC_TARRAY : JBC_TOBJECT) |
1873+
(is_jsonx ? JBC_TOBJECT_TOASTED : 0) |
1874+
JsonContainerSize(jc);
1875+
1876+
tjc = JsonContainerAlloc(is_jsonx ? &jsonxzContainerOps : &jsonbzContainerOps); /* FIXME optimize */
1877+
jsonxzInitWithHeader(tjc, toasted_val, &header);
1878+
1879+
return tjc;
1880+
}
1881+
18541882
static bool
18551883
jsonb_toaster_save_object(Relation rel, JsonContainer *root,
18561884
/* XXX bool uniquified, */ Size max_size, char cmethod,
@@ -1959,10 +1987,7 @@ jsonb_toaster_save_object(Relation rel, JsonContainer *root,
19591987
Datum compressed_val;
19601988
Datum toasted_val;
19611989
JsonContainer *jc;
1962-
JsonContainerData *tjc;
19631990
JsonbContainerHeader *jbc;
1964-
JsonbContainerHdr header;
1965-
bool is_jsonx;
19661991

19671992
for (i = 0; i < nkeys; i++)
19681993
{
@@ -2011,20 +2036,7 @@ jsonb_toaster_save_object(Relation rel, JsonContainer *root,
20112036
if (DatumGetPointer(compressed_val))
20122037
pfree(DatumGetPointer(compressed_val));
20132038

2014-
Assert(VARATT_IS_EXTERNAL_ONDISK(toasted_val));
2015-
2016-
is_jsonx = jc->ops == &jsonxContainerOps || jc->ops == &jsonxzContainerOps;
2017-
2018-
header =
2019-
(JsonContainerIsArray(jc) ? JBC_TARRAY : JBC_TOBJECT) |
2020-
(is_jsonx ? JBC_TOBJECT_TOASTED : 0) |
2021-
JsonContainerSize(jc);
2022-
2023-
tjc = JsonContainerAlloc(is_jsonx ? &jsonxzContainerOps : &jsonbzContainerOps); /* FIXME optimize */
2024-
jsonxzInitWithHeader(tjc, toasted_val, &header);
2025-
2026-
pairs[max_key_idx].value.val.binary.data = tjc;
2027-
2039+
pairs[max_key_idx].value.val.binary.data = jsonxzInitContainerFromDatum(jc, toasted_val);
20282040
sizes[max_key_idx] = sizeof(JsonbToastedContainerPointer);
20292041
total_size += INTALIGN(sizes[max_key_idx] + 3);
20302042
}
@@ -2220,11 +2232,11 @@ jsonb_toaster_copy(Relation rel, JsonContainer *jc, char cmethod)
22202232
static void
22212233
jsonb_toaster_delete_container(Relation rel, JsonContainer *jc)
22222234
{
2223-
JsonbToastedContainerPointer jbcptr;
2235+
JsonbToastedContainerPointerData jbcptr;
22242236

22252237
if (JsonContainerIsToasted(jc, &jbcptr))
22262238
{
2227-
struct varlena *ptr = jsonxMakeToastPointer(&jbcptr.ptr);
2239+
struct varlena *ptr = jsonxMakeToastPointer(&jbcptr);
22282240

22292241
toast_delete_datum(PointerGetDatum(ptr), false);
22302242
pfree(ptr);
@@ -2265,8 +2277,8 @@ jsonb_toaster_delete_recursive(Relation rel, JsonContainer *jc, bool delete_self
22652277
static bool
22662278
jsonb_toaster_cmp_recursive(Relation rel, JsonContainer *old_jc, JsonContainer *new_jc, char cmethod)
22672279
{
2268-
JsonbToastedContainerPointer new_jbcptr;
2269-
JsonbToastedContainerPointer old_jbcptr;
2280+
JsonbToastedContainerPointerData new_jbcptr;
2281+
JsonbToastedContainerPointerData old_jbcptr;
22702282
JsonIterator *old_it;
22712283
JsonIterator *new_it;
22722284
JsonValue old_jbv;
@@ -2312,7 +2324,7 @@ jsonb_toaster_cmp_recursive(Relation rel, JsonContainer *old_jc, JsonContainer *
23122324
if (JsonContainerIsToasted(newjc, &new_jbcptr))
23132325
{
23142326
if (!JsonContainerIsToasted(oldjc, &old_jbcptr) ||
2315-
memcmp(&new_jbcptr, &old_jbcptr, sizeof(new_jbcptr)))
2327+
memcmp(&new_jbcptr.ptr, &old_jbcptr.ptr, sizeof(new_jbcptr.ptr)))
23162328
{
23172329
changed |= jsonb_toaster_replace_toasted(rel, &new_jbv, (jsonbIterator *) new_it, offset, cmethod);
23182330
jsonb_toaster_delete_recursive(rel, oldjc, true);
@@ -2379,8 +2391,8 @@ jsonb_toaster_cmp_recursive(Relation rel, JsonContainer *old_jc, JsonContainer *
23792391
static Datum
23802392
jsonb_toaster_cmp(Relation rel, JsonContainer *new_jc, JsonContainer *old_jc, char cmethod)
23812393
{
2382-
JsonbToastedContainerPointer new_jbcptr;
2383-
JsonbToastedContainerPointer old_jbcptr;
2394+
JsonbToastedContainerPointerData new_jbcptr;
2395+
JsonbToastedContainerPointerData old_jbcptr;
23842396
Datum res;
23852397
void *jb;
23862398
JsonbContainerHeader *new_jbc;
@@ -2389,7 +2401,7 @@ jsonb_toaster_cmp(Relation rel, JsonContainer *new_jc, JsonContainer *old_jc, ch
23892401
if (JsonContainerIsToasted(new_jc, &new_jbcptr))
23902402
{
23912403
if (JsonContainerIsToasted(old_jc, &old_jbcptr) &&
2392-
!memcmp(&new_jbcptr, &old_jbcptr, sizeof(new_jbcptr)))
2404+
!memcmp(&new_jbcptr.ptr, &old_jbcptr.ptr, sizeof(new_jbcptr.ptr)))
23932405
return (Datum) 0;
23942406

23952407
res = jsonb_toaster_copy(rel, new_jc, cmethod);

0 commit comments

Comments
 (0)