git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: cf92226)
tableam: Move heap-specific logic from needs_toast_table below tableam.
2019年5月21日 15:57:13 +0000 (11:57 -0400)
2019年5月21日 15:57:13 +0000 (11:57 -0400)
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


diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 8d8161fd9717f6c01f7f05f958d153969b9be54c..56b2abda5fb086d11ec0573d83d9319ab29d8c9c 100644 (file)
--- 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 2276d3c5d36ce7db059ecea85142858b4a66a3d6..cf20ddb4e928e95974b61da6b2dc5900ae9bb927 100644 (file)
--- 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);
}
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 06eae2337a3bf031d185b60c32950f2ed2e16297..53b58c51da218cd98c7dea7281eb5862812ff7fb 100644 (file)
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -573,6 +573,16 @@ typedef struct TableAmRoutine
uint64 (*relation_size) (Relation rel, ForkNumber forkNumber);
+ /*
+ * This callback should return true if the relation requires a TOAST table
+ * and false if it does not. It may wish to examine the relation's
+ * tuple descriptor before making a decision, but if it uses some other
+ * method of storing large values (or if it does not support them) it can
+ * simply return false.
+ */
+ bool (*relation_needs_toast_table) (Relation rel);
+
+
/* ------------------------------------------------------------------------
* Planner related functions.
* ------------------------------------------------------------------------
@@ -1585,6 +1595,16 @@ table_relation_size(Relation rel, ForkNumber forkNumber)
return rel->rd_tableam->relation_size(rel, forkNumber);
}
+/*
+ * table_needs_toast_table - does this relation need a toast table?
+ */
+static inline bool
+table_relation_needs_toast_table(Relation rel)
+{
+ return rel->rd_tableam->relation_needs_toast_table(rel);
+}
+
+
/* ----------------------------------------------------------------------------
* Planner related functionality
* ----------------------------------------------------------------------------
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /