|
|
|
@ -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, |
|
|
|
|
|
|
|
|
|