diff options
author | Robert Haas <rhaas@postgresql.org> | 2019-05-21 11:57:13 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2019-05-21 11:57:13 -0400 |
commit | 1171d7d58545f26a402f76a05936d572bf29d53b (patch) | |
tree | 5850b9d8f0ad037579c1f39d91fbae972b9b4825 /src/backend | |
parent | cf92226e9f7f985a678287167b954a831a3b660c (diff) | |
download | postgresql-1171d7d58545f26a402f76a05936d572bf29d53b.tar.gz postgresql-1171d7d58545f26a402f76a05936d572bf29d53b.zip |
tableam: Move heap-specific logic from needs_toast_table below tableam.
This allows table AMs to completely suppress TOAST table creation, or
to modify the conditions under which they are created.
Patch by me. Reviewed by Andres Freund.
Discussion: http://postgr.es/m/CA+Tgmoa4O2n=yphqD2pERUnYmUO84bH1SqMsA-nSxBGsZ7gWfA@mail.gmail.com
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/heap/heapam_handler.c | 53 | ||||
-rw-r--r-- | src/backend/catalog/toasting.c | 50 |
2 files changed, 56 insertions, 47 deletions
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 8d8161fd971..56b2abda5fb 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -29,6 +29,7 @@ #include "access/rewriteheap.h" #include "access/tableam.h" #include "access/tsmapi.h" +#include "access/tuptoaster.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/index.h" @@ -2009,6 +2010,57 @@ heapam_relation_size(Relation rel, ForkNumber forkNumber) return nblocks * BLCKSZ; } +/* + * Check to see whether the table needs a TOAST table. It does only if + * (1) there are any toastable attributes, and (2) the maximum length + * of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to + * create a toast table for something like "f1 varchar(20)".) + */ +static bool +heapam_relation_needs_toast_table(Relation rel) +{ + int32 data_length = 0; + bool maxlength_unknown = false; + bool has_toastable_attrs = false; + TupleDesc tupdesc = rel->rd_att; + int32 tuple_length; + int i; + + for (i = 0; i < tupdesc->natts; i++) + { + Form_pg_attribute att = TupleDescAttr(tupdesc, i); + + if (att->attisdropped) + continue; + data_length = att_align_nominal(data_length, att->attalign); + if (att->attlen > 0) + { + /* Fixed-length types are never toastable */ + data_length += att->attlen; + } + else + { + int32 maxlen = type_maximum_size(att->atttypid, + att->atttypmod); + + if (maxlen < 0) + maxlength_unknown = true; + else + data_length += maxlen; + if (att->attstorage != 'p') + has_toastable_attrs = true; + } + } + if (!has_toastable_attrs) + return false; /* nothing to toast? */ + if (maxlength_unknown) + return true; /* any unlimited-length attrs? */ + tuple_length = MAXALIGN(SizeofHeapTupleHeader + + BITMAPLEN(tupdesc->natts)) + + MAXALIGN(data_length); + return (tuple_length > TOAST_TUPLE_THRESHOLD); +} + /* ------------------------------------------------------------------------ * Planner related callbacks for the heap AM @@ -2592,6 +2644,7 @@ static const TableAmRoutine heapam_methods = { .index_validate_scan = heapam_index_validate_scan, .relation_size = heapam_relation_size, + .relation_needs_toast_table = heapam_relation_needs_toast_table, .relation_estimate_size = heapam_estimate_rel_size, diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 2276d3c5d36..cf20ddb4e92 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -15,7 +15,6 @@ #include "postgres.h" #include "access/heapam.h" -#include "access/tuptoaster.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" #include "catalog/catalog.h" @@ -386,21 +385,11 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, } /* - * Check to see whether the table needs a TOAST table. It does only if - * (1) there are any toastable attributes, and (2) the maximum length - * of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to - * create a toast table for something like "f1 varchar(20)".) + * Check to see whether the table needs a TOAST table. */ static bool needs_toast_table(Relation rel) { - int32 data_length = 0; - bool maxlength_unknown = false; - bool has_toastable_attrs = false; - TupleDesc tupdesc; - int32 tuple_length; - int i; - /* * No need to create a TOAST table for partitioned tables. */ @@ -423,39 +412,6 @@ needs_toast_table(Relation rel) if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode()) return false; - tupdesc = rel->rd_att; - - for (i = 0; i < tupdesc->natts; i++) - { - Form_pg_attribute att = TupleDescAttr(tupdesc, i); - - if (att->attisdropped) - continue; - data_length = att_align_nominal(data_length, att->attalign); - if (att->attlen > 0) - { - /* Fixed-length types are never toastable */ - data_length += att->attlen; - } - else - { - int32 maxlen = type_maximum_size(att->atttypid, - att->atttypmod); - - if (maxlen < 0) - maxlength_unknown = true; - else - data_length += maxlen; - if (att->attstorage != 'p') - has_toastable_attrs = true; - } - } - if (!has_toastable_attrs) - return false; /* nothing to toast? */ - if (maxlength_unknown) - return true; /* any unlimited-length attrs? */ - tuple_length = MAXALIGN(SizeofHeapTupleHeader + - BITMAPLEN(tupdesc->natts)) + - MAXALIGN(data_length); - return (tuple_length > TOAST_TUPLE_THRESHOLD); + /* Otherwise, let the AM decide. */ + return table_relation_needs_toast_table(rel); } |