mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Add relation option toast_value_type
This relation option gives the possibility to define the attribute type that can be used for chunk_id in a TOAST table when it is initially created. An update of this parameter has no effect if a TOAST table already exists under the relation, even on rewrites. It cannot be set for TOAST relations. This new option can be set only to "oid" as of this commit. This feature is extracted as a patch of its own to ease the introduction of a second mode in a follow-up change, related to the introduction of 8-byte OIDs in external TOAST pointers. Bump catalog version, as StdRdOptions has changed. Author: Michael Paquier <michael@paquier.xyz> Reviewed-by: Greg Burd <greg@burd.me> Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Yugo Nagata <nagata@sraoss.co.jp> Discussion: https://postgr.es/m/af19kUjwjhaoUTLn@paquier.xyz
This commit is contained in:
@@ -1653,6 +1653,32 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="reloption-toast-value-type" xreflabel="toast_value_type">
|
||||
<term><literal>toast_value_type</literal> (<type>enum</type>)
|
||||
<indexterm>
|
||||
<primary><varname>toast_value_type</varname> storage parameter</primary>
|
||||
</indexterm>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies the attribute type of <literal>chunk_id</literal> to use when
|
||||
creating a <acronym>TOAST</acronym> relation for this table. The
|
||||
default is <literal>oid</literal>.
|
||||
This parameter cannot be set for <acronym>TOAST</acronym> tables.
|
||||
</para>
|
||||
<para>
|
||||
The value is only consulted when the <acronym>TOAST</acronym> relation
|
||||
is created. Changing it afterwards has no effect on an existing
|
||||
<acronym>TOAST</acronym> relation, and a table rewrite such as
|
||||
<link linkend="sql-cluster"><command>CLUSTER</command></link> or
|
||||
<link linkend="sql-vacuum"><command>VACUUM FULL</command></link>
|
||||
preserves the type already in use. A dump and restore, on the other
|
||||
hand, recreates the <acronym>TOAST</acronym> relation and therefore
|
||||
applies the current value of this parameter.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="reloption-parallel-workers" xreflabel="parallel_workers">
|
||||
<term><literal>parallel_workers</literal> (<type>integer</type>)
|
||||
<indexterm>
|
||||
|
||||
@@ -548,6 +548,14 @@ static relopt_enum_elt_def viewCheckOptValues[] =
|
||||
{(const char *) NULL} /* list terminator */
|
||||
};
|
||||
|
||||
/* values from StdRdOptToastValueType */
|
||||
static relopt_enum_elt_def StdRdOptToastValueTypes[] =
|
||||
{
|
||||
/* no value for INVALID */
|
||||
{"oid", STDRD_OPTION_TOAST_VALUE_TYPE_OID},
|
||||
{(const char *) NULL} /* list terminator */
|
||||
};
|
||||
|
||||
static relopt_enum enumRelOpts[] =
|
||||
{
|
||||
{
|
||||
@@ -561,6 +569,17 @@ static relopt_enum enumRelOpts[] =
|
||||
STDRD_OPTION_VACUUM_INDEX_CLEANUP_NOT_SET,
|
||||
gettext_noop("Valid values are \"on\", \"off\", and \"auto\".")
|
||||
},
|
||||
{
|
||||
{
|
||||
"toast_value_type",
|
||||
"Controls the attribute type of chunk_id at toast table creation",
|
||||
RELOPT_KIND_HEAP,
|
||||
ShareUpdateExclusiveLock
|
||||
},
|
||||
StdRdOptToastValueTypes,
|
||||
STDRD_OPTION_TOAST_VALUE_TYPE_OID,
|
||||
gettext_noop("Valid values are \"oid\".")
|
||||
},
|
||||
{
|
||||
{
|
||||
"buffering",
|
||||
@@ -2078,6 +2097,8 @@ static const relopt_parse_elt stdRdOptionsTab[] = {
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_analyze_min_duration)},
|
||||
{"toast_tuple_target", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, toast_tuple_target)},
|
||||
{"toast_value_type", RELOPT_TYPE_ENUM,
|
||||
offsetof(StdRdOptions, toast_value_type)},
|
||||
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)},
|
||||
{"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,
|
||||
|
||||
@@ -159,9 +159,25 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
|
||||
*/
|
||||
if (!IsBinaryUpgrade)
|
||||
{
|
||||
StdRdOptToastValueType value_type;
|
||||
|
||||
/* Normal mode, normal check */
|
||||
if (!needs_toast_table(rel))
|
||||
return false;
|
||||
|
||||
value_type = RelationGetToastValueType(rel, STDRD_OPTION_TOAST_VALUE_TYPE_OID);
|
||||
|
||||
/* no default clause to catch new values added */
|
||||
switch (value_type)
|
||||
{
|
||||
case STDRD_OPTION_TOAST_VALUE_TYPE_OID:
|
||||
toast_chunkid_typid = OIDOID;
|
||||
break;
|
||||
case STDRD_OPTION_TOAST_VALUE_TYPE_INVALID:
|
||||
elog(ERROR, "unexpected toast_value_type value %d",
|
||||
value_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1441,6 +1441,7 @@ static const char *const table_storage_parameters[] = {
|
||||
"toast.vacuum_max_eager_freeze_failure_rate",
|
||||
"toast.vacuum_truncate",
|
||||
"toast_tuple_target",
|
||||
"toast_value_type",
|
||||
"user_catalog_table",
|
||||
"vacuum_index_cleanup",
|
||||
"vacuum_max_eager_freeze_failure_rate",
|
||||
|
||||
@@ -57,6 +57,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202609111
|
||||
#define CATALOG_VERSION_NO 202609112
|
||||
|
||||
#endif
|
||||
|
||||
@@ -341,11 +341,20 @@ typedef enum StdRdOptIndexCleanup
|
||||
STDRD_OPTION_VACUUM_INDEX_CLEANUP_NOT_SET,
|
||||
} StdRdOptIndexCleanup;
|
||||
|
||||
/* StdRdOptions->toast_value_type values */
|
||||
typedef enum StdRdOptToastValueType
|
||||
{
|
||||
STDRD_OPTION_TOAST_VALUE_TYPE_INVALID = 0,
|
||||
STDRD_OPTION_TOAST_VALUE_TYPE_OID,
|
||||
} StdRdOptToastValueType;
|
||||
|
||||
typedef struct StdRdOptions
|
||||
{
|
||||
int32 vl_len_; /* varlena header (do not touch directly!) */
|
||||
int fillfactor; /* page fill factor in percent (0..100) */
|
||||
int toast_tuple_target; /* target for tuple toasting */
|
||||
StdRdOptToastValueType toast_value_type; /* type assigned to chunk_id
|
||||
* at toast table creation */
|
||||
AutoVacOpts autovacuum; /* autovacuum-related options */
|
||||
bool user_catalog_table; /* use as an additional catalog relation */
|
||||
int parallel_workers; /* max number of parallel workers */
|
||||
@@ -370,6 +379,14 @@ typedef struct StdRdOptions
|
||||
((relation)->rd_options ? \
|
||||
((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
|
||||
|
||||
/*
|
||||
* RelationGetToastValueType
|
||||
* Returns the relation's toast_value_type. Note multiple eval of argument!
|
||||
*/
|
||||
#define RelationGetToastValueType(relation, defaulttarg) \
|
||||
((relation)->rd_options ? \
|
||||
((StdRdOptions *) (relation)->rd_options)->toast_value_type : (defaulttarg))
|
||||
|
||||
/*
|
||||
* RelationGetFillFactor
|
||||
* Returns the relation's fillfactor. Note multiple eval of argument!
|
||||
|
||||
@@ -194,6 +194,28 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid;
|
||||
-- Fail on non-existent options in toast namespace
|
||||
CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42);
|
||||
ERROR: unrecognized parameter "not_existing_option"
|
||||
-- Test toast_value_type.
|
||||
CREATE TABLE reloptions_test2 (s VARCHAR) WITH (toast.toast_value_type = 'oid');
|
||||
ERROR: unrecognized parameter "toast_value_type"
|
||||
CREATE TABLE reloptions_test2 (s VARCHAR) WITH (toast_value_type = 'int8');
|
||||
ERROR: invalid value for enum option "toast_value_type": int8
|
||||
DETAIL: Valid values are "oid".
|
||||
CREATE TABLE reloptions_test2 (s VARCHAR) WITH (toast_value_type = 'oid');
|
||||
SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test2'::regclass;
|
||||
reloptions
|
||||
------------------------
|
||||
{toast_value_type=oid}
|
||||
(1 row)
|
||||
|
||||
DROP TABLE reloptions_test2;
|
||||
-- relkinds not supported.
|
||||
CREATE INDEX reloptions_test_idx0 ON reloptions_test (s)
|
||||
WITH (toast_value_type = 'oid');
|
||||
ERROR: unrecognized parameter "toast_value_type"
|
||||
CREATE TABLE reloptions_test2 (i int) PARTITION BY RANGE (i)
|
||||
WITH (toast_value_type = 'oid');
|
||||
ERROR: cannot specify storage parameters for a partitioned table
|
||||
HINT: Specify storage parameters for its leaf partitions instead.
|
||||
-- Mix TOAST & heap
|
||||
DROP TABLE reloptions_test;
|
||||
CREATE TABLE reloptions_test (s VARCHAR) WITH
|
||||
|
||||
@@ -112,6 +112,18 @@ SELECT reloptions FROM pg_class WHERE oid = :toast_oid;
|
||||
-- Fail on non-existent options in toast namespace
|
||||
CREATE TABLE reloptions_test2 (i int) WITH (toast.not_existing_option = 42);
|
||||
|
||||
-- Test toast_value_type.
|
||||
CREATE TABLE reloptions_test2 (s VARCHAR) WITH (toast.toast_value_type = 'oid');
|
||||
CREATE TABLE reloptions_test2 (s VARCHAR) WITH (toast_value_type = 'int8');
|
||||
CREATE TABLE reloptions_test2 (s VARCHAR) WITH (toast_value_type = 'oid');
|
||||
SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test2'::regclass;
|
||||
DROP TABLE reloptions_test2;
|
||||
-- relkinds not supported.
|
||||
CREATE INDEX reloptions_test_idx0 ON reloptions_test (s)
|
||||
WITH (toast_value_type = 'oid');
|
||||
CREATE TABLE reloptions_test2 (i int) PARTITION BY RANGE (i)
|
||||
WITH (toast_value_type = 'oid');
|
||||
|
||||
-- Mix TOAST & heap
|
||||
DROP TABLE reloptions_test;
|
||||
|
||||
|
||||
@@ -3000,6 +3000,7 @@ StatsElem
|
||||
StatsExtInfo
|
||||
StdAnalyzeData
|
||||
StdRdOptIndexCleanup
|
||||
StdRdOptToastValueType
|
||||
StdRdOptions
|
||||
Step
|
||||
StopList
|
||||
|
||||
Reference in New Issue
Block a user