Skip to content

Commit 3a2923a

Browse files
committed
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
1 parent cb3d674 commit 3a2923a

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

src/backend/parser/gram.y

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10383,11 +10383,29 @@ ExecuteStmt: EXECUTE name execute_param_clause
1038310383
ctas->into = $4;
1038410384
ctas->relkind = OBJECT_TABLE;
1038510385
ctas->is_select_into = false;
10386+
ctas->if_not_exists = false;
1038610387
/* cram additional flags into the IntoClause */
1038710388
$4->rel->relpersistence = $2;
1038810389
$4->skipData = !($9);
1038910390
$$ = (Node *) ctas;
1039010391
}
10392+
| CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS
10393+
EXECUTE name execute_param_clause opt_with_data
10394+
{
10395+
CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt);
10396+
ExecuteStmt *n = makeNode(ExecuteStmt);
10397+
n->name = $10;
10398+
n->params = $11;
10399+
ctas->query = (Node *) n;
10400+
ctas->into = $7;
10401+
ctas->relkind = OBJECT_TABLE;
10402+
ctas->is_select_into = false;
10403+
ctas->if_not_exists = true;
10404+
/* cram additional flags into the IntoClause */
10405+
$7->rel->relpersistence = $2;
10406+
$7->skipData = !($12);
10407+
$$ = (Node *) ctas;
10408+
}
1039110409
;
1039210410

1039310411
execute_param_clause: '(' expr_list ')' { $$ = $2; }

src/test/regress/expected/create_table.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,20 @@ ERROR: relation "as_select1" already exists
258258
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
259259
NOTICE: relation "as_select1" already exists, skipping
260260
DROP TABLE as_select1;
261+
PREPARE select1 AS SELECT 1 as a;
262+
CREATE TABLE as_select1 AS EXECUTE select1;
263+
CREATE TABLE as_select1 AS EXECUTE select1;
264+
ERROR: relation "as_select1" already exists
265+
SELECT * FROM as_select1;
266+
a
267+
---
268+
1
269+
(1 row)
270+
271+
CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1;
272+
NOTICE: relation "as_select1" already exists, skipping
273+
DROP TABLE as_select1;
274+
DEALLOCATE select1;
261275
-- check that the oid column is added before the primary key is checked
262276
CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
263277
DROP TABLE oid_pk;

src/test/regress/sql/create_table.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
274274
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
275275
DROP TABLE as_select1;
276276

277+
PREPARE select1 AS SELECT 1 as a;
278+
CREATE TABLE as_select1 AS EXECUTE select1;
279+
CREATE TABLE as_select1 AS EXECUTE select1;
280+
SELECT * FROM as_select1;
281+
CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1;
282+
DROP TABLE as_select1;
283+
DEALLOCATE select1;
284+
277285
-- check that the oid column is added before the primary key is checked
278286
CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
279287
DROP TABLE oid_pk;

0 commit comments

Comments
 (0)