Hi, > + > +/* > + * 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_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); > +}
I'm ok with adding something roughly like this. > /* ------------------------------------------------------------------------ > * Planner related callbacks for the heap AM > @@ -2558,6 +2615,8 @@ static const TableAmRoutine heapam_methods = { > > .relation_estimate_size = heapam_estimate_rel_size, > > + .needs_toast_table = heapam_needs_toast_table, > + I'd rather see this have a relation_ prefix. Greetings, Andres Freund