*/
CommandCounterIncrement();
+ /*
+ * Create a TOAST table if the table needs one. MERGE/SPLIT PARTITION
+ * moves rows from existing partition(s) into new partition(s), which may
+ * carry out-of-line varlena values that the new relation must be able to
+ * store. Also, the new partition must be able to receive out-of-line
+ * varlena values after the DDL operation is complete.
+ */
+ NewRelationCreateToastTable(newRelId, (Datum) 0);
+
/*
* Open the new partition with no lock, because we already have an
* AccessExclusiveLock placed there after creation.
1
(1 row)
+DROP TABLE t;
+-- A merged partition needs its own TOAST table; otherwise an out-of-line
+-- varlena value carried over from one of the merging partitions has
+-- nowhere to be stored. SET STORAGE EXTERNAL forces externalization
+-- for any value over the TOAST threshold, so a string over that threshold
+-- suffices to exercise the toast-table dependency.
+CREATE TABLE t (a text) PARTITION BY RANGE(a);
+ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL;
+CREATE TABLE tp_def PARTITION OF t DEFAULT;
+CREATE TABLE tp_2_3 PARTITION OF t FOR VALUES FROM ('2') TO ('3');
+INSERT INTO t SELECT repeat('1', 10000);
+ALTER TABLE t MERGE PARTITIONS (tp_def, tp_2_3) INTO tp_merged;
+SELECT reltoastrelid <> 0 AS has_toast,
+ pg_relation_size(reltoastrelid) > 0 AS toast_used
+ FROM pg_class WHERE relname = 'tp_merged';
+ has_toast | toast_used
+-----------+------------
+ t | t
+(1 row)
+
+SELECT length(a) FROM t;
+ length
+--------
+ 10000
+(1 row)
+
DROP TABLE t;
RESET search_path;
--
0
(1 row)
+DROP TABLE t;
+-- Each new partition produced by SPLIT must get its own TOAST table so
+-- that out-of-line varlena attributes coming from the source partition
+-- can be stored. SET STORAGE EXTERNAL forces externalization for any
+-- value over the TOAST threshold, so a string over that threshold
+-- suffices to exercise the toast-table dependency.
+CREATE TABLE t (a text) PARTITION BY RANGE(a);
+ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL;
+CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (MINVALUE) TO (MAXVALUE);
+INSERT INTO t SELECT repeat('1', 10000);
+ALTER TABLE t SPLIT PARTITION tp_all INTO (
+ PARTITION tp_lo FOR VALUES FROM (MINVALUE) TO ('2'),
+ PARTITION tp_hi FOR VALUES FROM ('2') TO (MAXVALUE)
+);
+SELECT relname,
+ reltoastrelid <> 0 AS has_toast,
+ pg_relation_size(reltoastrelid) > 0 AS toast_used
+ FROM pg_class WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname;
+ relname | has_toast | toast_used
+---------+-----------+------------
+ tp_hi | t | f
+ tp_lo | t | t
+(2 rows)
+
+SELECT length(a) FROM t;
+ length
+--------
+ 10000
+(1 row)
+
DROP TABLE t;
RESET search_path;
--
DROP TABLE t;
+-- A merged partition needs its own TOAST table; otherwise an out-of-line
+-- varlena value carried over from one of the merging partitions has
+-- nowhere to be stored. SET STORAGE EXTERNAL forces externalization
+-- for any value over the TOAST threshold, so a string over that threshold
+-- suffices to exercise the toast-table dependency.
+CREATE TABLE t (a text) PARTITION BY RANGE(a);
+ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL;
+CREATE TABLE tp_def PARTITION OF t DEFAULT;
+CREATE TABLE tp_2_3 PARTITION OF t FOR VALUES FROM ('2') TO ('3');
+INSERT INTO t SELECT repeat('1', 10000);
+ALTER TABLE t MERGE PARTITIONS (tp_def, tp_2_3) INTO tp_merged;
+SELECT reltoastrelid <> 0 AS has_toast,
+ pg_relation_size(reltoastrelid) > 0 AS toast_used
+ FROM pg_class WHERE relname = 'tp_merged';
+SELECT length(a) FROM t;
+DROP TABLE t;
+
RESET search_path;
DROP TABLE t;
+-- Each new partition produced by SPLIT must get its own TOAST table so
+-- that out-of-line varlena attributes coming from the source partition
+-- can be stored. SET STORAGE EXTERNAL forces externalization for any
+-- value over the TOAST threshold, so a string over that threshold
+-- suffices to exercise the toast-table dependency.
+CREATE TABLE t (a text) PARTITION BY RANGE(a);
+ALTER TABLE t ALTER COLUMN a SET STORAGE EXTERNAL;
+CREATE TABLE tp_all PARTITION OF t FOR VALUES FROM (MINVALUE) TO (MAXVALUE);
+INSERT INTO t SELECT repeat('1', 10000);
+ALTER TABLE t SPLIT PARTITION tp_all INTO (
+ PARTITION tp_lo FOR VALUES FROM (MINVALUE) TO ('2'),
+ PARTITION tp_hi FOR VALUES FROM ('2') TO (MAXVALUE)
+);
+SELECT relname,
+ reltoastrelid <> 0 AS has_toast,
+ pg_relation_size(reltoastrelid) > 0 AS toast_used
+ FROM pg_class WHERE relname IN ('tp_lo', 'tp_hi') ORDER BY relname;
+SELECT length(a) FROM t;
+DROP TABLE t;
RESET search_path;