]> 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:51 +0000 (17:12 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 15 Feb 2019 08:12:51 +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 e27d37cdfe96d13036b615f993bbb2ddfcc53277..9f08926e772ff1e3967da78b95af04033ccf212c 100644 (file)
@@ -9441,11 +9441,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 8ba7bbc1113ad207c91ac63c9e2d897330e40bb0..3b141834afbcdf9ee0331fcc952c754dc92ebc7c 100644 (file)
@@ -250,3 +250,17 @@ 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;
index 03bb5ff704e494c5c70f29e5493bf4e0f6f341dc..0a0497e53b0d84480449da4df733fc887c8db309 100644 (file)
@@ -265,3 +265,11 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 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;