Commit f5024d8d authored by Tom Lane's avatar Tom Lane

Re-order pg_attribute columns to eliminate some padding space.

Now that attcompression is just a char, there's a lot of wasted
padding space after it.  Move it into the group of char-wide
columns to save a net of 4 bytes per pg_attribute entry.  While
we're at it, swap the order of attstorage and attalign to make for
a more logical grouping of these columns.

Also re-order actions in related code to match the new field ordering.

This patch also fixes one outright bug: equalTupleDescs() failed to
compare attcompression.  That could, for example, cause relcache
reload to fail to adopt a new value following a change.

Michael Paquier and Tom Lane, per a gripe from Andres Freund.

Discussion: https://postgr.es/m/20210517204803.iyk5wwvwgtjcmc5w@alap3.anarazel.de
parent bc2a389e
...@@ -1236,6 +1236,15 @@ ...@@ -1236,6 +1236,15 @@
</para></entry> </para></entry>
</row> </row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>attalign</structfield> <type>char</type>
</para>
<para>
A copy of <literal>pg_type.typalign</literal> of this column's type
</para></entry>
</row>
<row> <row>
<entry role="catalog_table_entry"><para role="column_definition"> <entry role="catalog_table_entry"><para role="column_definition">
<structfield>attstorage</structfield> <type>char</type> <structfield>attstorage</structfield> <type>char</type>
...@@ -1249,10 +1258,13 @@ ...@@ -1249,10 +1258,13 @@
<row> <row>
<entry role="catalog_table_entry"><para role="column_definition"> <entry role="catalog_table_entry"><para role="column_definition">
<structfield>attalign</structfield> <type>char</type> <structfield>attcompression</structfield> <type>char</type>
</para> </para>
<para> <para>
A copy of <literal>pg_type.typalign</literal> of this column's type The current compression method of the column. If it is an invalid
compression method (<literal>'\0'</literal>) then column data will not
be compressed. Otherwise, <literal>'p'</literal> = pglz compression or
<literal>'l'</literal> = <productname>LZ4</productname> compression.
</para></entry> </para></entry>
</row> </row>
...@@ -1355,18 +1367,6 @@ ...@@ -1355,18 +1367,6 @@
</para></entry> </para></entry>
</row> </row>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>attcompression</structfield> <type>char</type>
</para>
<para>
The current compression method of the column. If it is an invalid
compression method (<literal>'\0'</literal>) then column data will not
be compressed. Otherwise, <literal>'p'</literal> = pglz compression or
<literal>'l'</literal> = <productname>LZ4</productname> compression.
</para></entry>
</row>
<row> <row>
<entry role="catalog_table_entry"><para role="column_definition"> <entry role="catalog_table_entry"><para role="column_definition">
<structfield>attacl</structfield> <type>aclitem[]</type> <structfield>attacl</structfield> <type>aclitem[]</type>
......
...@@ -424,7 +424,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) ...@@ -424,7 +424,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
* general it seems safer to check them always. * general it seems safer to check them always.
* *
* attcacheoff must NOT be checked since it's possibly not set in both * attcacheoff must NOT be checked since it's possibly not set in both
* copies. * copies. We also intentionally ignore atthasmissing, since that's
* not very relevant in tupdescs, which lack the attmissingval field.
*/ */
if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0) if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
return false; return false;
...@@ -440,9 +441,11 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) ...@@ -440,9 +441,11 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false; return false;
if (attr1->attbyval != attr2->attbyval) if (attr1->attbyval != attr2->attbyval)
return false; return false;
if (attr1->attalign != attr2->attalign)
return false;
if (attr1->attstorage != attr2->attstorage) if (attr1->attstorage != attr2->attstorage)
return false; return false;
if (attr1->attalign != attr2->attalign) if (attr1->attcompression != attr2->attcompression)
return false; return false;
if (attr1->attnotnull != attr2->attnotnull) if (attr1->attnotnull != attr2->attnotnull)
return false; return false;
...@@ -460,7 +463,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) ...@@ -460,7 +463,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
return false; return false;
if (attr1->attcollation != attr2->attcollation) if (attr1->attcollation != attr2->attcollation)
return false; return false;
/* attacl, attoptions and attfdwoptions are not even present... */ /* variable-length fields are not even present... */
} }
if (tupdesc1->constr != NULL) if (tupdesc1->constr != NULL)
...@@ -639,12 +642,11 @@ TupleDescInitEntry(TupleDesc desc, ...@@ -639,12 +642,11 @@ TupleDescInitEntry(TupleDesc desc,
att->attbyval = typeForm->typbyval; att->attbyval = typeForm->typbyval;
att->attalign = typeForm->typalign; att->attalign = typeForm->typalign;
att->attstorage = typeForm->typstorage; att->attstorage = typeForm->typstorage;
att->attcollation = typeForm->typcollation;
if (IsStorageCompressible(typeForm->typstorage)) if (IsStorageCompressible(typeForm->typstorage))
att->attcompression = GetDefaultToastCompression(); att->attcompression = GetDefaultToastCompression();
else else
att->attcompression = InvalidCompressionMethod; att->attcompression = InvalidCompressionMethod;
att->attcollation = typeForm->typcollation;
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
} }
...@@ -709,6 +711,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, ...@@ -709,6 +711,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
att->attbyval = false; att->attbyval = false;
att->attalign = TYPALIGN_INT; att->attalign = TYPALIGN_INT;
att->attstorage = TYPSTORAGE_EXTENDED; att->attstorage = TYPSTORAGE_EXTENDED;
att->attcompression = GetDefaultToastCompression();
att->attcollation = DEFAULT_COLLATION_OID; att->attcollation = DEFAULT_COLLATION_OID;
break; break;
...@@ -717,6 +720,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, ...@@ -717,6 +720,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
att->attbyval = true; att->attbyval = true;
att->attalign = TYPALIGN_CHAR; att->attalign = TYPALIGN_CHAR;
att->attstorage = TYPSTORAGE_PLAIN; att->attstorage = TYPSTORAGE_PLAIN;
att->attcompression = InvalidCompressionMethod;
att->attcollation = InvalidOid; att->attcollation = InvalidOid;
break; break;
...@@ -725,6 +729,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, ...@@ -725,6 +729,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
att->attbyval = true; att->attbyval = true;
att->attalign = TYPALIGN_INT; att->attalign = TYPALIGN_INT;
att->attstorage = TYPSTORAGE_PLAIN; att->attstorage = TYPSTORAGE_PLAIN;
att->attcompression = InvalidCompressionMethod;
att->attcollation = InvalidOid; att->attcollation = InvalidOid;
break; break;
...@@ -733,6 +738,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, ...@@ -733,6 +738,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
att->attbyval = FLOAT8PASSBYVAL; att->attbyval = FLOAT8PASSBYVAL;
att->attalign = TYPALIGN_DOUBLE; att->attalign = TYPALIGN_DOUBLE;
att->attstorage = TYPSTORAGE_PLAIN; att->attstorage = TYPSTORAGE_PLAIN;
att->attcompression = InvalidCompressionMethod;
att->attcollation = InvalidOid; att->attcollation = InvalidOid;
break; break;
......
...@@ -165,8 +165,8 @@ fillTypeDesc(SpGistTypeDesc *desc, Oid type) ...@@ -165,8 +165,8 @@ fillTypeDesc(SpGistTypeDesc *desc, Oid type)
typtup = (Form_pg_type) GETSTRUCT(tp); typtup = (Form_pg_type) GETSTRUCT(tp);
desc->attlen = typtup->typlen; desc->attlen = typtup->typlen;
desc->attbyval = typtup->typbyval; desc->attbyval = typtup->typbyval;
desc->attstorage = typtup->typstorage;
desc->attalign = typtup->typalign; desc->attalign = typtup->typalign;
desc->attstorage = typtup->typstorage;
ReleaseSysCache(tp); ReleaseSysCache(tp);
} }
...@@ -304,8 +304,8 @@ getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType) ...@@ -304,8 +304,8 @@ getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
att->attalign = keyType->attalign; att->attalign = keyType->attalign;
att->attstorage = keyType->attstorage; att->attstorage = keyType->attstorage;
/* We shouldn't need to bother with making these valid: */ /* We shouldn't need to bother with making these valid: */
att->attcollation = InvalidOid;
att->attcompression = InvalidCompressionMethod; att->attcompression = InvalidCompressionMethod;
att->attcollation = InvalidOid;
/* In case we changed typlen, we'd better reset following offsets */ /* In case we changed typlen, we'd better reset following offsets */
for (int i = spgFirstIncludeColumn; i < outTupDesc->natts; i++) for (int i = spgFirstIncludeColumn; i < outTupDesc->natts; i++)
TupleDescAttr(outTupDesc, i)->attcacheoff = -1; TupleDescAttr(outTupDesc, i)->attcacheoff = -1;
......
...@@ -699,8 +699,8 @@ DefineAttr(char *name, char *type, int attnum, int nullness) ...@@ -699,8 +699,8 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
attrtypes[attnum]->atttypid = Ap->am_oid; attrtypes[attnum]->atttypid = Ap->am_oid;
attrtypes[attnum]->attlen = Ap->am_typ.typlen; attrtypes[attnum]->attlen = Ap->am_typ.typlen;
attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
attrtypes[attnum]->attalign = Ap->am_typ.typalign; attrtypes[attnum]->attalign = Ap->am_typ.typalign;
attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
attrtypes[attnum]->attcollation = Ap->am_typ.typcollation; attrtypes[attnum]->attcollation = Ap->am_typ.typcollation;
/* if an array type, assume 1-dimensional attribute */ /* if an array type, assume 1-dimensional attribute */
if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0) if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0)
...@@ -713,8 +713,8 @@ DefineAttr(char *name, char *type, int attnum, int nullness) ...@@ -713,8 +713,8 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
attrtypes[attnum]->atttypid = TypInfo[typeoid].oid; attrtypes[attnum]->atttypid = TypInfo[typeoid].oid;
attrtypes[attnum]->attlen = TypInfo[typeoid].len; attrtypes[attnum]->attlen = TypInfo[typeoid].len;
attrtypes[attnum]->attbyval = TypInfo[typeoid].byval; attrtypes[attnum]->attbyval = TypInfo[typeoid].byval;
attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
attrtypes[attnum]->attalign = TypInfo[typeoid].align; attrtypes[attnum]->attalign = TypInfo[typeoid].align;
attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
attrtypes[attnum]->attcollation = TypInfo[typeoid].collation; attrtypes[attnum]->attcollation = TypInfo[typeoid].collation;
/* if an array type, assume 1-dimensional attribute */ /* if an array type, assume 1-dimensional attribute */
if (TypInfo[typeoid].elem != InvalidOid && if (TypInfo[typeoid].elem != InvalidOid &&
...@@ -724,6 +724,11 @@ DefineAttr(char *name, char *type, int attnum, int nullness) ...@@ -724,6 +724,11 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
attrtypes[attnum]->attndims = 0; attrtypes[attnum]->attndims = 0;
} }
if (IsStorageCompressible(attrtypes[attnum]->attstorage))
attrtypes[attnum]->attcompression = GetDefaultToastCompression();
else
attrtypes[attnum]->attcompression = InvalidCompressionMethod;
/* /*
* If a system catalog column is collation-aware, force it to use C * If a system catalog column is collation-aware, force it to use C
* collation, so that its behavior is independent of the database's * collation, so that its behavior is independent of the database's
...@@ -737,10 +742,6 @@ DefineAttr(char *name, char *type, int attnum, int nullness) ...@@ -737,10 +742,6 @@ DefineAttr(char *name, char *type, int attnum, int nullness)
attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->atttypmod = -1;
attrtypes[attnum]->attislocal = true; attrtypes[attnum]->attislocal = true;
if (IsStorageCompressible(attrtypes[attnum]->attstorage))
attrtypes[attnum]->attcompression = GetDefaultToastCompression();
else
attrtypes[attnum]->attcompression = InvalidCompressionMethod;
if (nullness == BOOTCOL_NULL_FORCE_NOT_NULL) if (nullness == BOOTCOL_NULL_FORCE_NOT_NULL)
{ {
......
...@@ -897,8 +897,11 @@ sub morph_row_for_pgattr ...@@ -897,8 +897,11 @@ sub morph_row_for_pgattr
$row->{atttypid} = $type->{oid}; $row->{atttypid} = $type->{oid};
$row->{attlen} = $type->{typlen}; $row->{attlen} = $type->{typlen};
$row->{attbyval} = $type->{typbyval}; $row->{attbyval} = $type->{typbyval};
$row->{attstorage} = $type->{typstorage};
$row->{attalign} = $type->{typalign}; $row->{attalign} = $type->{typalign};
$row->{attstorage} = $type->{typstorage};
$row->{attcompression} =
$type->{typstorage} ne 'p' && $type->{typstorage} ne 'e' ? 'p' : '\0';
# set attndims if it's an array type # set attndims if it's an array type
$row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0'; $row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0';
...@@ -907,9 +910,6 @@ sub morph_row_for_pgattr ...@@ -907,9 +910,6 @@ sub morph_row_for_pgattr
$row->{attcollation} = $row->{attcollation} =
$type->{typcollation} ne '0' ? $C_COLLATION_OID : 0; $type->{typcollation} ne '0' ? $C_COLLATION_OID : 0;
$row->{attcompression} =
$type->{typstorage} ne 'p' && $type->{typstorage} ne 'e' ? 'p' : '\0';
if (defined $attr->{forcenotnull}) if (defined $attr->{forcenotnull})
{ {
$row->{attnotnull} = 't'; $row->{attnotnull} = 't';
......
...@@ -146,7 +146,8 @@ static Node *cookConstraint(ParseState *pstate, ...@@ -146,7 +146,8 @@ static Node *cookConstraint(ParseState *pstate,
/* /*
* The initializers below do not include trailing variable length fields, * The initializers below do not include trailing variable length fields,
* but that's OK - we're never going to reference anything beyond the * but that's OK - we're never going to reference anything beyond the
* fixed-size portion of the structure anyway. * fixed-size portion of the structure anyway. Fields that can default
* to zeroes are also not mentioned.
*/ */
static const FormData_pg_attribute a1 = { static const FormData_pg_attribute a1 = {
...@@ -157,8 +158,8 @@ static const FormData_pg_attribute a1 = { ...@@ -157,8 +158,8 @@ static const FormData_pg_attribute a1 = {
.attcacheoff = -1, .attcacheoff = -1,
.atttypmod = -1, .atttypmod = -1,
.attbyval = false, .attbyval = false,
.attstorage = TYPSTORAGE_PLAIN,
.attalign = TYPALIGN_SHORT, .attalign = TYPALIGN_SHORT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true, .attnotnull = true,
.attislocal = true, .attislocal = true,
}; };
...@@ -171,8 +172,8 @@ static const FormData_pg_attribute a2 = { ...@@ -171,8 +172,8 @@ static const FormData_pg_attribute a2 = {
.attcacheoff = -1, .attcacheoff = -1,
.atttypmod = -1, .atttypmod = -1,
.attbyval = true, .attbyval = true,
.attstorage = TYPSTORAGE_PLAIN,
.attalign = TYPALIGN_INT, .attalign = TYPALIGN_INT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true, .attnotnull = true,
.attislocal = true, .attislocal = true,
}; };
...@@ -185,8 +186,8 @@ static const FormData_pg_attribute a3 = { ...@@ -185,8 +186,8 @@ static const FormData_pg_attribute a3 = {
.attcacheoff = -1, .attcacheoff = -1,
.atttypmod = -1, .atttypmod = -1,
.attbyval = true, .attbyval = true,
.attstorage = TYPSTORAGE_PLAIN,
.attalign = TYPALIGN_INT, .attalign = TYPALIGN_INT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true, .attnotnull = true,
.attislocal = true, .attislocal = true,
}; };
...@@ -199,8 +200,8 @@ static const FormData_pg_attribute a4 = { ...@@ -199,8 +200,8 @@ static const FormData_pg_attribute a4 = {
.attcacheoff = -1, .attcacheoff = -1,
.atttypmod = -1, .atttypmod = -1,
.attbyval = true, .attbyval = true,
.attstorage = TYPSTORAGE_PLAIN,
.attalign = TYPALIGN_INT, .attalign = TYPALIGN_INT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true, .attnotnull = true,
.attislocal = true, .attislocal = true,
}; };
...@@ -213,8 +214,8 @@ static const FormData_pg_attribute a5 = { ...@@ -213,8 +214,8 @@ static const FormData_pg_attribute a5 = {
.attcacheoff = -1, .attcacheoff = -1,
.atttypmod = -1, .atttypmod = -1,
.attbyval = true, .attbyval = true,
.attstorage = TYPSTORAGE_PLAIN,
.attalign = TYPALIGN_INT, .attalign = TYPALIGN_INT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true, .attnotnull = true,
.attislocal = true, .attislocal = true,
}; };
...@@ -233,8 +234,8 @@ static const FormData_pg_attribute a6 = { ...@@ -233,8 +234,8 @@ static const FormData_pg_attribute a6 = {
.attcacheoff = -1, .attcacheoff = -1,
.atttypmod = -1, .atttypmod = -1,
.attbyval = true, .attbyval = true,
.attstorage = TYPSTORAGE_PLAIN,
.attalign = TYPALIGN_INT, .attalign = TYPALIGN_INT,
.attstorage = TYPSTORAGE_PLAIN,
.attnotnull = true, .attnotnull = true,
.attislocal = true, .attislocal = true,
}; };
...@@ -779,8 +780,9 @@ InsertPgAttributeTuples(Relation pg_attribute_rel, ...@@ -779,8 +780,9 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
slot[slotCount]->tts_values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1); slot[slotCount]->tts_values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
slot[slotCount]->tts_values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(attrs->atttypmod); slot[slotCount]->tts_values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(attrs->atttypmod);
slot[slotCount]->tts_values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(attrs->attbyval); slot[slotCount]->tts_values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(attrs->attbyval);
slot[slotCount]->tts_values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(attrs->attstorage);
slot[slotCount]->tts_values[Anum_pg_attribute_attalign - 1] = CharGetDatum(attrs->attalign); slot[slotCount]->tts_values[Anum_pg_attribute_attalign - 1] = CharGetDatum(attrs->attalign);
slot[slotCount]->tts_values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(attrs->attstorage);
slot[slotCount]->tts_values[Anum_pg_attribute_attcompression - 1] = CharGetDatum(attrs->attcompression);
slot[slotCount]->tts_values[Anum_pg_attribute_attnotnull - 1] = BoolGetDatum(attrs->attnotnull); slot[slotCount]->tts_values[Anum_pg_attribute_attnotnull - 1] = BoolGetDatum(attrs->attnotnull);
slot[slotCount]->tts_values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(attrs->atthasdef); slot[slotCount]->tts_values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(attrs->atthasdef);
slot[slotCount]->tts_values[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(attrs->atthasmissing); slot[slotCount]->tts_values[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(attrs->atthasmissing);
...@@ -790,7 +792,6 @@ InsertPgAttributeTuples(Relation pg_attribute_rel, ...@@ -790,7 +792,6 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal); slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal);
slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attrs->attinhcount); slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(attrs->attinhcount);
slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation); slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation);
slot[slotCount]->tts_values[Anum_pg_attribute_attcompression - 1] = CharGetDatum(attrs->attcompression);
if (attoptions && attoptions[natts] != (Datum) 0) if (attoptions && attoptions[natts] != (Datum) 0)
slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attoptions[natts]; slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attoptions[natts];
else else
......
...@@ -345,8 +345,8 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -345,8 +345,8 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attndims = from->attndims; to->attndims = from->attndims;
to->atttypmod = from->atttypmod; to->atttypmod = from->atttypmod;
to->attbyval = from->attbyval; to->attbyval = from->attbyval;
to->attstorage = from->attstorage;
to->attalign = from->attalign; to->attalign = from->attalign;
to->attstorage = from->attstorage;
to->attcompression = from->attcompression; to->attcompression = from->attcompression;
} }
else else
...@@ -373,16 +373,16 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -373,16 +373,16 @@ ConstructTupleDescriptor(Relation heapRelation,
*/ */
to->atttypid = keyType; to->atttypid = keyType;
to->attlen = typeTup->typlen; to->attlen = typeTup->typlen;
to->atttypmod = exprTypmod(indexkey);
to->attbyval = typeTup->typbyval; to->attbyval = typeTup->typbyval;
to->attstorage = typeTup->typstorage;
to->attalign = typeTup->typalign; to->attalign = typeTup->typalign;
to->atttypmod = exprTypmod(indexkey); to->attstorage = typeTup->typstorage;
/* /*
* For expression columns, set attcompression invalid, since * For expression columns, set attcompression invalid, since
* there's no table column from which to copy the value. Whenever * there's no table column from which to copy the value. Whenever
* we actually need to compress a value, we'll use whatever the * we actually need to compress a value, we'll use whatever the
* current value of default_compression_method is at that point in * current value of default_toast_compression is at that point in
* time. * time.
*/ */
to->attcompression = InvalidCompressionMethod; to->attcompression = InvalidCompressionMethod;
...@@ -464,6 +464,8 @@ ConstructTupleDescriptor(Relation heapRelation, ...@@ -464,6 +464,8 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attbyval = typeTup->typbyval; to->attbyval = typeTup->typbyval;
to->attalign = typeTup->typalign; to->attalign = typeTup->typalign;
to->attstorage = typeTup->typstorage; to->attstorage = typeTup->typstorage;
/* As above, use the default compression method in this case */
to->attcompression = InvalidCompressionMethod;
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
} }
......
...@@ -2640,8 +2640,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence, ...@@ -2640,8 +2640,8 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
def->constraints = NIL; def->constraints = NIL;
def->location = -1; def->location = -1;
if (CompressionMethodIsValid(attribute->attcompression)) if (CompressionMethodIsValid(attribute->attcompression))
def->compression = pstrdup(GetCompressionMethodName( def->compression =
attribute->attcompression)); pstrdup(GetCompressionMethodName(attribute->attcompression));
else else
def->compression = NULL; def->compression = NULL;
inhSchema = lappend(inhSchema, def); inhSchema = lappend(inhSchema, def);
...@@ -6596,12 +6596,19 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, ...@@ -6596,12 +6596,19 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
attribute.atttypid = typeOid; attribute.atttypid = typeOid;
attribute.attstattarget = (newattnum > 0) ? -1 : 0; attribute.attstattarget = (newattnum > 0) ? -1 : 0;
attribute.attlen = tform->typlen; attribute.attlen = tform->typlen;
attribute.atttypmod = typmod;
attribute.attnum = newattnum; attribute.attnum = newattnum;
attribute.attbyval = tform->typbyval;
attribute.attndims = list_length(colDef->typeName->arrayBounds); attribute.attndims = list_length(colDef->typeName->arrayBounds);
attribute.attstorage = tform->typstorage; attribute.atttypmod = typmod;
attribute.attbyval = tform->typbyval;
attribute.attalign = tform->typalign; attribute.attalign = tform->typalign;
attribute.attstorage = tform->typstorage;
/* do not set compression in views etc */
if (rel->rd_rel->relkind == RELKIND_RELATION ||
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
attribute.attcompression = GetAttributeCompression(&attribute,
colDef->compression);
else
attribute.attcompression = InvalidCompressionMethod;
attribute.attnotnull = colDef->is_not_null; attribute.attnotnull = colDef->is_not_null;
attribute.atthasdef = false; attribute.atthasdef = false;
attribute.atthasmissing = false; attribute.atthasmissing = false;
...@@ -6612,17 +6619,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, ...@@ -6612,17 +6619,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
attribute.attinhcount = colDef->inhcount; attribute.attinhcount = colDef->inhcount;
attribute.attcollation = collOid; attribute.attcollation = collOid;
/*
* lookup attribute's compression method and store it in the
* attr->attcompression.
*/
if (rel->rd_rel->relkind == RELKIND_RELATION ||
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
attribute.attcompression = GetAttributeCompression(&attribute,
colDef->compression);
else
attribute.attcompression = InvalidCompressionMethod;
/* attribute.attacl is handled by InsertPgAttributeTuples() */ /* attribute.attacl is handled by InsertPgAttributeTuples() */
ReleaseSysCache(typeTuple); ReleaseSysCache(typeTuple);
......
...@@ -137,8 +137,8 @@ typedef struct SpGistTypeDesc ...@@ -137,8 +137,8 @@ typedef struct SpGistTypeDesc
Oid type; Oid type;
int16 attlen; int16 attlen;
bool attbyval; bool attbyval;
char attstorage;
char attalign; char attalign;
char attstorage;
} SpGistTypeDesc; } SpGistTypeDesc;
typedef struct SpGistState typedef struct SpGistState
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202105121 #define CATALOG_VERSION_NO 202105231
#endif #endif
...@@ -111,6 +111,12 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, ...@@ -111,6 +111,12 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
*/ */
bool attbyval; bool attbyval;
/*
* attalign is a copy of the typalign field from pg_type for this
* attribute. See atttypid comments above.
*/
char attalign;
/*---------- /*----------
* attstorage tells for VARLENA attributes, what the heap access * attstorage tells for VARLENA attributes, what the heap access
* methods can do to it if a given tuple doesn't fit into a page. * methods can do to it if a given tuple doesn't fit into a page.
...@@ -120,10 +126,10 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, ...@@ -120,10 +126,10 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
char attstorage; char attstorage;
/* /*
* attalign is a copy of the typalign field from pg_type for this * Compression method. Must be InvalidCompressionMethod if and only if
* attribute. See atttypid comments above. * typstorage is 'plain' or 'external'.
*/ */
char attalign; char attcompression BKI_DEFAULT('\0');
/* This flag represents the "NOT NULL" constraint */ /* This flag represents the "NOT NULL" constraint */
bool attnotnull; bool attnotnull;
...@@ -160,12 +166,6 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, ...@@ -160,12 +166,6 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
/* attribute's collation, if any */ /* attribute's collation, if any */
Oid attcollation BKI_LOOKUP_OPT(pg_collation); Oid attcollation BKI_LOOKUP_OPT(pg_collation);
/*
* compression method. Must be InvalidCompressionMethod if and only if
* typstorage is 'plain' or 'external'.
*/
char attcompression BKI_DEFAULT('\0');
#ifdef CATALOG_VARLEN /* variable-length fields start here */ #ifdef CATALOG_VARLEN /* variable-length fields start here */
/* NOTE: The following fields are not present in tuple descriptors. */ /* NOTE: The following fields are not present in tuple descriptors. */
...@@ -190,10 +190,10 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, ...@@ -190,10 +190,10 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
* ATTRIBUTE_FIXED_PART_SIZE is the size of the fixed-layout, * ATTRIBUTE_FIXED_PART_SIZE is the size of the fixed-layout,
* guaranteed-not-null part of a pg_attribute row. This is in fact as much * guaranteed-not-null part of a pg_attribute row. This is in fact as much
* of the row as gets copied into tuple descriptors, so don't expect you * of the row as gets copied into tuple descriptors, so don't expect you
* can access fields beyond attcollation except in a real tuple! * can access the variable-length fields except in a real tuple!
*/ */
#define ATTRIBUTE_FIXED_PART_SIZE \ #define ATTRIBUTE_FIXED_PART_SIZE \
(offsetof(FormData_pg_attribute,attcompression) + sizeof(char)) (offsetof(FormData_pg_attribute,attcollation) + sizeof(Oid))
/* ---------------- /* ----------------
* Form_pg_attribute corresponds to a pointer to a tuple with * Form_pg_attribute corresponds to a pointer to a tuple with
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment