Skip to content

Commit ea7c205

Browse files
author
Nikita Glukhov
committed
Add support for extended compressed attributes
1 parent aab623a commit ea7c205

File tree

4 files changed

+115
-30
lines changed

4 files changed

+115
-30
lines changed

src/backend/access/brin/brin_tuple.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
175175
/* Assert that hoff fits in the space available */
176176
Assert((rettuple->bt_info & BRIN_OFFSET_MASK) == hoff);
177177

178+
/* FIXME compressed/extended attributes */
178179
/*
179180
* The infomask and null bitmap as computed by heap_fill_tuple are useless
180181
* to us. However, that function will not accept a null infomask; and we

src/backend/access/common/heaptuple.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ heap_fill_tuple(TupleDesc tupleDesc,
229229
att[i]->attalign);
230230
data_length = EOH_get_flat_size(eoh);
231231
EOH_flatten_into(eoh, data, data_length);
232+
if (VARATT_IS_EXTERNAL(data))
233+
*infomask |= HEAP_HASEXTERNAL;
232234
}
233235
else
234236
{
@@ -747,8 +749,12 @@ heap_form_tuple(TupleDesc tupleDescriptor,
747749
if (!tupleDescriptor->tdcmroutines)
748750
break;
749751
}
750-
else if (/* XXX compress && */
751-
OidIsValid(tupleDescriptor->attrs[i]->attcompression))
752+
else if ((OidIsValid(tupleDescriptor->attrs[i]->attcompression) ||
753+
(tupleDescriptor->attrs[i]->attlen == -1 &&
754+
OidIsValid(tupleDescriptor->attrs[i]->attrelid) &&
755+
tupleDescriptor->tdcmroutines &&
756+
tupleDescriptor->tdcmroutines[i] &&
757+
VARATT_IS_EXTERNAL(DatumGetPointer(values[i])))))
752758
{
753759
if (!oldValues)
754760
{

src/backend/access/common/indextuple.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,23 @@ index_form_tuple(TupleDesc tupleDescriptor,
8181
untoasted_values[i] =
8282
PointerGetDatum(heap_tuple_fetch_attr((struct varlena *)
8383
DatumGetPointer(values[i])));
84-
untoasted_free[i] = true;
84+
85+
if (untoasted_values[i] != values[i])
86+
untoasted_free[i] = true;
87+
88+
if (VARATT_IS_EXTERNAL_EXTENDED(DatumGetPointer(values[i])))
89+
{
90+
untoasted_values[i] = PointerGetDatum(
91+
tuple_compress_attr(tupleDescriptor, i, values[i]));
92+
93+
Assert(untoasted_values[i] != values[i]);
94+
95+
if (untoasted_values[i] != values[i])
96+
{
97+
untoasted_free[i] = true;
98+
Assert(!VARATT_IS_EXTERNAL(untoasted_values[i]));
99+
}
100+
}
85101
}
86102

87103
/*

src/backend/access/heap/tuptoaster.c

Lines changed: 89 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,11 @@ heap_tuple_untoast_attr(struct varlena * attr)
220220
*/
221221
attr = heap_tuple_fetch_attr(attr);
222222
/* flatteners are not allowed to produce compressed/short output */
223-
Assert(!VARATT_IS_EXTENDED(attr));
223+
Assert(!VARATT_IS_EXTENDED(attr) || VARATT_IS_EXTERNAL_EXTENDED(attr));
224+
}
225+
else if (VARATT_IS_EXTERNAL_EXTENDED(attr))
226+
{
227+
/* This is an extended datum --- return it */
224228
}
225229
else if (VARATT_IS_COMPRESSED(attr))
226230
{
@@ -439,6 +443,10 @@ toast_datum_size(Datum value)
439443
{
440444
result = EOH_get_flat_size(DatumGetEOHP(value));
441445
}
446+
else if (VARATT_IS_EXTERNAL_EXTENDED(attr))
447+
{
448+
result = VARSIZE_ANY(attr);
449+
}
442450
else if (VARATT_IS_SHORT(attr))
443451
{
444452
result = VARSIZE_SHORT(attr);
@@ -672,6 +680,8 @@ toast_insert_or_update(Relation rel, TupleDesc newtupdesc, HeapTuple newtup,
672680
*/
673681
if (att[i]->attlen == -1)
674682
{
683+
bool need_compress = false;
684+
675685
/*
676686
* If the table's attribute says PLAIN always, force it so.
677687
*/
@@ -688,37 +698,65 @@ toast_insert_or_update(Relation rel, TupleDesc newtupdesc, HeapTuple newtup,
688698
*/
689699
if (VARATT_IS_EXTERNAL(new_value))
690700
{
691-
toast_oldexternal[i] = new_value;
692-
if (att[i]->attstorage == 'p')
693-
new_value = heap_tuple_untoast_attr(new_value);
701+
if (VARATT_IS_EXTERNAL_EXPANDED(new_value))
702+
{
703+
Assert(recompress[i]);
704+
need_compress = true;
705+
}
694706
else
695-
new_value = heap_tuple_fetch_attr(new_value);
696-
toast_values[i] = PointerGetDatum(new_value);
697-
toast_free[i] = true;
698-
need_change = true;
699-
need_free = true;
700-
}
701-
702-
if (recompress[i])
703-
{
704-
if (OidIsValid(att[i]->attcompression))
705707
{
706-
struct varlena * compressed_value = (struct varlena *)
707-
tuple_compress_attr(tupleDesc, i,
708-
PointerGetDatum(new_value));
709-
if (compressed_value != new_value)
708+
struct varlena *untoasted_value =
709+
att[i]->attstorage == 'p'
710+
? heap_tuple_untoast_attr(new_value)
711+
: heap_tuple_fetch_attr(new_value);
712+
713+
if (untoasted_value != new_value)
710714
{
711-
new_value = compressed_value;
712-
toast_oldexternal[i] = NULL;
713-
if (toast_free[i])
714-
pfree(DatumGetPointer(toast_values[i]));
715+
toast_oldexternal[i] = new_value;
716+
new_value = untoasted_value;
715717
toast_values[i] = PointerGetDatum(new_value);
716718
toast_free[i] = true;
719+
need_change = true;
717720
need_free = true;
718-
Assert(!VARATT_IS_EXTERNAL(new_value));
721+
}
722+
723+
if (VARATT_IS_EXTERNAL_EXTENDED(new_value))
724+
{
725+
Assert(recompress[i] ||
726+
!OidIsValid(newtupdesc->attrs[i]->attrelid));
727+
728+
if (!recompress[i] || !OidIsValid(att[i]->attcompression))
729+
need_compress = true;
719730
}
720731
}
721-
need_change = true;
732+
}
733+
734+
if (recompress[i])
735+
{
736+
if (OidIsValid(att[i]->attcompression))
737+
need_compress = true;
738+
else
739+
need_change = true;
740+
}
741+
742+
if (need_compress)
743+
{
744+
struct varlena *compressed_value = (struct varlena *)
745+
tuple_compress_attr(tupleDesc, i,
746+
PointerGetDatum(new_value));
747+
748+
if (compressed_value != new_value)
749+
{
750+
new_value = compressed_value;
751+
toast_oldexternal[i] = NULL;
752+
if (toast_free[i])
753+
pfree(DatumGetPointer(toast_values[i]));
754+
toast_values[i] = PointerGetDatum(new_value);
755+
toast_free[i] = true;
756+
need_free = true;
757+
need_change = true;
758+
Assert(!VARATT_IS_EXTERNAL(new_value));
759+
}
722760
}
723761

724762
/*
@@ -1254,9 +1292,33 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
12541292
if (VARATT_IS_EXTERNAL(new_value) ||
12551293
VARATT_IS_COMPRESSED(new_value))
12561294
{
1257-
new_value = heap_tuple_untoast_attr(new_value);
1258-
toast_values[i] = PointerGetDatum(new_value);
1259-
toast_free[i] = true;
1295+
struct varlena *untoasted_value =
1296+
heap_tuple_untoast_attr(new_value);
1297+
if (untoasted_value != new_value)
1298+
{
1299+
new_value = untoasted_value;
1300+
toast_values[i] = PointerGetDatum(new_value);
1301+
toast_free[i] = true;
1302+
}
1303+
}
1304+
1305+
if (OidIsValid(att[i]->attcompression) ||
1306+
(att[i]->attlen == -1 &&
1307+
OidIsValid(att[i]->attrelid) &&
1308+
VARATT_IS_EXTERNAL_EXTENDED(DatumGetPointer(new_value))))
1309+
{
1310+
void *compressed_value = DatumGetPointer(
1311+
tuple_compress_attr(tupleDesc, i,
1312+
PointerGetDatum(new_value)));
1313+
1314+
if (compressed_value != new_value)
1315+
{
1316+
if (toast_free[i])
1317+
pfree(DatumGetPointer(toast_values[i]));
1318+
new_value = compressed_value;
1319+
toast_values[i] = PointerGetDatum(new_value);
1320+
toast_free[i] = true;
1321+
}
12601322
}
12611323
}
12621324
}

0 commit comments

Comments
 (0)