]> granicus.if.org Git - postgresql/commitdiff
Fix support for CREATE TABLE IF NOT EXISTS AS EXECUTE
authorMichael Paquier <michael@paquier.xyz>
Fri, 15 Feb 2019 08:12:24 +0000 (17:12 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 15 Feb 2019 08:12:24 +0000 (17:12 +0900)
The grammar IF NOT EXISTS for CTAS is supported since 9.5 and documented
as such, however the case of using EXECUTE as query has never been
covered as EXECUTE CTAS statements and normal CTAS statements are parsed
separately.

Author: Andreas Karlsson
Discussion: https://postgr.es/m/2ddcc188-e37c-a0be-32bf-a56b07c3559e@proxel.se
Backpatch-through: 9.5

src/backend/parser/gram.y
src/test/regress/expected/create_table.out
src/test/regress/sql/create_table.sql

index ef6bbe35d7f756e9aa006739f65cc6f620ed69ac..7bb2b0b2a52ef4d9f08f7a7d77f78320c558e440 100644 (file)
@@ -10700,11 +10700,29 @@ ExecuteStmt: EXECUTE name execute_param_clause
                                        ctas->into = $4;
                                        ctas->relkind = OBJECT_TABLE;
                                        ctas->is_select_into = false;
+                                       ctas->if_not_exists = false;
                                        /* cram additional flags into the IntoClause */
                                        $4->rel->relpersistence = $2;
                                        $4->skipData = !($9);
                                        $$ = (Node *) ctas;
                                }
+                       | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS
+                               EXECUTE name execute_param_clause opt_with_data
+                               {
+                                       CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
+                                       ExecuteStmt *n = makeNode(ExecuteStmt);
+                                       n->name = $10;
+                                       n->params = $11;
+                                       ctas->query = (Node *) n;
+                                       ctas->into = $7;
+                                       ctas->relkind = OBJECT_TABLE;
+                                       ctas->is_select_into = false;
+                                       ctas->if_not_exists = true;
+                                       /* cram additional flags into the IntoClause */
+                                       $7->rel->relpersistence = $2;
+                                       $7->skipData = !($12);
+                                       $$ = (Node *) ctas;
+                               }
                ;
 
 execute_param_clause: '(' expr_list ')'                                { $$ = $2; }
index 100fa53ab0cd222c022385d349954a02f9c77d65..d51e547278efa7000d4da02c9e1ef3751e7db9c3 100644 (file)
@@ -261,6 +261,20 @@ ERROR:  relation "as_select1" already exists
 CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 NOTICE:  relation "as_select1" already exists, skipping
 DROP TABLE as_select1;
+PREPARE select1 AS SELECT 1 as a;
+CREATE TABLE as_select1 AS EXECUTE select1;
+CREATE TABLE as_select1 AS EXECUTE select1;
+ERROR:  relation "as_select1" already exists
+SELECT * FROM as_select1;
+ a 
+---
+ 1
+(1 row)
+
+CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1;
+NOTICE:  relation "as_select1" already exists, skipping
+DROP TABLE as_select1;
+DEALLOCATE select1;
 -- create an extra wide table to test for issues related to that
 -- (temporarily hide query, to avoid the long CREATE TABLE stmt)
 \set ECHO none
index 22a3d901013e697f38d50b5b7432d341d6291b67..4091c19cf035828c13aeaab0ae2d9279ed0694c7 100644 (file)
@@ -277,6 +277,14 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 DROP TABLE as_select1;
 
+PREPARE select1 AS SELECT 1 as a;
+CREATE TABLE as_select1 AS EXECUTE select1;
+CREATE TABLE as_select1 AS EXECUTE select1;
+SELECT * FROM as_select1;
+CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1;
+DROP TABLE as_select1;
+DEALLOCATE select1;
+
 -- create an extra wide table to test for issues related to that
 -- (temporarily hide query, to avoid the long CREATE TABLE stmt)
 \set ECHO none