Skip to content

Commit 6c28edc

Browse files
author
Nikita Glukhov
committed
Add default compression methods for types
1 parent c3b3c7c commit 6c28edc

File tree

12 files changed

+343
-203
lines changed

12 files changed

+343
-203
lines changed

src/backend/catalog/pg_type.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
118118
values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(-1);
119119
values[Anum_pg_type_typndims - 1] = Int32GetDatum(0);
120120
values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(InvalidOid);
121+
values[Anum_pg_type_typdefaultcm - 1] = ObjectIdGetDatum(InvalidOid);
121122
nulls[Anum_pg_type_typdefaultbin - 1] = true;
122123
nulls[Anum_pg_type_typdefault - 1] = true;
123124
nulls[Anum_pg_type_typacl - 1] = true;
@@ -362,6 +363,7 @@ TypeCreate(Oid newTypeOid,
362363
values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(typeMod);
363364
values[Anum_pg_type_typndims - 1] = Int32GetDatum(typNDims);
364365
values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(typeCollation);
366+
values[Anum_pg_type_typdefaultcm - 1] = ObjectIdGetDatum(InvalidOid);
365367

366368
/*
367369
* initialize the default binary value for this type. Check for nulls of

src/backend/commands/typecmds.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "catalog/pg_am.h"
4141
#include "catalog/pg_authid.h"
4242
#include "catalog/pg_collation.h"
43+
#include "catalog/pg_compression.h"
4344
#include "catalog/pg_constraint.h"
4445
#include "catalog/pg_constraint_fn.h"
4546
#include "catalog/pg_depend.h"
@@ -3623,6 +3624,66 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
36233624
return oldNspOid;
36243625
}
36253626

3627+
3628+
/*
3629+
* Execute ALTER TYPE SET COMPRESSED <cm> [WITH (<option>, ...)]
3630+
*/
3631+
static void
3632+
AlterTypeDefaultCompression(Oid typeid, ColumnCompression *compression)
3633+
{
3634+
Oid cmoid;
3635+
Type oldtup = typeidType(typeid);
3636+
Form_pg_type oldtype = (Form_pg_type) GETSTRUCT(oldtup);
3637+
3638+
cmoid = compression->methodName
3639+
? get_compression_method_oid(compression->methodName, false)
3640+
: InvalidOid;
3641+
3642+
if (oldtype->typdefaultcm != cmoid)
3643+
{
3644+
Relation typrel;
3645+
HeapTuple newtup;
3646+
Datum values[Natts_pg_type];
3647+
bool nulls[Natts_pg_type];
3648+
bool replace[Natts_pg_type];
3649+
3650+
typrel = heap_open(TypeRelationId, RowExclusiveLock);
3651+
3652+
memset(replace, 0, sizeof(replace));
3653+
3654+
values[Anum_pg_type_typdefaultcm - 1] = ObjectIdGetDatum(cmoid);
3655+
nulls[Anum_pg_type_typdefaultcm - 1] = false;
3656+
replace[Anum_pg_type_typdefaultcm - 1] = true;
3657+
3658+
newtup = heap_modify_tuple(oldtup, RelationGetDescr(typrel),
3659+
values, nulls, replace);
3660+
3661+
CatalogTupleUpdate(typrel, &newtup->t_self, newtup);
3662+
3663+
heap_freetuple(newtup);
3664+
3665+
heap_close(typrel, RowExclusiveLock);
3666+
3667+
if (OidIsValid(oldtype->typdefaultcm))
3668+
deleteDependencyRecordsForClass(TypeRelationId, typeid, 0,
3669+
CompressionMethodRelationId,
3670+
DEPENDENCY_NORMAL);
3671+
3672+
if (OidIsValid(cmoid))
3673+
{
3674+
ObjectAddress myself,
3675+
referenced;
3676+
ObjectAddressSet(myself, TypeRelationId, typeid);
3677+
ObjectAddressSet(referenced, CompressionMethodRelationId, cmoid);
3678+
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
3679+
}
3680+
3681+
InvokeObjectPostAlterHook(TypeRelationId, typeid, 0);
3682+
}
3683+
3684+
ReleaseSysCache(oldtup);
3685+
}
3686+
36263687
/*
36273688
* Execute ALTER TYPE <typeName> <command>, ...
36283689
*/
@@ -3643,6 +3704,10 @@ AlterType(AlterTypeStmt *stmt)
36433704

36443705
switch (cmd->cmdtype)
36453706
{
3707+
case AT_AlterTypeCompression:
3708+
AlterTypeDefaultCompression(typeid,
3709+
(ColumnCompression *) cmd->def);
3710+
break;
36463711
default:
36473712
elog(ERROR, "unknown ALTER TYPE command %d", cmd->cmdtype);
36483713
}

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,6 +2827,7 @@ _copyColumnCompression(const ColumnCompression *from)
28272827
ColumnCompression *newnode = makeNode(ColumnCompression);
28282828

28292829
COPY_STRING_FIELD(methodName);
2830+
COPY_SCALAR_FIELD(methodOid);
28302831
COPY_NODE_FIELD(options);
28312832

28322833
return newnode;

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,6 +2559,7 @@ static bool
25592559
_equalColumnCompression(const ColumnCompression *a, const ColumnCompression *b)
25602560
{
25612561
COMPARE_STRING_FIELD(methodName);
2562+
COMPARE_SCALAR_FIELD(methodOid);
25622563
COMPARE_NODE_FIELD(options);
25632564

25642565
return true;

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2788,6 +2788,7 @@ _outColumnCompression(StringInfo str, const ColumnCompression *node)
27882788
WRITE_NODE_TYPE("COLUMNCOMPRESSION");
27892789

27902790
WRITE_STRING_FIELD(methodName);
2791+
WRITE_OID_FIELD(methodOid);
27912792
WRITE_NODE_FIELD(options);
27922793
}
27932794

src/backend/parser/gram.y

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
584584
%type <partrange_datum> PartitionRangeDatum
585585
%type <list> range_datum_list
586586

587-
%type <node> columnCompression optColumnCompression
587+
%type <node> columnCompression optColumnCompression compressedClause
588588

589589
/*
590590
* Non-keyword token types. These are hard-wired into the "flex" lexer.
@@ -2179,7 +2179,7 @@ alter_table_cmd:
21792179
n->missing_ok = true;
21802180
$$ = (Node *)n;
21812181
}
2182-
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET COMPRESSED <cm> [WITH (<options>)] */
2182+
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET (NOT COMPRESSED | COMPRESSED <cm> [WITH (<options>)]) */
21832183
| ALTER opt_column ColId SET columnCompression
21842184
{
21852185
AlterTableCmd *n = makeNode(AlterTableCmd);
@@ -2188,15 +2188,6 @@ alter_table_cmd:
21882188
n->def = $5;
21892189
$$ = (Node *)n;
21902190
}
2191-
/* ALTER TABLE <name> ALTER [COLUMN] <colname> SET NOT COMPRESSED */
2192-
| ALTER opt_column ColId SET NOT COMPRESSED
2193-
{
2194-
AlterTableCmd *n = makeNode(AlterTableCmd);
2195-
n->subtype = AT_AlterColumnCompression;
2196-
n->name = $3;
2197-
n->def = NULL;
2198-
$$ = (Node *)n;
2199-
}
22002191
/* ALTER TABLE <name> DROP [COLUMN] IF EXISTS <colname> [RESTRICT|CASCADE] */
22012192
| DROP opt_column IF_P EXISTS ColId opt_drop_behavior
22022193
{
@@ -2758,7 +2749,14 @@ alterTypeCmds:
27582749
;
27592750

27602751
alterTypeCmd:
2761-
/*EMPTY*/
2752+
/* ALTER TYPE <name> SET (NOT COMPRESSED | COMPRESSED <cm> [WITH (<options>)]) */
2753+
SET columnCompression
2754+
{
2755+
AlterTypeCmd *n = makeNode(AlterTypeCmd);
2756+
n->cmdtype = AT_AlterTypeCompression;
2757+
n->def = $2;
2758+
$$ = (Node *)n;
2759+
}
27622760
;
27632761

27642762
AlterCompositeTypeStmt:
@@ -3349,18 +3347,31 @@ columnOptions: ColId ColQualList
33493347
}
33503348
;
33513349

3352-
columnCompression:
3350+
compressedClause:
33533351
COMPRESSED name optCompressionParameters
33543352
{
33553353
ColumnCompression *n = makeNode(ColumnCompression);
33563354
n->methodName = $2;
3355+
n->methodOid = InvalidOid;
33573356
n->options = (List *) $3;
33583357
$$ = (Node *) n;
33593358
}
33603359
;
33613360

3361+
columnCompression:
3362+
compressedClause |
3363+
NOT COMPRESSED
3364+
{
3365+
ColumnCompression *n = makeNode(ColumnCompression);
3366+
n->methodName = NULL;
3367+
n->methodOid = InvalidOid;
3368+
n->options = NIL;
3369+
$$ = (Node *) n;
3370+
}
3371+
;
3372+
33623373
optColumnCompression:
3363-
columnCompression
3374+
compressedClause /* FIXME shift/reduce conflict on NOT COMPRESSED/NOT NULL */
33643375
| /*EMPTY*/ { $$ = NULL; }
33653376
;
33663377

src/backend/parser/parse_utilcmd.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,21 @@ void
487487
transformColumnCompression(ColumnDef *column, RangeVar *relation,
488488
AlterTableStmt **alterStmt)
489489
{
490+
if (!column->compression && column->typeName)
491+
{
492+
Type tup = typenameType(NULL, column->typeName, NULL);
493+
Oid cmoid = get_base_typdefaultcm(tup);
494+
495+
ReleaseSysCache(tup);
496+
497+
if (OidIsValid(cmoid))
498+
{
499+
column->compression = makeNode(ColumnCompression);
500+
column->compression->methodName = get_compression_method_name(cmoid);
501+
column->compression->options = NIL;
502+
}
503+
}
504+
490505
if (column->compression)
491506
{
492507
AlterTableCmd *cmd;

src/backend/utils/cache/lsyscache.c

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,16 +2307,12 @@ getBaseType(Oid typid)
23072307
}
23082308

23092309
/*
2310-
* getBaseTypeAndTypmod
2311-
* If the given type is a domain, return its base type and typmod;
2312-
* otherwise return the type's own OID, and leave *typmod unchanged.
2313-
*
23142310
* Note that the "applied typmod" should be -1 for every domain level
23152311
* above the bottommost; therefore, if the passed-in typid is indeed
23162312
* a domain, *typmod should be -1.
23172313
*/
2318-
Oid
2319-
getBaseTypeAndTypmod(Oid typid, int32 *typmod)
2314+
static inline HeapTuple
2315+
getBaseTypeTuple(Oid *typid, int32 *typmod)
23202316
{
23212317
/*
23222318
* We loop to find the bottom base type in a stack of domains.
@@ -2326,27 +2322,36 @@ getBaseTypeAndTypmod(Oid typid, int32 *typmod)
23262322
HeapTuple tup;
23272323
Form_pg_type typTup;
23282324

2329-
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2325+
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*typid));
23302326
if (!HeapTupleIsValid(tup))
2331-
elog(ERROR, "cache lookup failed for type %u", typid);
2327+
elog(ERROR, "cache lookup failed for type %u", *typid);
23322328
typTup = (Form_pg_type) GETSTRUCT(tup);
23332329
if (typTup->typtype != TYPTYPE_DOMAIN)
2334-
{
23352330
/* Not a domain, so done */
2336-
ReleaseSysCache(tup);
2337-
break;
2338-
}
2331+
return tup;
23392332

23402333
Assert(*typmod == -1);
2341-
typid = typTup->typbasetype;
2334+
*typid = typTup->typbasetype;
23422335
*typmod = typTup->typtypmod;
23432336

23442337
ReleaseSysCache(tup);
23452338
}
2346-
2347-
return typid;
23482339
}
23492340

2341+
/*
2342+
* getBaseTypeAndTypmod
2343+
* If the given type is a domain, return its base type and typmod;
2344+
* otherwise return the type's own OID, and leave *typmod unchanged.
2345+
*
2346+
*/
2347+
Oid
2348+
getBaseTypeAndTypmod(Oid typid, int32 *typmod)
2349+
{
2350+
HeapTuple tup = getBaseTypeTuple(&typid, typmod);
2351+
ReleaseSysCache(tup);
2352+
return typid;
2353+
}
2354+
23502355
/*
23512356
* get_typavgwidth
23522357
*
@@ -2839,6 +2844,39 @@ type_is_collatable(Oid typid)
28392844
return OidIsValid(get_typcollation(typid));
28402845
}
28412846

2847+
/*
2848+
* get_base_typdefaultcm
2849+
*
2850+
* Given the type tuple, return the base type's typdefaultlcm attribute.
2851+
*/
2852+
Oid
2853+
get_base_typdefaultcm(HeapTuple typtup)
2854+
{
2855+
Oid typid;
2856+
Oid base;
2857+
Oid cm = InvalidOid;
2858+
2859+
for (typid = (Oid) -1; !OidIsValid(cm) && OidIsValid(typid); typid = base)
2860+
{
2861+
Form_pg_type type;
2862+
2863+
if (typid != (Oid) -1)
2864+
{
2865+
typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
2866+
if (!HeapTupleIsValid(typtup))
2867+
elog(ERROR, "cache lookup failed for type %u", typid);
2868+
}
2869+
2870+
type = (Form_pg_type) GETSTRUCT(typtup);
2871+
base = type->typtype == TYPTYPE_DOMAIN ? type->typbasetype : InvalidOid;
2872+
cm = type->typdefaultcm;
2873+
2874+
if (typid != (Oid) -1)
2875+
ReleaseSysCache(typtup);
2876+
}
2877+
2878+
return cm;
2879+
}
28422880

28432881
/* ---------- STATISTICS CACHE ---------- */
28442882

src/include/catalog/pg_class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ typedef FormData_pg_class *Form_pg_class;
147147
* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId;
148148
* similarly, "1" in relminmxid stands for FirstMultiXactId
149149
*/
150-
DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f f f t n f 3 1 _null_ _null_ _null_));
150+
DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 31 0 t f f f f f f t n f 3 1 _null_ _null_ _null_));
151151
DESCR("");
152152
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 24 0 f f f f f f f t n f 3 1 _null_ _null_ _null_));
153153
DESCR("");

0 commit comments

Comments
 (0)