v6-0002-fixup-create-table-like-incluing-parameters.patch
text/x-patch
Filename: v6-0002-fixup-create-table-like-incluing-parameters.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v6-0002
Subject: fixup! create table like incluing parameters
| File | + | − |
|---|---|---|
| src/backend/access/common/reloptions.c | 3 | 37 |
| src/backend/parser/parse_utilcmd.c | 15 | 18 |
| src/include/access/reloptions.h | 1 | 1 |
| src/test/regress/expected/create_table_like.out | 23 | 26 |
| src/test/regress/sql/create_table_like.sql | 18 | 18 |
From a87da89dea951c78b62e796eb13e4f75f171a6c8 Mon Sep 17 00:00:00 2001
From: Euler Taveira <euler@eulerto.com>
Date: Mon, 15 Dec 2025 11:11:43 -0300
Subject: [PATCH v6 2/2] fixup! create table like incluing parameters
---
src/backend/access/common/reloptions.c | 40 ++-------------
src/backend/parser/parse_utilcmd.c | 33 ++++++-------
src/include/access/reloptions.h | 2 +-
.../regress/expected/create_table_like.out | 49 +++++++++----------
src/test/regress/sql/create_table_like.sql | 36 +++++++-------
5 files changed, 60 insertions(+), 100 deletions(-)
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 9289caef7ba..93db86acad3 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -1359,48 +1359,14 @@ transformRelOptions(Datum oldOptions, List *defList, const char *nameSpace,
List *
untransformRelOptions(Datum options)
{
- List *result = NIL;
- ArrayType *array;
- Datum *optiondatums;
- int noptions;
- int i;
-
- /* Nothing to do if no options */
- if (DatumGetPointer(options) == NULL)
- return result;
-
- array = DatumGetArrayTypeP(options);
-
- deconstruct_array_builtin(array, TEXTOID, &optiondatums, NULL, &noptions);
-
- for (i = 0; i < noptions; i++)
- {
- char *s;
- char *p;
- Node *val = NULL;
-
- s = TextDatumGetCString(optiondatums[i]);
- p = strchr(s, '=');
- if (p)
- {
- *p++ = '\0';
- val = (Node *) makeString(p);
- }
- result = lappend(result, makeDefElem(s, val, -1));
- }
-
- return result;
+ return untransformRelOptionsExtended(options, NULL);
}
/*
- * Convert the reloptions from text-array format into a List of DefElem. This
- * is the reverse operation of transformRelOptions().
- *
- * If any option includes a namespace qualification, create the DefElem in that
- * namespace, otherwise this behave the same as untransformRelOptions.
+ * Same as untransformRelOptions() but includes a namespace into DefElem.
*/
List *
-untransformRelOptionsExtended(Datum options, char* nameSpace)
+untransformRelOptionsExtended(Datum options, char *nameSpace)
{
List *result = NIL;
ArrayType *array;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 2e77c2db19b..c9056c4f22e 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -88,7 +88,8 @@ typedef struct
List *fkconstraints; /* FOREIGN KEY constraints */
List *ixconstraints; /* index-creating constraints */
List *likeclauses; /* LIKE clauses that need post-processing */
- List *options; /* options from WITH clause, table AM specific parameters */
+ List *options; /* options from WITH clause, table AM specific
+ * parameters */
List *blist; /* "before list" of things to do before
* creating the table */
List *alist; /* "after list" of things to do after creating
@@ -1125,8 +1126,8 @@ transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint)
* table has been created.
*
* Some options are ignored. For example, as foreign tables have no storage,
- * these INCLUDING options have no effect: STORAGE, COMPRESSION, IDENTITY
- * and INDEXES. Similarly, INCLUDING INDEXES is ignored from a view.
+ * these INCLUDING options have no effect: STORAGE, COMPRESSION, IDENTITY,
+ * INDEXES and PARAMETERS. Similarly, INCLUDING INDEXES is ignored from a view.
*/
static void
transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_clause)
@@ -1274,17 +1275,16 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
}
}
- /* Likewise, copy stoarge paramters if requested */
+ /* Likewise, copy storage parameters if requested */
if ((table_like_clause->options & CREATE_TABLE_LIKE_PARAMETERS) &&
!cxt->isforeign)
{
HeapTuple tuple;
- HeapTuple toast_tuple;
Datum reloptions;
bool isnull;
Oid relid;
- List *oldoptions = NIL;
- List *oldtoastoptions = NIL;
+ List *oldoptions = NIL;
+ List *oldtoastoptions = NIL;
relid = RelationGetRelid(relation);
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
@@ -1308,7 +1308,6 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
if (OidIsValid(relation->rd_rel->reltoastrelid))
{
Relation toastrel;
-
Oid toastid = relation->rd_rel->reltoastrelid;
/*
@@ -1317,14 +1316,12 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
*/
toastrel = table_open(toastid, AccessShareLock);
- /* Fetch heap tuple */
- toast_tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid));
+ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid));
- if (!HeapTupleIsValid(toast_tuple))
- elog(ERROR, "cache lookup failed for toast relation %u", toastid);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for relation %u", toastid);
- /* Get the toast reloptions */
- reloptions = SysCacheGetAttr(RELOID, toast_tuple, Anum_pg_class_reloptions,
+ reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
&isnull);
if (!isnull)
{
@@ -1334,12 +1331,12 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
cxt->options = lappend(cxt->options, option);
}
- ReleaseSysCache(toast_tuple);
+ ReleaseSysCache(tuple);
/*
- * Close the parent TOAST rel, but keep our AccessShareLock on it
- * until xact commit. That will prevent someone else from deleting
- * or ALTERing the parent TOAST before we can run
+ * Close the toast relation, but keep our AccessShareLock on it
+ * until xact commit. That will prevent someone else from
+ * deleting or ALTERing the parent TOAST before we can run
* expandTableLikeClause.
*/
table_close(toastrel, NoLock);
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 8589616d08b..0c29f5df229 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -236,7 +236,7 @@ extern Datum transformRelOptions(Datum oldOptions, List *defList,
const char *nameSpace, const char *const validnsps[],
bool acceptOidsOff, bool isReset);
extern List *untransformRelOptions(Datum options);
-extern List *untransformRelOptionsExtended(Datum options, char* nameSpace);
+extern List *untransformRelOptionsExtended(Datum options, char *nameSpace);
extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
amoptions_function amoptions);
extern void *build_reloptions(Datum reloptions, bool validate,
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index 3eb079e24ed..89145882aef 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -700,18 +700,18 @@ DROP FOREIGN TABLE ctl_foreign_table2;
DROP FOREIGN DATA WRAPPER ctl_dummy CASCADE;
NOTICE: drop cascades to server ctl_s0
--CREATE TABLE LIKE with PARAMETERS
-create table t_sp(a text) with (
- fillfactor = 100,
- toast_tuple_target = 128,
- vacuum_index_cleanup = auto,
- toast.vacuum_index_cleanup = auto,
- vacuum_truncate = true,
- toast.vacuum_truncate = false,
- log_autovacuum_min_duration = 100,
- toast.log_autovacuum_min_duration = 100);
-create table t_sp1(like t_sp including parameters) with (fillfactor = 100); --error
+CREATE TABLE t_sp (a text) WITH (
+ fillfactor = 100,
+ toast_tuple_target = 128,
+ vacuum_index_cleanup = auto,
+ toast.vacuum_index_cleanup = auto,
+ vacuum_truncate = true,
+ toast.vacuum_truncate = false,
+ log_autovacuum_min_duration = 100,
+ toast.log_autovacuum_min_duration = 100);
+CREATE TABLE t_sp1 (LIKE t_sp INCLUDING PARAMETERS) WITH (fillfactor = 100); -- fail
ERROR: parameter "fillfactor" specified more than once
-create table t_sp1(like t_sp excluding parameters) with (fillfactor = 100); --ok
+CREATE TABLE T_sp1 (LIKE t_sp EXCLUDING PARAMETERS) WITH (fillfactor = 100); -- ok
\d+ t_sp1
Table "public.t_sp1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
@@ -719,22 +719,19 @@ create table t_sp1(like t_sp excluding parameters) with (fillfactor = 100); --ok
a | text | | | | extended | |
Options: fillfactor=100
-create table t_sp2(like t_sp including parameters) with (
+CREATE TABLE t_sp2 (LIKE t_sp INCLUDING PARAMETERS) WITH (
parallel_workers = 3,
toast.autovacuum_vacuum_threshold = 101,
toast.autovacuum_vacuum_scale_factor = 0.3);
-select c.relname, c.reloptions, tc.reloptions as toast_options
-from pg_catalog.pg_class c
-left join pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)
-where c.relname in ('t_sp1', 't_sp2')
-order by c.relname \gx
--[ RECORD 1 ]-+-----------------------------------------------------------------------------------------------------------------------------------------------------
-relname | t_sp1
-reloptions | {fillfactor=100}
-toast_options |
--[ RECORD 2 ]-+-----------------------------------------------------------------------------------------------------------------------------------------------------
-relname | t_sp2
-reloptions | {parallel_workers=3,fillfactor=100,toast_tuple_target=128,vacuum_index_cleanup=auto,vacuum_truncate=true,log_autovacuum_min_duration=100}
-toast_options | {autovacuum_vacuum_threshold=101,autovacuum_vacuum_scale_factor=0.3,vacuum_index_cleanup=auto,vacuum_truncate=false,log_autovacuum_min_duration=100}
+SELECT c.relname, c.reloptions, t.reloptions as toast_reloptions
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_class t ON (c.reltoastrelid = t.oid)
+ WHERE c.relname IN ('t_sp1', 't_sp2')
+ ORDER BY c.relname;
+ relname | reloptions | toast_reloptions
+---------+-------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------
+ t_sp1 | {fillfactor=100} |
+ t_sp2 | {parallel_workers=3,fillfactor=100,toast_tuple_target=128,vacuum_index_cleanup=auto,vacuum_truncate=true,log_autovacuum_min_duration=100} | {autovacuum_vacuum_threshold=101,autovacuum_vacuum_scale_factor=0.3,vacuum_index_cleanup=auto,vacuum_truncate=false,log_autovacuum_min_duration=100}
+(2 rows)
-drop table t_sp, t_sp1, t_sp2;
+DROP TABLE t_sp, t_sp1, t_sp2;
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index afc8ffe6ad5..c357c2dec0d 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -282,29 +282,29 @@ DROP FOREIGN TABLE ctl_foreign_table2;
DROP FOREIGN DATA WRAPPER ctl_dummy CASCADE;
--CREATE TABLE LIKE with PARAMETERS
-create table t_sp(a text) with (
- fillfactor = 100,
- toast_tuple_target = 128,
- vacuum_index_cleanup = auto,
- toast.vacuum_index_cleanup = auto,
- vacuum_truncate = true,
- toast.vacuum_truncate = false,
- log_autovacuum_min_duration = 100,
- toast.log_autovacuum_min_duration = 100);
+CREATE TABLE t_sp (a text) WITH (
+ fillfactor = 100,
+ toast_tuple_target = 128,
+ vacuum_index_cleanup = auto,
+ toast.vacuum_index_cleanup = auto,
+ vacuum_truncate = true,
+ toast.vacuum_truncate = false,
+ log_autovacuum_min_duration = 100,
+ toast.log_autovacuum_min_duration = 100);
-create table t_sp1(like t_sp including parameters) with (fillfactor = 100); --error
-create table t_sp1(like t_sp excluding parameters) with (fillfactor = 100); --ok
+CREATE TABLE t_sp1 (LIKE t_sp INCLUDING PARAMETERS) WITH (fillfactor = 100); -- fail
+CREATE TABLE T_sp1 (LIKE t_sp EXCLUDING PARAMETERS) WITH (fillfactor = 100); -- ok
\d+ t_sp1
-create table t_sp2(like t_sp including parameters) with (
+CREATE TABLE t_sp2 (LIKE t_sp INCLUDING PARAMETERS) WITH (
parallel_workers = 3,
toast.autovacuum_vacuum_threshold = 101,
toast.autovacuum_vacuum_scale_factor = 0.3);
-select c.relname, c.reloptions, tc.reloptions as toast_options
-from pg_catalog.pg_class c
-left join pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)
-where c.relname in ('t_sp1', 't_sp2')
-order by c.relname \gx
+SELECT c.relname, c.reloptions, t.reloptions as toast_reloptions
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_class t ON (c.reltoastrelid = t.oid)
+ WHERE c.relname IN ('t_sp1', 't_sp2')
+ ORDER BY c.relname;
-drop table t_sp, t_sp1, t_sp2;
+DROP TABLE t_sp, t_sp1, t_sp2;
--
2.39.5