Commit 331a613e authored by Michael Paquier's avatar Michael Paquier

Fix support for CREATE TABLE IF NOT EXISTS AS EXECUTE

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
parent 6c0fb941
...@@ -10700,11 +10700,29 @@ ExecuteStmt: EXECUTE name execute_param_clause ...@@ -10700,11 +10700,29 @@ ExecuteStmt: EXECUTE name execute_param_clause
ctas->into = $4; ctas->into = $4;
ctas->relkind = OBJECT_TABLE; ctas->relkind = OBJECT_TABLE;
ctas->is_select_into = false; ctas->is_select_into = false;
ctas->if_not_exists = false;
/* cram additional flags into the IntoClause */ /* cram additional flags into the IntoClause */
$4->rel->relpersistence = $2; $4->rel->relpersistence = $2;
$4->skipData = !($9); $4->skipData = !($9);
$$ = (Node *) ctas; $$ = (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; } execute_param_clause: '(' expr_list ')' { $$ = $2; }
......
...@@ -261,6 +261,20 @@ ERROR: relation "as_select1" already exists ...@@ -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'; CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
NOTICE: relation "as_select1" already exists, skipping NOTICE: relation "as_select1" already exists, skipping
DROP TABLE as_select1; 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 -- create an extra wide table to test for issues related to that
-- (temporarily hide query, to avoid the long CREATE TABLE stmt) -- (temporarily hide query, to avoid the long CREATE TABLE stmt)
\set ECHO none \set ECHO none
......
...@@ -277,6 +277,14 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; ...@@ -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'; CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
DROP TABLE as_select1; 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 -- create an extra wide table to test for issues related to that
-- (temporarily hide query, to avoid the long CREATE TABLE stmt) -- (temporarily hide query, to avoid the long CREATE TABLE stmt)
\set ECHO none \set ECHO none
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment