Skip to content

Commit a3b012b

Browse files
committed
CREATE TABLE IF NOT EXISTS.
Reviewed by Bernd Helmle.
1 parent edff75b commit a3b012b

File tree

21 files changed

+145
-31
lines changed

21 files changed

+145
-31
lines changed

doc/src/sgml/ref/create_table.sgml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.128 2010/06/07 02:59:02 itagaki Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.129 2010/07/25 23:21:21 rhaas Exp $
33
PostgreSQL documentation
44
-->
55

@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [
24+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [
2525
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
2626
| <replaceable>table_constraint</replaceable>
2727
| LIKE <replaceable>parent_table</replaceable> [ <replaceable>like_option</replaceable> ... ] }
@@ -32,7 +32,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
3232
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
3333
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
3434

35-
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable>
35+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
3636
OF <replaceable class="PARAMETER">type_name</replaceable> [ (
3737
{ <replaceable class="PARAMETER">column_name</replaceable> WITH OPTIONS [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
3838
| <replaceable>table_constraint</replaceable> }
@@ -163,6 +163,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
163163
</listitem>
164164
</varlistentry>
165165

166+
<varlistentry>
167+
<term><literal>IF NOT EXISTS</></term>
168+
<listitem>
169+
<para>
170+
Do not throw an error if a relation with the same name already exists.
171+
A notice is issued in this case. Note that there is no guarantee that
172+
the existing relation is anything like the one that would have been
173+
created.
174+
</para>
175+
</listitem>
176+
</varlistentry>
177+
166178
<varlistentry>
167179
<term><replaceable class="PARAMETER">table_name</replaceable></term>
168180
<listitem>

src/backend/bootstrap/bootparse.y

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.105 2010/02/07 20:48:09 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.106 2010/07/25 23:21:21 rhaas Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -245,7 +245,8 @@ Boot_CreateStmt:
245245
ONCOMMIT_NOOP,
246246
(Datum) 0,
247247
false,
248-
true);
248+
true,
249+
false);
249250
elog(DEBUG4, "relation created with oid %u", id);
250251
}
251252
do_end();

src/backend/catalog/heap.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.373 2010/04/05 01:09:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.374 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -903,11 +903,13 @@ heap_create_with_catalog(const char *relname,
903903
OnCommitAction oncommit,
904904
Datum reloptions,
905905
bool use_user_acl,
906-
bool allow_system_table_mods)
906+
bool allow_system_table_mods,
907+
bool if_not_exists)
907908
{
908909
Relation pg_class_desc;
909910
Relation new_rel_desc;
910911
Acl *relacl;
912+
Oid existing_relid;
911913
Oid old_type_oid;
912914
Oid new_type_oid;
913915
Oid new_array_oid = InvalidOid;
@@ -921,10 +923,27 @@ heap_create_with_catalog(const char *relname,
921923

922924
CheckAttributeNamesTypes(tupdesc, relkind, allow_system_table_mods);
923925

924-
if (get_relname_relid(relname, relnamespace))
926+
/*
927+
* If the relation already exists, it's an error, unless the user specifies
928+
* "IF NOT EXISTS". In that case, we just print a notice and do nothing
929+
* further.
930+
*/
931+
existing_relid = get_relname_relid(relname, relnamespace);
932+
if (existing_relid != InvalidOid)
933+
{
934+
if (if_not_exists)
935+
{
936+
ereport(NOTICE,
937+
(errcode(ERRCODE_DUPLICATE_TABLE),
938+
errmsg("relation \"%s\" already exists, skipping",
939+
relname)));
940+
heap_close(pg_class_desc, RowExclusiveLock);
941+
return InvalidOid;
942+
}
925943
ereport(ERROR,
926944
(errcode(ERRCODE_DUPLICATE_TABLE),
927945
errmsg("relation \"%s\" already exists", relname)));
946+
}
928947

929948
/*
930949
* Since we are going to create a rowtype as well, also check for

src/backend/catalog/toasting.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.32 2010/02/26 02:00:37 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.33 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -223,7 +223,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
223223
ONCOMMIT_NOOP,
224224
reloptions,
225225
false,
226-
true);
226+
true,
227+
false);
228+
Assert(toast_relid != InvalidOid);
227229

228230
/* make the toast relation visible, else index creation will fail */
229231
CommandCounterIncrement();

src/backend/commands/cluster.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.203 2010/04/28 16:10:41 heikki Exp $
14+
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.204 2010/07/25 23:21:21 rhaas Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -687,7 +687,9 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace)
687687
ONCOMMIT_NOOP,
688688
reloptions,
689689
false,
690-
true);
690+
true,
691+
false);
692+
Assert(OIDNewHeap != InvalidOid);
691693

692694
ReleaseSysCache(tuple);
693695

src/backend/commands/sequence.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.168 2010/02/20 21:24:02 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.169 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -203,8 +203,10 @@ DefineSequence(CreateSeqStmt *seq)
203203
stmt->options = list_make1(defWithOids(false));
204204
stmt->oncommit = ONCOMMIT_NOOP;
205205
stmt->tablespacename = NULL;
206+
stmt->if_not_exists = false;
206207

207208
seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
209+
Assert(seqoid != InvalidOid);
208210

209211
rel = heap_open(seqoid, AccessExclusiveLock);
210212
tupDesc = RelationGetDescr(rel);

src/backend/commands/tablecmds.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.333 2010/07/23 20:04:18 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.334 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -548,8 +548,18 @@ DefineRelation(CreateStmt *stmt, char relkind)
548548
stmt->oncommit,
549549
reloptions,
550550
true,
551-
allowSystemTableMods);
551+
allowSystemTableMods,
552+
stmt->if_not_exists);
552553

554+
/*
555+
* If heap_create_with_catalog returns InvalidOid, it means that the user
556+
* specified "IF NOT EXISTS" and the relation already exists. In that
557+
* case we do nothing further.
558+
*/
559+
if (relationId == InvalidOid)
560+
return InvalidOid;
561+
562+
/* Store inheritance information for new rel. */
553563
StoreCatalogInheritance(relationId, inheritOids);
554564

555565
/*

src/backend/commands/typecmds.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.148 2010/02/26 02:00:40 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.149 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
* DESCRIPTION
1414
* The "DefineFoo" routines take the parse tree and pick out the
@@ -1506,6 +1506,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
15061506
CreateStmt *createStmt = makeNode(CreateStmt);
15071507
Oid old_type_oid;
15081508
Oid typeNamespace;
1509+
Oid relid;
15091510

15101511
if (coldeflist == NIL)
15111512
ereport(ERROR,
@@ -1523,6 +1524,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
15231524
createStmt->options = list_make1(defWithOids(false));
15241525
createStmt->oncommit = ONCOMMIT_NOOP;
15251526
createStmt->tablespacename = NULL;
1527+
createStmt->if_not_exists = false;
15261528

15271529
/*
15281530
* Check for collision with an existing type name. If there is one and
@@ -1546,7 +1548,9 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
15461548
/*
15471549
* Finally create the relation. This also creates the type.
15481550
*/
1549-
return DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE);
1551+
relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE);
1552+
Assert(relid != InvalidOid);
1553+
return relid;
15501554
}
15511555

15521556
/*

src/backend/commands/view.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.120 2010/01/02 16:57:40 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.121 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -222,6 +222,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
222222
}
223223
else
224224
{
225+
Oid relid;
226+
225227
/*
226228
* now set the parameters for keys/inheritance etc. All of these are
227229
* uninteresting for views...
@@ -233,13 +235,16 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
233235
createStmt->options = list_make1(defWithOids(false));
234236
createStmt->oncommit = ONCOMMIT_NOOP;
235237
createStmt->tablespacename = NULL;
238+
createStmt->if_not_exists = false;
236239

237240
/*
238241
* finally create the relation (this will error out if there's an
239242
* existing view, so we don't need more code to complain if "replace"
240243
* is false).
241244
*/
242-
return DefineRelation(createStmt, RELKIND_VIEW);
245+
relid = DefineRelation(createStmt, RELKIND_VIEW);
246+
Assert(relid != InvalidOid);
247+
return relid;
243248
}
244249
}
245250

src/backend/executor/execMain.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.352 2010/07/22 00:47:52 rhaas Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.353 2010/07/25 23:21:21 rhaas Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -2190,7 +2190,9 @@ OpenIntoRel(QueryDesc *queryDesc)
21902190
into->onCommit,
21912191
reloptions,
21922192
true,
2193-
allowSystemTableMods);
2193+
allowSystemTableMods,
2194+
false);
2195+
Assert(intoRelationId != InvalidOid);
21942196

21952197
FreeTupleDesc(tupdesc);
21962198

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.465 2010/07/12 17:01:05 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.466 2010/07/25 23:21:21 rhaas Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2537,6 +2537,7 @@ _copyCreateStmt(CreateStmt *from)
25372537
COPY_NODE_FIELD(options);
25382538
COPY_SCALAR_FIELD(oncommit);
25392539
COPY_STRING_FIELD(tablespacename);
2540+
COPY_SCALAR_FIELD(if_not_exists);
25402541

25412542
return newnode;
25422543
}

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1994, Regents of the University of California
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.385 2010/02/26 02:00:43 momjian Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.386 2010/07/25 23:21:21 rhaas Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -1104,6 +1104,7 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
11041104
COMPARE_NODE_FIELD(options);
11051105
COMPARE_SCALAR_FIELD(oncommit);
11061106
COMPARE_STRING_FIELD(tablespacename);
1107+
COMPARE_SCALAR_FIELD(if_not_exists);
11071108

11081109
return true;
11091110
}

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.386 2010/07/12 17:01:05 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.387 2010/07/25 23:21:21 rhaas Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1795,6 +1795,7 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
17951795
WRITE_NODE_FIELD(options);
17961796
WRITE_ENUM_FIELD(oncommit, OnCommitAction);
17971797
WRITE_STRING_FIELD(tablespacename);
1798+
WRITE_BOOL_FIELD(if_not_exists);
17981799
}
17991800

18001801
static void

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy