diff options
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); } |