Skip to content

Commit 9243837

Browse files
author
Nikita Glukhov
committed
Add compression options
1 parent 21428e4 commit 9243837

File tree

26 files changed

+726
-98
lines changed

26 files changed

+726
-98
lines changed

src/backend/access/common/heaptuple.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -683,30 +683,30 @@ heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
683683
return PointerGetDatum(td);
684684
}
685685

686-
static inline CompressionMethodRoutine *
687-
TupleDescGetCompressionMethodRoutine(TupleDesc tupdesc, AttrNumber attnum)
686+
static inline AttributeCompression *
687+
TupleDescGetAttributeCompression(TupleDesc tupdesc, AttrNumber attnum)
688688
{
689-
CompressionMethodRoutine *cmr;
690-
Assert(tupdesc->tdcmroutines);
691-
cmr = tupdesc->tdcmroutines[attnum];
692-
Assert(cmr);
693-
return cmr;
689+
AttributeCompression *compression;
690+
Assert(tupdesc->tdcompression);
691+
compression = &tupdesc->tdcompression[attnum];
692+
Assert(compression->routine);
693+
return compression;
694694
}
695695

696696
Datum
697697
tuple_compress_attr(TupleDesc tupdesc, AttrNumber attnum, Datum value)
698698
{
699-
CompressionMethodRoutine *cmr =
700-
TupleDescGetCompressionMethodRoutine(tupdesc, attnum);
701-
return (*cmr->compress)(value, tupdesc->attrs[attnum]);
699+
AttributeCompression *compression =
700+
TupleDescGetAttributeCompression(tupdesc, attnum);
701+
return compression->routine->compress(value, compression->options);
702702
}
703703

704704
Datum
705705
tuple_decompress_attr(TupleDesc tupdesc, int attnum, Datum value)
706706
{
707-
CompressionMethodRoutine *cmr =
708-
TupleDescGetCompressionMethodRoutine(tupdesc, attnum);
709-
return (*cmr->decompress)(value, tupdesc->attrs[attnum]);
707+
AttributeCompression *compression =
708+
TupleDescGetAttributeCompression(tupdesc, attnum);
709+
return compression->routine->decompress(value, compression->options);
710710
}
711711

712712
/*
@@ -746,14 +746,14 @@ heap_form_tuple(TupleDesc tupleDescriptor,
746746
{
747747
hasnull = true;
748748

749-
if (!tupleDescriptor->tdcmroutines)
749+
if (!tupleDescriptor->tdcompression)
750750
break;
751751
}
752752
else if ((OidIsValid(tupleDescriptor->attrs[i]->attcompression) ||
753753
(tupleDescriptor->attrs[i]->attlen == -1 &&
754754
OidIsValid(tupleDescriptor->attrs[i]->attrelid) &&
755-
tupleDescriptor->tdcmroutines &&
756-
tupleDescriptor->tdcmroutines[i] &&
755+
tupleDescriptor->tdcompression &&
756+
tupleDescriptor->tdcompression[i].routine &&
757757
VARATT_IS_EXTERNAL(DatumGetPointer(values[i])))))
758758
{
759759
if (!oldValues)

src/backend/access/common/reloptions.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,25 @@ untransformRelOptions(Datum options)
940940
return result;
941941
}
942942

943+
char *
944+
formatRelOptions(List *options)
945+
{
946+
StringInfoData buf;
947+
ListCell *cell;
948+
949+
initStringInfo(&buf);
950+
951+
foreach(cell, options)
952+
{
953+
DefElem *def = (DefElem *) lfirst(cell);
954+
955+
appendStringInfo(&buf, "%s%s=%s", buf.len > 0 ? ", " : "",
956+
def->defname, defGetString(def));
957+
}
958+
959+
return buf.data;
960+
}
961+
943962
/*
944963
* Extract and parse reloptions from a pg_class tuple.
945964
*

src/backend/access/common/tupdesc.c

Lines changed: 111 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
#include "catalog/pg_collation.h"
2525
#include "catalog/pg_type.h"
2626
#include "commands/defrem.h"
27+
#include "commands/tablecmds.h"
2728
#include "miscadmin.h"
2829
#include "parser/parse_type.h"
2930
#include "utils/acl.h"
3031
#include "utils/builtins.h"
32+
#include "utils/datum.h"
3133
#include "utils/resowner_private.h"
3234
#include "utils/syscache.h"
3335

@@ -91,7 +93,7 @@ CreateTemplateTupleDesc(int natts, bool hasoid)
9193
*/
9294
desc->natts = natts;
9395
desc->constr = NULL;
94-
desc->tdcmroutines = NULL;
96+
desc->tdcompression = NULL;
9597
desc->tdtypeid = RECORDOID;
9698
desc->tdtypmod = -1;
9799
desc->tdhasoid = hasoid;
@@ -125,7 +127,7 @@ CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs)
125127
desc->attrs = attrs;
126128
desc->natts = natts;
127129
desc->constr = NULL;
128-
desc->tdcmroutines = NULL;
130+
desc->tdcompression = NULL;
129131
desc->tdtypeid = RECORDOID;
130132
desc->tdtypmod = -1;
131133
desc->tdhasoid = hasoid;
@@ -134,6 +136,35 @@ CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs)
134136
return desc;
135137
}
136138

139+
static AttributeCompression *
140+
TupleDescCopyCompression(TupleDesc tupdesc)
141+
{
142+
AttributeCompression *src = tupdesc->tdcompression;
143+
AttributeCompression *dst = (AttributeCompression *)
144+
palloc0(sizeof(*dst) * tupdesc->natts);
145+
int i;
146+
147+
for (i = 0; i < tupdesc->natts; i++)
148+
if (src[i].routine)
149+
{
150+
dst[i].routine = palloc(sizeof(*dst[i].routine));
151+
152+
memcpy(dst[i].routine, src[i].routine, sizeof(*dst[i].routine));
153+
154+
if (DatumGetPointer(src[i].optionsDatum) != NULL)
155+
dst[i].optionsDatum = datumCopy(src[i].optionsDatum, false, -1);
156+
else
157+
dst[i].optionsDatum = src[i].optionsDatum;
158+
159+
dst[i].options = src[i].routine->options &&
160+
src[i].routine->options->copy ?
161+
src[i].routine->options->copy(src[i].options) :
162+
src[i].options;
163+
}
164+
165+
return dst;
166+
}
167+
137168
/*
138169
* CreateTupleDescCopy
139170
* This function creates a new TupleDesc by copying from an existing
@@ -160,6 +191,9 @@ CreateTupleDescCopy(TupleDesc tupdesc)
160191
desc->tdtypeid = tupdesc->tdtypeid;
161192
desc->tdtypmod = tupdesc->tdtypmod;
162193

194+
if (tupdesc->tdcompression)
195+
desc->tdcompression = TupleDescCopyCompression(tupdesc);
196+
163197
return desc;
164198
}
165199

@@ -173,7 +207,6 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
173207
{
174208
TupleDesc desc;
175209
TupleConstr *constr = tupdesc->constr;
176-
CompressionMethodRoutine **cmroutines = tupdesc->tdcmroutines;
177210
int i;
178211

179212
desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
@@ -218,20 +251,8 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
218251
desc->constr = cpy;
219252
}
220253

221-
if (cmroutines)
222-
{
223-
CompressionMethodRoutine **cmrs = (CompressionMethodRoutine **)
224-
palloc0(sizeof(*cmrs) * tupdesc->natts);
225-
226-
for (i = 0; i < tupdesc->natts; i++)
227-
if (cmroutines[i])
228-
{
229-
cmrs[i] = palloc(sizeof(**cmrs));
230-
memcpy(cmrs[i], cmroutines[i], sizeof(**cmrs));
231-
}
232-
233-
desc->tdcmroutines = cmrs;
234-
}
254+
if (tupdesc->tdcompression)
255+
desc->tdcompression = TupleDescCopyCompression(tupdesc);
235256

236257
desc->tdtypeid = tupdesc->tdtypeid;
237258
desc->tdtypmod = tupdesc->tdtypmod;
@@ -279,6 +300,7 @@ TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno,
279300
dst->attrs[dstAttno - 1]->attnotnull = false;
280301
dst->attrs[dstAttno - 1]->atthasdef = false;
281302
dst->attrs[dstAttno - 1]->attidentity = '\0';
303+
dst->attrs[dstAttno - 1]->attcompression = InvalidOid;
282304
}
283305

284306
/*
@@ -324,12 +346,20 @@ FreeTupleDesc(TupleDesc tupdesc)
324346
pfree(tupdesc->constr);
325347
}
326348

327-
if (tupdesc->tdcmroutines)
349+
if (tupdesc->tdcompression)
328350
{
329351
for (i = 0; i < tupdesc->natts; i++)
330-
if (tupdesc->tdcmroutines[i])
331-
pfree(tupdesc->tdcmroutines[i]);
332-
pfree(tupdesc->tdcmroutines);
352+
if (tupdesc->tdcompression[i].routine)
353+
{
354+
CompressionMethodRoutine *cmr = tupdesc->tdcompression[i].routine;
355+
356+
if (cmr->options && cmr->options->free)
357+
cmr->options->free(tupdesc->tdcompression[i].options);
358+
359+
pfree(cmr);
360+
}
361+
362+
pfree(tupdesc->tdcompression);
333363
}
334364

335365
pfree(tupdesc);
@@ -506,9 +536,34 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
506536
else if (tupdesc2->constr != NULL)
507537
return false;
508538

509-
if (tupdesc1->tdcmroutines != tupdesc2->tdcmroutines) /* FIXME compare cmroutines[*] */
539+
if ((tupdesc1->tdcompression == NULL) != (tupdesc2->tdcompression == NULL))
510540
return false;
511541

542+
if (tupdesc1->tdcompression == NULL)
543+
return true;
544+
545+
for (i = 0; i < tupdesc1->natts; i++)
546+
{
547+
AttributeCompression *ac1 = &tupdesc1->tdcompression[i];
548+
AttributeCompression *ac2 = &tupdesc2->tdcompression[i];
549+
CompressionMethodRoutine *cmr1 = ac1->routine;
550+
CompressionMethodRoutine *cmr2 = ac2->routine;
551+
552+
if (!cmr1 != !cmr2)
553+
return false;
554+
555+
if (!cmr1)
556+
continue;
557+
558+
if (memcmp(cmr1, cmr2, sizeof(*cmr1)))
559+
return false;
560+
561+
if (cmr1->options && cmr1->options->equal
562+
? !cmr1->options->equal(ac1->options, ac2->options)
563+
: ac1->options != ac2->options)
564+
return false;
565+
}
566+
512567
return true;
513568
}
514569

@@ -702,6 +757,27 @@ TupleDescInitEntryCollation(TupleDesc desc,
702757
desc->attrs[attributeNumber - 1]->attcollation = collationid;
703758
}
704759

760+
void
761+
TupleDescInitAttrCompression(TupleDesc desc,
762+
AttrNumber attnum,
763+
CompressionMethodRoutine *cmr,
764+
List *optionsList,
765+
Datum optionsDatum)
766+
{
767+
AttributeCompression *ac;
768+
769+
if (!desc->tdcompression)
770+
desc->tdcompression = (AttributeCompression *)
771+
palloc0(desc->natts * sizeof(AttributeCompression));
772+
773+
ac = &desc->tdcompression[attnum - 1];
774+
775+
ac->routine = cmr;
776+
ac->optionsDatum = optionsDatum;
777+
ac->options = cmr->options && cmr->options->convert ?
778+
cmr->options->convert(desc->attrs[attnum - 1], optionsList) :
779+
optionsList;
780+
}
705781

706782
/*
707783
* BuildDescForRelation
@@ -737,8 +813,11 @@ BuildDescForRelation(List *schema)
737813

738814
foreach(l, schema)
739815
{
740-
ColumnDef *entry = lfirst(l);
741-
AclResult aclresult;
816+
ColumnDef *entry = lfirst(l);
817+
AclResult aclresult;
818+
CompressionMethodRoutine *cmroutine;
819+
List *cmoptionsList;
820+
Datum cmoptionsDatum;
742821

743822
/*
744823
* for each entry in the list, get the name and type information from
@@ -777,21 +856,15 @@ BuildDescForRelation(List *schema)
777856
desc->attrs[attnum - 1]->attislocal = entry->is_local;
778857
desc->attrs[attnum - 1]->attinhcount = entry->inhcount;
779858

780-
if (entry->compression)
781-
{
782-
/* Get compression method OID, throwing an error if it doesn't exist. */
783-
Oid cmoid = GetCompressionMethodOid(entry->compression->methodName,
784-
false);
785-
CompressionMethodRoutine *cmr =
786-
GetCompressionMethodRoutineByCmId(cmoid);
787-
788-
desc->attrs[attnum - 1]->attcompression = cmoid;
859+
/* entry->compression is handled in subsequent ALTER TABLE statement */
860+
GetAttributeCompression(NULL,
861+
desc->attrs[attnum - 1],
862+
&desc->attrs[attnum - 1]->attcompression,
863+
&cmroutine, &cmoptionsList, &cmoptionsDatum);
789864

790-
if (cmr->addAttr)
791-
(*cmr->addAttr)(desc->attrs[attnum - 1]);
792-
793-
/* TODO attcmoptions */
794-
}
865+
if (OidIsValid(desc->attrs[attnum - 1]->attcompression))
866+
TupleDescInitAttrCompression(desc, attnum, cmroutine,
867+
cmoptionsList, cmoptionsDatum);
795868
}
796869

797870
if (has_not_null)

0 commit comments

Comments
 (0)