]> 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:46 +0000 (17:12 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 15 Feb 2019 08:12:46 +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 a0ef488003f53c426dc05e139ce9638512ea8159..ced7f814f77ae6839e812e303e631d17c8e83c81 100644 (file)
@@ -9583,11 +9583,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 41ceb874e8f650f82f66ddc06b9c8b955474d61a..145bac1b2f2928f4eeb2de38ff58191eb7a4b8ec 100644 (file)
@@ -250,6 +250,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;
 -- check that the oid column is added before the primary key is checked
 CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
 DROP TABLE oid_pk;
index 78bdc8bf5e7d6e9d6078dcf75203d55a1ac3bb3d..ec19f9a34f8d54f62d50290d114bfd8ded6de809 100644 (file)
@@ -266,6 +266,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;
+
 -- check that the oid column is added before the primary key is checked
 CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
 DROP TABLE oid_pk;