Currently TOAST table is always created (if needed based on data type
properties) independent of table AM. How toasting is handled seems
should be AM responsibility. Generic code shouldn't force the use of
the separate table for the same. Like for Zedstore we store toasted
chunks in separate blocks but within the table file itself and don't
need separate toast table. Some other AM may implement the
functionality differently. So, similar to relation forks, usage of
toast table should be optional and left to AM to handle.

Wish to discuss ways on how best to achieve it. Attaching patch just
to showcase a way could be done. The patch adds property to
TableAmRoutine to convey if AM uses separate Toast table or not.

Other possibility could be with some refactoring move toast table
creation inside relation_set_new_filenode callback or provide separate
callback for Toast Table creation to AM.
From fcbf6b8187ef8389cf38cd185b709bcb6ef1152a Mon Sep 17 00:00:00 2001
From: Ashwin Agrawal <aagra...@pivotal.io>
Date: Fri, 10 May 2019 17:42:06 -0700
Subject: [PATCH 1/1] Create toast table only if AM needs it.

All AM may not need toast table, hence add property to TableAmRoutine
to define if uses toast table or not. Only for AM using the toast
table create the toast table, otherwise skip the same. Heap AM sets
the property as true.
---
 src/backend/access/heap/heapam_handler.c | 1 +
 src/backend/catalog/toasting.c           | 5 +++++
 src/include/access/tableam.h             | 7 +++++++
 3 files changed, 13 insertions(+)

diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 00505ec3f4d..243a221c923 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -2515,6 +2515,7 @@ SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer,
 
 static const TableAmRoutine heapam_methods = {
 	.type = T_TableAmRoutine,
+	.uses_toast_table = true,
 
 	.slot_callbacks = heapam_slot_callbacks,
 
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 2276d3c5d36..2345ef8ee84 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -407,6 +407,11 @@ needs_toast_table(Relation rel)
 	if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
 		return false;
 
+	Assert(rel->rd_tableam != NULL);
+	/* No need to create TOAST table if AM doesn't need one */
+	if (!table_uses_toast_table(rel))
+		return false;
+
 	/*
 	 * We cannot allow toasting a shared relation after initdb (because
 	 * there's no way to mark it toasted in other databases' pg_class).
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index ebfa0d51855..ed116e18f10 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -142,6 +142,8 @@ typedef struct TableAmRoutine
 {
 	/* this must be set to T_TableAmRoutine */
 	NodeTag		type;
+	/* does AM need separate TOAST table */
+	bool uses_toast_table;
 
 
 	/* ------------------------------------------------------------------------
@@ -657,6 +659,11 @@ typedef struct TableAmRoutine
 
 } TableAmRoutine;
 
+static inline bool
+table_uses_toast_table(Relation relation)
+{
+	return relation->rd_tableam->uses_toast_table;
+}
 
 /* ----------------------------------------------------------------------------
  * Slot functions.
-- 
2.19.1

Reply via email to