Re: create table like: ACCESS METHOD

2021-10-01 Thread Michael Paquier
On Thu, Sep 09, 2021 at 02:30:51PM +0200, Peter Eisentraut wrote:
> Hmm.  The problem is that the LIKE clause is really a macro that expands to
> the column definitions of the other table.  So there is, so far, no such as
> thing as two LIKE clauses contradicting.  Whereas the access method is a
> table property.  So I don't think this syntax is the right approach for this
> feature.
> 
> You might think about something like
> 
> CREATE TABLE t2 (...) USING (LIKE t1);
> 
> At least in terms of how the syntax should be structured.

Good point.  I have marked the patch as RwF.
--
Michael


signature.asc
Description: PGP signature


Re: create table like: ACCESS METHOD

2021-09-09 Thread Peter Eisentraut

On 27.08.21 12:37, Vik Fearing wrote:

It seems like this should error to me:

CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
CREATE TABLE likeam1() USING heap;
CREATE TABLE likeam2() USING heapdup;
CREATE TABLE likeamlike(
 LIKE likeam1 INCLUDING ACCESS METHOD,
 LIKE likeam2 INCLUDING ACCESS METHOD
);

At the very least, the documentation should say that the last one wins.


Hmm.  The problem is that the LIKE clause is really a macro that expands 
to the column definitions of the other table.  So there is, so far, no 
such as thing as two LIKE clauses contradicting.  Whereas the access 
method is a table property.  So I don't think this syntax is the right 
approach for this feature.


You might think about something like

CREATE TABLE t2 (...) USING (LIKE t1);

At least in terms of how the syntax should be structured.




Re: create table like: ACCESS METHOD

2021-08-29 Thread Michael Paquier
On Fri, Aug 27, 2021 at 02:38:43PM +0900, Michael Paquier wrote:
> +CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
> +CREATE TABLE likeam() USING heapdup;
> +CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL);
> Rather than creating a custom AM in this test path, I would be
> tempted to move that to create_am.sql.

+   /* ACCESS METHOD doesn't apply and isn't copied for partitioned tables 
*/
+   if ((table_like_clause->options & CREATE_TABLE_LIKE_ACCESS_METHOD) != 0 
&&
+   !cxt->ispartitioned)
+   cxt->accessMethod = get_am_name(relation->rd_rel->relam);

If the new table is partitioned, this would work.  Now I think that we
should also add here a (relation->rd_rel->relkind == RELKIND_RELATION)
to make sure that we only copy an access method if the original
relation is a table.  Note that the original relation could be as well
a view, a foreign table or a composite type.

@@ -349,6 +351,9 @@ transformCreateStmt(CreateStmt *stmt, const char 
*queryString)
[...]
+   if (cxt.accessMethod != NULL)
+   stmt->accessMethod = cxt.accessMethod;

This bit is something I have been chewing on a bit.  It means that if
we find out an AM to copy from any of the LIKE clauses, we would
blindly overwrite the AM defined in an existing CreateStmt.  We could
also argue in favor of keeping the original AM defined by USING from
the query rather than having an error.  This means to check that
stmt->accessMethod is overwritten only if NULL at this point.  Anyway,
the patch is wrong with this implementation.

This makes me actually wonder if this patch is really a good idea at
the end.  The interactions with USING and LIKE would be confusing to
the end-user one way or the other.  The argument of upthread regarding
INCLUDING ALL or INCLUDING ACCESS METHOD with multiple original
relations also goes in this sense.  If we want to move forward here, I
think that we should really be careful and have a clear definition
behind all those corner cases.  The patch fails this point for now.
--
Michael


signature.asc
Description: PGP signature


Re: create table like: ACCESS METHOD

2021-08-29 Thread Michael Paquier
On Fri, Aug 27, 2021 at 12:37:59PM +0200, Vik Fearing wrote:
> It seems like this should error to me:
> 
> CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
> CREATE TABLE likeam1() USING heap;
> CREATE TABLE likeam2() USING heapdup;
> CREATE TABLE likeamlike(
> LIKE likeam1 INCLUDING ACCESS METHOD,
> LIKE likeam2 INCLUDING ACCESS METHOD
> );
> 
> At the very least, the documentation should say that the last one wins.

An error may be annoying once you do an INCLUDING ALL with more than
one relation, no?  I'd be fine with just documenting that the last one
wins.
--
Michael


signature.asc
Description: PGP signature


Re: create table like: ACCESS METHOD

2021-08-27 Thread Vik Fearing
On 3/23/21 1:39 AM, Justin Pryzby wrote:
> On Tue, Jan 19, 2021 at 03:03:31PM -0600, Justin Pryzby wrote:
>> On Wed, Dec 30, 2020 at 12:33:56PM +, Simon Riggs wrote:
>>> There are no tests for the new functionality, please could you add some?
>>
>> Did you look at the most recent patch?
>>
>> +CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
>> +CREATE TABLE likeam() USING heapdup;
>> +CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL); 
>>  
>>  

It seems like this should error to me:

CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
CREATE TABLE likeam1() USING heap;
CREATE TABLE likeam2() USING heapdup;
CREATE TABLE likeamlike(
LIKE likeam1 INCLUDING ACCESS METHOD,
LIKE likeam2 INCLUDING ACCESS METHOD
);

At the very least, the documentation should say that the last one wins.
-- 
Vik Fearing




Re: create table like: ACCESS METHOD

2021-08-26 Thread Michael Paquier
On Tue, Jun 01, 2021 at 02:10:45PM -0500, Justin Pryzby wrote:
> rebased and alphabetized

+   /* ACCESS METHOD doesn't apply and isn't copied for partitioned tables */
+   if ((table_like_clause->options & CREATE_TABLE_LIKE_ACCESS_METHOD) != 0 &&
+   !cxt->ispartitioned)
+   cxt->accessMethod = get_am_name(relation->rd_rel->relam);
I was thinking about an ERROR here, but all the other options do the
work when specified only if required, so that's fine.  We should have
a test with a partitioned table and the clause specified, though.

+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
Why is there any need to mention default_table_access_method?  This
just inherits the AM from the source table, which has nothing to do
with the default directly.

+CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
+CREATE TABLE likeam() USING heapdup;
+CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL);
Rather than creating a custom AM in this test path, I would be
tempted to move that to create_am.sql.
--
Michael


signature.asc
Description: PGP signature


Re: create table like: ACCESS METHOD

2021-06-01 Thread Justin Pryzby
rebased and alphabetized
>From c1420e17cc2036d4bf3a6c1f9366bf1cd03bd831 Mon Sep 17 00:00:00 2001
From: Justin Pryzby 
Date: Sun, 15 Nov 2020 16:54:53 -0600
Subject: [PATCH v5] create table (like .. including ACCESS METHOD)

---
 doc/src/sgml/ref/create_table.sgml| 22 ++-
 src/backend/parser/gram.y |  3 ++-
 src/backend/parser/parse_utilcmd.c| 10 +
 src/include/nodes/parsenodes.h| 19 
 .../regress/expected/create_table_like.out| 12 ++
 src/test/regress/sql/create_table_like.sql|  8 +++
 6 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index c6d0a35e50..ab84ca8718 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -87,7 +87,7 @@ class="parameter">referential_action ] [ ON UPDATE and like_option is:
 
-{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+{ INCLUDING | EXCLUDING } { ACCESS METHOD | COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
 
 and partition_bound_spec is:
 
@@ -618,6 +618,16 @@ WITH ( MODULUS numeric_literal, REM
   available options are:
 
   
+   
+INCLUDING ACCESS METHOD
+
+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
+
+   
+

 INCLUDING COMMENTS
 
@@ -725,6 +735,16 @@ WITH ( MODULUS numeric_literal, REM
 

 
+   
+INCLUDING TABLE ACCESS METHOD
+
+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
+
+   
+

 INCLUDING ALL
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9ee90e3f13..c8991cead9 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3754,7 +3754,8 @@ TableLikeOptionList:
 		;
 
 TableLikeOption:
-COMMENTS			{ $$ = CREATE_TABLE_LIKE_COMMENTS; }
+ACCESS METHOD			{ $$ = CREATE_TABLE_LIKE_ACCESS_METHOD; }
+| COMMENTS			{ $$ = CREATE_TABLE_LIKE_COMMENTS; }
 | COMPRESSION		{ $$ = CREATE_TABLE_LIKE_COMPRESSION; }
 | CONSTRAINTS		{ $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }
 | DEFAULTS			{ $$ = CREATE_TABLE_LIKE_DEFAULTS; }
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index d5b67d48cf..0cdea516ac 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -97,6 +97,7 @@ typedef struct
 	bool		ispartitioned;	/* true if table is partitioned */
 	PartitionBoundSpec *partbound;	/* transformed FOR VALUES */
 	bool		ofType;			/* true if statement contains OF typename */
+	char		*accessMethod;	/* table access method */
 } CreateStmtContext;
 
 /* State shared by transformCreateSchemaStmt and its subroutines */
@@ -252,6 +253,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	cxt.ispartitioned = stmt->partspec != NULL;
 	cxt.partbound = stmt->partbound;
 	cxt.ofType = (stmt->ofTypename != NULL);
+	cxt.accessMethod = NULL;
 
 	Assert(!stmt->ofTypename || !stmt->inhRelations);	/* grammar enforces */
 
@@ -349,6 +351,9 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	stmt->tableElts = cxt.columns;
 	stmt->constraints = cxt.ckconstraints;
 
+	if (cxt.accessMethod != NULL)
+		stmt->accessMethod = cxt.accessMethod;
+
 	result = lappend(cxt.blist, stmt);
 	result = list_concat(result, cxt.alist);
 	result = list_concat(result, save_alist);
@@ -1139,6 +1144,11 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 		cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause);
 	}
 
+	/* ACCESS METHOD doesn't apply and isn't copied for partitioned tables */
+	if ((table_like_clause->options & CREATE_TABLE_LIKE_ACCESS_METHOD) != 0 &&
+		!cxt->ispartitioned)
+		cxt->accessMethod = get_am_name(relation->rd_rel->relam);
+
 	/*
 	 * We may copy extended statistics if requested, since the representation
 	 * of CreateStatsStmt doesn't depend on column numbers.
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index ef73342019..726f15f78a 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -689,15 +689,16 @@ typedef struct TableLikeClause
 
 typedef enum TableLikeOption
 {
-	CREATE_TABLE_LIKE_COMMENTS = 1 << 0,
-	CREATE_TABLE_LIKE_COMPRESSION = 1 << 1,
-	CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 2,
-	CREATE_TABLE_LIKE_DEFAULTS = 1 << 3,
-	CREATE_TABLE_LIKE_GENERATED = 1 << 4,
-	CREATE_TABLE_LIKE_IDENTITY = 1 << 5,
-	CREATE_TABLE_LIKE_INDEXES = 1 << 6,
-	CREATE_TABLE_LIKE_STATISTICS = 1 << 7,
-	CREATE_TABLE_LIKE_STORAGE = 1 << 8,
+	CREATE_T

Re: create table like: ACCESS METHOD

2021-03-22 Thread Justin Pryzby
On Tue, Jan 19, 2021 at 03:03:31PM -0600, Justin Pryzby wrote:
> On Wed, Dec 30, 2020 at 12:33:56PM +, Simon Riggs wrote:
> > There are no tests for the new functionality, please could you add some?
> 
> Did you look at the most recent patch?
> 
> +CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
> +CREATE TABLE likeam() USING heapdup;
> +CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL);  
>   
>
> 
> Also, I just realized that Dilip's toast compression patch adds "INCLUDING
> COMPRESSION", which is stored in pg_am.  That's an implementation detail of
> that patch, but it's not intuitive that "including access method" wouldn't
> include the compression stored there.  So I think this should use "INCLUDING
> TABLE ACCESS METHOD" not just ACCESS METHOD.  

Since the TOAST patch ended up not using access methods after all, I renamed
this back to "like ACCESS METHOD" (without table).

For now, I left TableLikeOption un-alphabetized.

-- 
Justin
>From 2da8104a39f65f576d0f221c288502d27211a209 Mon Sep 17 00:00:00 2001
From: Justin Pryzby 
Date: Sun, 15 Nov 2020 16:54:53 -0600
Subject: [PATCH v4] create table (like .. including ACCESS METHOD)

---
 doc/src/sgml/ref/create_table.sgml  | 12 +++-
 src/backend/parser/gram.y   |  1 +
 src/backend/parser/parse_utilcmd.c  | 10 ++
 src/include/nodes/parsenodes.h  |  1 +
 src/test/regress/expected/create_table_like.out | 12 
 src/test/regress/sql/create_table_like.sql  |  8 
 6 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index c6c248f1e9..dd92fd0e9a 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -87,7 +87,7 @@ class="parameter">referential_action ] [ ON UPDATE and like_option is:
 
-{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+{ INCLUDING | EXCLUDING } { ACCESS METHOD | COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
 
 and partition_bound_spec is:
 
@@ -613,6 +613,16 @@ WITH ( MODULUS numeric_literal, REM
   available options are:
 
   
+   
+INCLUDING ACCESS METHOD
+
+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
+
+   
+

 INCLUDING COMMENTS
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index bc43641ffe..383e0671af 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3741,6 +3741,7 @@ TableLikeOption:
 | STATISTICS		{ $$ = CREATE_TABLE_LIKE_STATISTICS; }
 | STORAGE			{ $$ = CREATE_TABLE_LIKE_STORAGE; }
 | COMPRESSION		{ $$ = CREATE_TABLE_LIKE_COMPRESSION; }
+| ACCESS METHOD 	{ $$ = CREATE_TABLE_LIKE_ACCESS_METHOD; }
 | ALL{ $$ = CREATE_TABLE_LIKE_ALL; }
 		;
 
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index aa6c19adad..07e18fa62f 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -97,6 +97,7 @@ typedef struct
 	bool		ispartitioned;	/* true if table is partitioned */
 	PartitionBoundSpec *partbound;	/* transformed FOR VALUES */
 	bool		ofType;			/* true if statement contains OF typename */
+	char		*accessMethod;	/* table access method */
 } CreateStmtContext;
 
 /* State shared by transformCreateSchemaStmt and its subroutines */
@@ -253,6 +254,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	cxt.ispartitioned = stmt->partspec != NULL;
 	cxt.partbound = stmt->partbound;
 	cxt.ofType = (stmt->ofTypename != NULL);
+	cxt.accessMethod = NULL;
 
 	Assert(!stmt->ofTypename || !stmt->inhRelations);	/* grammar enforces */
 
@@ -347,6 +349,9 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	stmt->tableElts = cxt.columns;
 	stmt->constraints = cxt.ckconstraints;
 
+	if (cxt.accessMethod != NULL)
+		stmt->accessMethod = cxt.accessMethod;
+
 	result = lappend(cxt.blist, stmt);
 	result = list_concat(result, cxt.alist);
 	result = list_concat(result, save_alist);
@@ -1137,6 +1142,11 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 		cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause);
 	}
 
+	/* ACCESS METHOD doesn't apply and isn't copied for partitioned tables */
+	if ((table_like_clause->options & CREATE_TABLE_LIKE_ACCESS_METHOD) != 0 &&
+		!cxt->ispartitioned)
+		cxt->accessMethod = get_am_name(relation->rd_rel->relam);
+
 	/*
 	 * We may copy extended statistics if requested, since the representation
 	 * of CreateStatsStmt doesn't depen

Re: create table like: ACCESS METHOD

2021-03-19 Thread David Steele

On 1/19/21 4:03 PM, Justin Pryzby wrote:

On Wed, Dec 30, 2020 at 12:33:56PM +, Simon Riggs wrote:

There are no tests for the new functionality, please could you add some?


Did you look at the most recent patch?

+CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
+CREATE TABLE likeam() USING heapdup;
+CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL);

Also, I just realized that Dilip's toast compression patch adds "INCLUDING
COMPRESSION", which is stored in pg_am.  That's an implementation detail of
that patch, but it's not intuitive that "including access method" wouldn't
include the compression stored there.  So I think this should use "INCLUDING
TABLE ACCESS METHOD" not just ACCESS METHOD.


Simon, do you know when you'll have a chance to review the updated patch 
in [1]?


Regards,
--
-David
da...@pgmasters.net

[1] 
https://www.postgresql.org/message-id/20210119210331.GN8560%40telsasoft.com





Re: create table like: ACCESS METHOD

2021-01-19 Thread Justin Pryzby
On Wed, Dec 30, 2020 at 12:33:56PM +, Simon Riggs wrote:
> There are no tests for the new functionality, please could you add some?

Did you look at the most recent patch?

+CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler;
+CREATE TABLE likeam() USING heapdup;
+CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL);

   

Also, I just realized that Dilip's toast compression patch adds "INCLUDING
COMPRESSION", which is stored in pg_am.  That's an implementation detail of
that patch, but it's not intuitive that "including access method" wouldn't
include the compression stored there.  So I think this should use "INCLUDING
TABLE ACCESS METHOD" not just ACCESS METHOD.  

-- 
Justin
>From f27fd6291aa10af1ca0be4bc72a656811c8e0c9f Mon Sep 17 00:00:00 2001
From: Justin Pryzby 
Date: Sun, 15 Nov 2020 16:54:53 -0600
Subject: [PATCH v3] create table (like .. including ACCESS METHOD)

---
 doc/src/sgml/ref/create_table.sgml  | 12 +++-
 src/backend/parser/gram.y   |  1 +
 src/backend/parser/parse_utilcmd.c  | 10 ++
 src/include/nodes/parsenodes.h  |  1 +
 src/test/regress/expected/create_table_like.out | 12 
 src/test/regress/sql/create_table_like.sql  |  8 
 6 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 569f4c9da7..e3c607f6b1 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -87,7 +87,7 @@ class="parameter">referential_action ] [ ON UPDATE and like_option is:
 
-{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | TABLE ACCESS METHOD | ALL }
 
 and partition_bound_spec is:
 
@@ -689,6 +689,16 @@ WITH ( MODULUS numeric_literal, REM
 

 
+   
+INCLUDING TABLE ACCESS METHOD
+
+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
+
+   
+

 INCLUDING ALL
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 31c95443a5..719ac838e3 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3708,6 +3708,7 @@ TableLikeOption:
 | INDEXES			{ $$ = CREATE_TABLE_LIKE_INDEXES; }
 | STATISTICS		{ $$ = CREATE_TABLE_LIKE_STATISTICS; }
 | STORAGE			{ $$ = CREATE_TABLE_LIKE_STORAGE; }
+| TABLE ACCESS METHOD { $$ = CREATE_TABLE_LIKE_TABLE_ACCESS_METHOD; }
 | ALL{ $$ = CREATE_TABLE_LIKE_ALL; }
 		;
 
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index b31f3afa03..f34f42aae3 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -96,6 +96,7 @@ typedef struct
 	bool		ispartitioned;	/* true if table is partitioned */
 	PartitionBoundSpec *partbound;	/* transformed FOR VALUES */
 	bool		ofType;			/* true if statement contains OF typename */
+	char		*accessMethod;	/* table access method */
 } CreateStmtContext;
 
 /* State shared by transformCreateSchemaStmt and its subroutines */
@@ -252,6 +253,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	cxt.ispartitioned = stmt->partspec != NULL;
 	cxt.partbound = stmt->partbound;
 	cxt.ofType = (stmt->ofTypename != NULL);
+	cxt.accessMethod = NULL;
 
 	Assert(!stmt->ofTypename || !stmt->inhRelations);	/* grammar enforces */
 
@@ -346,6 +348,9 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	stmt->tableElts = cxt.columns;
 	stmt->constraints = cxt.ckconstraints;
 
+	if (cxt.accessMethod != NULL)
+		stmt->accessMethod = cxt.accessMethod;
+
 	result = lappend(cxt.blist, stmt);
 	result = list_concat(result, cxt.alist);
 	result = list_concat(result, save_alist);
@@ -1118,6 +1123,11 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 		cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause);
 	}
 
+	/* ACCESS METHOD doesn't apply and isn't copied for partitioned tables */
+	if ((table_like_clause->options & CREATE_TABLE_LIKE_TABLE_ACCESS_METHOD) != 0 &&
+		!cxt->ispartitioned)
+		cxt->accessMethod = get_am_name(relation->rd_rel->relam);
+
 	/*
 	 * We may copy extended statistics if requested, since the representation
 	 * of CreateStatsStmt doesn't depend on column numbers.
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index dc2bb40926..600856c229 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -685,6 +685,7 @@ typedef enum TableLikeOption
 	CREATE_TABLE_LIKE

Re: create table like: ACCESS METHOD

2020-12-30 Thread Simon Riggs
On Tue, 29 Dec 2020 at 23:08, Justin Pryzby  wrote:
>
> On Fri, Dec 25, 2020 at 03:41:46PM +0900, Michael Paquier wrote:
> > On Wed, Dec 09, 2020 at 02:13:29PM -0600, Justin Pryzby wrote:
> > > I thought this was a good idea, but didn't hear back when I raised it 
> > > before.
> > >
> > > Failing to preserve access method is arguably a bug, reminiscent of CREATE
> > > STATISTICS and 5564c1181.  But maybe it's not important to backpatch a 
> > > fix in
> > > this case, since access methods are still evolving.
> >
> > Interesting.  Access methods for tables are released for more than one
> > year now, so my take about a backpatch is that this boat has already
> > sailed.  This may give a reason to actually not introduce this
> > feature.
>
> Are you saying that since v12/13 didn't preserve the access method, it might 
> be
> preferred to never do it ?  I think it's reasonable to not change v12/13 but
> the behavior seems like an omission going forward.  It's not so important 
> right
> now, since AMs aren't widely used.

Omitting copying the AM seems like a bug during
  CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL);
But this does allow you to specify the TableAM by using
default_table_access_method, and to use
  CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL) USING (heapdup);
if you wish to set the AM explicitly, so I don't see this as needing backpatch.

Which means that the emphasis for the earlier functionality was
towards one "preferred AM" rather than using multiple AMs at same
time. Allowing this change in later releases makes sense.

Please make sure this is marked as an incompatibility in the release notes.

> > This patch should have more tests.  Something could be added in
> > create_am.sql where there is a fake heap2 as table AM.
>
> Yes, I had already done that locally.

There are no tests for the new functionality, please could you add some?

-- 
Simon Riggshttp://www.EnterpriseDB.com/




Re: create table like: ACCESS METHOD

2020-12-29 Thread Justin Pryzby
On Fri, Dec 25, 2020 at 03:41:46PM +0900, Michael Paquier wrote:
> On Wed, Dec 09, 2020 at 02:13:29PM -0600, Justin Pryzby wrote:
> > I thought this was a good idea, but didn't hear back when I raised it 
> > before.
> > 
> > Failing to preserve access method is arguably a bug, reminiscent of CREATE
> > STATISTICS and 5564c1181.  But maybe it's not important to backpatch a fix 
> > in
> > this case, since access methods are still evolving.
> 
> Interesting.  Access methods for tables are released for more than one
> year now, so my take about a backpatch is that this boat has already
> sailed.  This may give a reason to actually not introduce this
> feature.

Are you saying that since v12/13 didn't preserve the access method, it might be
preferred to never do it ?  I think it's reasonable to to not change v12/13 but
the behavior seems like an omission going forward.  It's not so important right
now, since AMs aren't widely used.

This might be important for a few cases I can think of easily:

If an readonly AM doesn't support DDL, and table needs to be rebuilt, we'd
handle that by creating a new table LIKE the existing table, preserving its AM,
and then INSERT into it.  Like for column type promotion.  That's much better
than querying amname FROM pg_class JOIN relam.

ALTER TABLE..ATTACH PARTITION requires a less strong lock than CREATE
TABLE..PARTITION OF, so it's nice to be able to CREATE TABLE LIKE.

To use an alternate AM for historic data, we'd CREATE TABLE LIKE an existing,
populated table before inserting into it.  This would support re-creating on a
new AM, or re-creating on the same AM, say, to get rid of dropped columns, or
to re-arrange columns.  

>  -- fail, as partitioned tables don't allow NO INHERIT constraints
> -CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL)
> +CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL 
> EXCLUDING ACCESS METHOD)
>PARTITION BY LIST (a);
> This diff means that you are introducing an incompatible change by
> forcing any application using CREATE TABLE LIKE for a partitioned
> table to exclude access methods.  This is not acceptable, and it may
> be better to just ignore this clause instead in this context.

Ok.  This means that 
CREATE TABLE (LIKE x INCLUDING ACCESS METHOD) PARTITION BY ...
silently ignores the INCLUDING AM.  Is that ok ?  I think the alternative is
for INCLUDING to be "ternary" options, defaulting to UNSET=0, when it's ok to
ignore options in contexts where they're not useful.
Maybe we'd need to specially handle INCLUDING ALL, to make options
"soft"/implied rather than explicit.

> This patch should have more tests.  Something could be added in
> create_am.sql where there is a fake heap2 as table AM.

Yes, I had already done that locally.

-- 
Justin
>From c4c4570f90623aa8508a2749f5ca5e2780ab10df Mon Sep 17 00:00:00 2001
From: Justin Pryzby 
Date: Sun, 15 Nov 2020 16:54:53 -0600
Subject: [PATCH v2] create table (like .. including ACCESS METHOD)

---
 doc/src/sgml/ref/create_table.sgml  | 12 +++-
 src/backend/parser/gram.y   |  3 ++-
 src/backend/parser/parse_utilcmd.c  | 10 ++
 src/include/nodes/parsenodes.h  | 17 +
 src/test/regress/expected/create_table_like.out | 12 
 src/test/regress/sql/create_table_like.sql  |  8 
 6 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 569f4c9da7..cb95177e92 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -87,7 +87,7 @@ class="parameter">referential_action ] [ ON UPDATE and like_option is:
 
-{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+{ INCLUDING | EXCLUDING } { ACCESS METHOD | COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
 
 and partition_bound_spec is:
 
@@ -593,6 +593,16 @@ WITH ( MODULUS numeric_literal, REM
   available options are:
 
   
+   
+INCLUDING ACCESS METHOD
+
+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
+
+   
+

 INCLUDING COMMENTS
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 8f341ac006..fee0aceb65 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3651,7 +3651,8 @@ TableLikeOptionList:
 		;
 
 TableLikeOption:
-COMMENTS			{ $$ = CREATE_TABLE_LIKE_COMMENTS; }
+ACCESS METHOD			{ $$ = CREATE_TABLE_LIKE_ACCESS_METHOD; }
+| COMMENTS			{ $$ = CREATE_TABLE_LIKE_COMMENTS; }
 | CONSTRAINTS		{ $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }
 | DEFAULTS			{ $$ = CREATE_TABLE_LIKE_DEFAULTS; }
 | IDENTITY_P		{ $$ = CREATE_TABLE_LIKE_IDENTITY; }
diff --git a

Re: create table like: ACCESS METHOD

2020-12-24 Thread Michael Paquier
On Wed, Dec 09, 2020 at 02:13:29PM -0600, Justin Pryzby wrote:
> I thought this was a good idea, but didn't hear back when I raised it before.
> 
> Failing to preserve access method is arguably a bug, reminiscent of CREATE
> STATISTICS and 5564c1181.  But maybe it's not important to backpatch a fix in
> this case, since access methods are still evolving.

Interesting.  Access methods for tables are released for more than one
year now, so my take about a backpatch is that this boat has already
sailed.  This may give a reason to actually not introduce this
feature.

+   CREATE_TABLE_LIKE_ACCESSMETHOD = 1 << 0,
Nit: wouldn't this be better as ACCESS_METHOD?

 -- fail, as partitioned tables don't allow NO INHERIT constraints
-CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL)
+CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL 
EXCLUDING ACCESS METHOD)
   PARTITION BY LIST (a);
This diff means that you are introducing an incompatible change by
forcing any application using CREATE TABLE LIKE for a partitioned
table to exclude access methods.  This is not acceptable, and it may
be better to just ignore this clause instead in this context.

This patch should have more tests.  Something could be added in
create_am.sql where there is a fake heap2 as table AM.

+ 
+  The table's access method will be copied.  By default, the
+  default_table_access_method is used.
+ 
Second sentence sounds a bit strange by combining "the" and a GUC
name.  I would just write "Default is default_table_a_m".
--
Michael


signature.asc
Description: PGP signature