Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1171d7d

Browse files
committed
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
1 parent cf92226 commit 1171d7d

File tree

3 files changed

+76
-47
lines changed

3 files changed

+76
-47
lines changed

src/backend/access/heap/heapam_handler.c

+53
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "access/rewriteheap.h"
3030
#include "access/tableam.h"
3131
#include "access/tsmapi.h"
32+
#include "access/tuptoaster.h"
3233
#include "access/xact.h"
3334
#include "catalog/catalog.h"
3435
#include "catalog/index.h"
@@ -2009,6 +2010,57 @@ heapam_relation_size(Relation rel, ForkNumber forkNumber)
20092010
return nblocks * BLCKSZ;
20102011
}
20112012

2013+
/*
2014+
* Check to see whether the table needs a TOAST table. It does only if
2015+
* (1) there are any toastable attributes, and (2) the maximum length
2016+
* of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to
2017+
* create a toast table for something like "f1 varchar(20)".)
2018+
*/
2019+
static bool
2020+
heapam_relation_needs_toast_table(Relation rel)
2021+
{
2022+
int32 data_length = 0;
2023+
bool maxlength_unknown = false;
2024+
bool has_toastable_attrs = false;
2025+
TupleDesc tupdesc = rel->rd_att;
2026+
int32 tuple_length;
2027+
int i;
2028+
2029+
for (i = 0; i < tupdesc->natts; i++)
2030+
{
2031+
Form_pg_attribute att = TupleDescAttr(tupdesc, i);
2032+
2033+
if (att->attisdropped)
2034+
continue;
2035+
data_length = att_align_nominal(data_length, att->attalign);
2036+
if (att->attlen > 0)
2037+
{
2038+
/* Fixed-length types are never toastable */
2039+
data_length += att->attlen;
2040+
}
2041+
else
2042+
{
2043+
int32 maxlen = type_maximum_size(att->atttypid,
2044+
att->atttypmod);
2045+
2046+
if (maxlen < 0)
2047+
maxlength_unknown = true;
2048+
else
2049+
data_length += maxlen;
2050+
if (att->attstorage != 'p')
2051+
has_toastable_attrs = true;
2052+
}
2053+
}
2054+
if (!has_toastable_attrs)
2055+
return false; /* nothing to toast? */
2056+
if (maxlength_unknown)
2057+
return true; /* any unlimited-length attrs? */
2058+
tuple_length = MAXALIGN(SizeofHeapTupleHeader +
2059+
BITMAPLEN(tupdesc->natts)) +
2060+
MAXALIGN(data_length);
2061+
return (tuple_length > TOAST_TUPLE_THRESHOLD);
2062+
}
2063+
20122064

20132065
/* ------------------------------------------------------------------------
20142066
* Planner related callbacks for the heap AM
@@ -2592,6 +2644,7 @@ static const TableAmRoutine heapam_methods = {
25922644
.index_validate_scan = heapam_index_validate_scan,
25932645

25942646
.relation_size = heapam_relation_size,
2647+
.relation_needs_toast_table = heapam_relation_needs_toast_table,
25952648

25962649
.relation_estimate_size = heapam_estimate_rel_size,
25972650

src/backend/catalog/toasting.c

+3-47
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "postgres.h"
1616

1717
#include "access/heapam.h"
18-
#include "access/tuptoaster.h"
1918
#include "access/xact.h"
2019
#include "catalog/binary_upgrade.h"
2120
#include "catalog/catalog.h"
@@ -386,21 +385,11 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
386385
}
387386

388387
/*
389-
* Check to see whether the table needs a TOAST table. It does only if
390-
* (1) there are any toastable attributes, and (2) the maximum length
391-
* of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to
392-
* create a toast table for something like "f1 varchar(20)".)
388+
* Check to see whether the table needs a TOAST table.
393389
*/
394390
static bool
395391
needs_toast_table(Relation rel)
396392
{
397-
int32 data_length = 0;
398-
bool maxlength_unknown = false;
399-
bool has_toastable_attrs = false;
400-
TupleDesc tupdesc;
401-
int32 tuple_length;
402-
int i;
403-
404393
/*
405394
* No need to create a TOAST table for partitioned tables.
406395
*/
@@ -423,39 +412,6 @@ needs_toast_table(Relation rel)
423412
if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode())
424413
return false;
425414

426-
tupdesc = rel->rd_att;
427-
428-
for (i = 0; i < tupdesc->natts; i++)
429-
{
430-
Form_pg_attribute att = TupleDescAttr(tupdesc, i);
431-
432-
if (att->attisdropped)
433-
continue;
434-
data_length = att_align_nominal(data_length, att->attalign);
435-
if (att->attlen > 0)
436-
{
437-
/* Fixed-length types are never toastable */
438-
data_length += att->attlen;
439-
}
440-
else
441-
{
442-
int32 maxlen = type_maximum_size(att->atttypid,
443-
att->atttypmod);
444-
445-
if (maxlen < 0)
446-
maxlength_unknown = true;
447-
else
448-
data_length += maxlen;
449-
if (att->attstorage != 'p')
450-
has_toastable_attrs = true;
451-
}
452-
}
453-
if (!has_toastable_attrs)
454-
return false; /* nothing to toast? */
455-
if (maxlength_unknown)
456-
return true; /* any unlimited-length attrs? */
457-
tuple_length = MAXALIGN(SizeofHeapTupleHeader +
458-
BITMAPLEN(tupdesc->natts)) +
459-
MAXALIGN(data_length);
460-
return (tuple_length > TOAST_TUPLE_THRESHOLD);
415+
/* Otherwise, let the AM decide. */
416+
return table_relation_needs_toast_table(rel);
461417
}

src/include/access/tableam.h

+20
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,16 @@ typedef struct TableAmRoutine
573573
uint64 (*relation_size) (Relation rel, ForkNumber forkNumber);
574574

575575

576+
/*
577+
* This callback should return true if the relation requires a TOAST table
578+
* and false if it does not. It may wish to examine the relation's
579+
* tuple descriptor before making a decision, but if it uses some other
580+
* method of storing large values (or if it does not support them) it can
581+
* simply return false.
582+
*/
583+
bool (*relation_needs_toast_table) (Relation rel);
584+
585+
576586
/* ------------------------------------------------------------------------
577587
* Planner related functions.
578588
* ------------------------------------------------------------------------
@@ -1585,6 +1595,16 @@ table_relation_size(Relation rel, ForkNumber forkNumber)
15851595
return rel->rd_tableam->relation_size(rel, forkNumber);
15861596
}
15871597

1598+
/*
1599+
* table_needs_toast_table - does this relation need a toast table?
1600+
*/
1601+
static inline bool
1602+
table_relation_needs_toast_table(Relation rel)
1603+
{
1604+
return rel->rd_tableam->relation_needs_toast_table(rel);
1605+
}
1606+
1607+
15881608
/* ----------------------------------------------------------------------------
15891609
* Planner related functionality
15901610
* ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)