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)
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