Commit a3b012b5 authored by Robert Haas's avatar Robert Haas

CREATE TABLE IF NOT EXISTS.

Reviewed by Bernd Helmle.
parent edff75be
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.128 2010/06/07 02:59:02 itagaki Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.129 2010/07/25 23:21:21 rhaas Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -21,7 +21,7 @@ PostgreSQL documentation ...@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv> <refsynopsisdiv>
<synopsis> <synopsis>
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> ( [ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable> ( [
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ] { <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
| <replaceable>table_constraint</replaceable> | <replaceable>table_constraint</replaceable>
| LIKE <replaceable>parent_table</replaceable> [ <replaceable>like_option</replaceable> ... ] } | LIKE <replaceable>parent_table</replaceable> [ <replaceable>like_option</replaceable> ... ] }
...@@ -32,7 +32,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR ...@@ -32,7 +32,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ] [ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
OF <replaceable class="PARAMETER">type_name</replaceable> [ ( OF <replaceable class="PARAMETER">type_name</replaceable> [ (
{ <replaceable class="PARAMETER">column_name</replaceable> WITH OPTIONS [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ] { <replaceable class="PARAMETER">column_name</replaceable> WITH OPTIONS [ DEFAULT <replaceable>default_expr</replaceable> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
| <replaceable>table_constraint</replaceable> } | <replaceable>table_constraint</replaceable> }
...@@ -163,6 +163,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR ...@@ -163,6 +163,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>IF NOT EXISTS</></term>
<listitem>
<para>
Do not throw an error if a relation with the same name already exists.
A notice is issued in this case. Note that there is no guarantee that
the existing relation is anything like the one that would have been
created.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="PARAMETER">table_name</replaceable></term> <term><replaceable class="PARAMETER">table_name</replaceable></term>
<listitem> <listitem>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.105 2010/02/07 20:48:09 tgl Exp $ * $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.106 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -245,7 +245,8 @@ Boot_CreateStmt: ...@@ -245,7 +245,8 @@ Boot_CreateStmt:
ONCOMMIT_NOOP, ONCOMMIT_NOOP,
(Datum) 0, (Datum) 0,
false, false,
true); true,
false);
elog(DEBUG4, "relation created with oid %u", id); elog(DEBUG4, "relation created with oid %u", id);
} }
do_end(); do_end();
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.373 2010/04/05 01:09:52 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.374 2010/07/25 23:21:21 rhaas Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -903,11 +903,13 @@ heap_create_with_catalog(const char *relname, ...@@ -903,11 +903,13 @@ heap_create_with_catalog(const char *relname,
OnCommitAction oncommit, OnCommitAction oncommit,
Datum reloptions, Datum reloptions,
bool use_user_acl, bool use_user_acl,
bool allow_system_table_mods) bool allow_system_table_mods,
bool if_not_exists)
{ {
Relation pg_class_desc; Relation pg_class_desc;
Relation new_rel_desc; Relation new_rel_desc;
Acl *relacl; Acl *relacl;
Oid existing_relid;
Oid old_type_oid; Oid old_type_oid;
Oid new_type_oid; Oid new_type_oid;
Oid new_array_oid = InvalidOid; Oid new_array_oid = InvalidOid;
...@@ -921,10 +923,27 @@ heap_create_with_catalog(const char *relname, ...@@ -921,10 +923,27 @@ heap_create_with_catalog(const char *relname,
CheckAttributeNamesTypes(tupdesc, relkind, allow_system_table_mods); CheckAttributeNamesTypes(tupdesc, relkind, allow_system_table_mods);
if (get_relname_relid(relname, relnamespace)) /*
* If the relation already exists, it's an error, unless the user specifies
* "IF NOT EXISTS". In that case, we just print a notice and do nothing
* further.
*/
existing_relid = get_relname_relid(relname, relnamespace);
if (existing_relid != InvalidOid)
{
if (if_not_exists)
{
ereport(NOTICE,
(errcode(ERRCODE_DUPLICATE_TABLE),
errmsg("relation \"%s\" already exists, skipping",
relname)));
heap_close(pg_class_desc, RowExclusiveLock);
return InvalidOid;
}
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_TABLE), (errcode(ERRCODE_DUPLICATE_TABLE),
errmsg("relation \"%s\" already exists", relname))); errmsg("relation \"%s\" already exists", relname)));
}
/* /*
* Since we are going to create a rowtype as well, also check for * Since we are going to create a rowtype as well, also check for
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.32 2010/02/26 02:00:37 momjian Exp $ * $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.33 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -223,7 +223,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio ...@@ -223,7 +223,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
ONCOMMIT_NOOP, ONCOMMIT_NOOP,
reloptions, reloptions,
false, false,
true); true,
false);
Assert(toast_relid != InvalidOid);
/* make the toast relation visible, else index creation will fail */ /* make the toast relation visible, else index creation will fail */
CommandCounterIncrement(); CommandCounterIncrement();
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.203 2010/04/28 16:10:41 heikki Exp $ * $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.204 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -687,7 +687,9 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace) ...@@ -687,7 +687,9 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace)
ONCOMMIT_NOOP, ONCOMMIT_NOOP,
reloptions, reloptions,
false, false,
true); true,
false);
Assert(OIDNewHeap != InvalidOid);
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.168 2010/02/20 21:24:02 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.169 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -203,8 +203,10 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -203,8 +203,10 @@ DefineSequence(CreateSeqStmt *seq)
stmt->options = list_make1(defWithOids(false)); stmt->options = list_make1(defWithOids(false));
stmt->oncommit = ONCOMMIT_NOOP; stmt->oncommit = ONCOMMIT_NOOP;
stmt->tablespacename = NULL; stmt->tablespacename = NULL;
stmt->if_not_exists = false;
seqoid = DefineRelation(stmt, RELKIND_SEQUENCE); seqoid = DefineRelation(stmt, RELKIND_SEQUENCE);
Assert(seqoid != InvalidOid);
rel = heap_open(seqoid, AccessExclusiveLock); rel = heap_open(seqoid, AccessExclusiveLock);
tupDesc = RelationGetDescr(rel); tupDesc = RelationGetDescr(rel);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.333 2010/07/23 20:04:18 petere Exp $ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.334 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -548,8 +548,18 @@ DefineRelation(CreateStmt *stmt, char relkind) ...@@ -548,8 +548,18 @@ DefineRelation(CreateStmt *stmt, char relkind)
stmt->oncommit, stmt->oncommit,
reloptions, reloptions,
true, true,
allowSystemTableMods); allowSystemTableMods,
stmt->if_not_exists);
/*
* If heap_create_with_catalog returns InvalidOid, it means that the user
* specified "IF NOT EXISTS" and the relation already exists. In that
* case we do nothing further.
*/
if (relationId == InvalidOid)
return InvalidOid;
/* Store inheritance information for new rel. */
StoreCatalogInheritance(relationId, inheritOids); StoreCatalogInheritance(relationId, inheritOids);
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.148 2010/02/26 02:00:40 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.149 2010/07/25 23:21:21 rhaas Exp $
* *
* DESCRIPTION * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
...@@ -1506,6 +1506,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -1506,6 +1506,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
CreateStmt *createStmt = makeNode(CreateStmt); CreateStmt *createStmt = makeNode(CreateStmt);
Oid old_type_oid; Oid old_type_oid;
Oid typeNamespace; Oid typeNamespace;
Oid relid;
if (coldeflist == NIL) if (coldeflist == NIL)
ereport(ERROR, ereport(ERROR,
...@@ -1523,6 +1524,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -1523,6 +1524,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
createStmt->options = list_make1(defWithOids(false)); createStmt->options = list_make1(defWithOids(false));
createStmt->oncommit = ONCOMMIT_NOOP; createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL; createStmt->tablespacename = NULL;
createStmt->if_not_exists = false;
/* /*
* Check for collision with an existing type name. If there is one and * Check for collision with an existing type name. If there is one and
...@@ -1546,7 +1548,9 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) ...@@ -1546,7 +1548,9 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
/* /*
* Finally create the relation. This also creates the type. * Finally create the relation. This also creates the type.
*/ */
return DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE); relid = DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE);
Assert(relid != InvalidOid);
return relid;
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.120 2010/01/02 16:57:40 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.121 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -222,6 +222,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) ...@@ -222,6 +222,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
} }
else else
{ {
Oid relid;
/* /*
* now set the parameters for keys/inheritance etc. All of these are * now set the parameters for keys/inheritance etc. All of these are
* uninteresting for views... * uninteresting for views...
...@@ -233,13 +235,16 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) ...@@ -233,13 +235,16 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
createStmt->options = list_make1(defWithOids(false)); createStmt->options = list_make1(defWithOids(false));
createStmt->oncommit = ONCOMMIT_NOOP; createStmt->oncommit = ONCOMMIT_NOOP;
createStmt->tablespacename = NULL; createStmt->tablespacename = NULL;
createStmt->if_not_exists = false;
/* /*
* finally create the relation (this will error out if there's an * finally create the relation (this will error out if there's an
* existing view, so we don't need more code to complain if "replace" * existing view, so we don't need more code to complain if "replace"
* is false). * is false).
*/ */
return DefineRelation(createStmt, RELKIND_VIEW); relid = DefineRelation(createStmt, RELKIND_VIEW);
Assert(relid != InvalidOid);
return relid;
} }
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.352 2010/07/22 00:47:52 rhaas Exp $ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.353 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2190,7 +2190,9 @@ OpenIntoRel(QueryDesc *queryDesc) ...@@ -2190,7 +2190,9 @@ OpenIntoRel(QueryDesc *queryDesc)
into->onCommit, into->onCommit,
reloptions, reloptions,
true, true,
allowSystemTableMods); allowSystemTableMods,
false);
Assert(intoRelationId != InvalidOid);
FreeTupleDesc(tupdesc); FreeTupleDesc(tupdesc);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.465 2010/07/12 17:01:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.466 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2537,6 +2537,7 @@ _copyCreateStmt(CreateStmt *from) ...@@ -2537,6 +2537,7 @@ _copyCreateStmt(CreateStmt *from)
COPY_NODE_FIELD(options); COPY_NODE_FIELD(options);
COPY_SCALAR_FIELD(oncommit); COPY_SCALAR_FIELD(oncommit);
COPY_STRING_FIELD(tablespacename); COPY_STRING_FIELD(tablespacename);
COPY_SCALAR_FIELD(if_not_exists);
return newnode; return newnode;
} }
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.385 2010/02/26 02:00:43 momjian Exp $ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.386 2010/07/25 23:21:21 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1104,6 +1104,7 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b) ...@@ -1104,6 +1104,7 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(options);
COMPARE_SCALAR_FIELD(oncommit); COMPARE_SCALAR_FIELD(oncommit);
COMPARE_STRING_FIELD(tablespacename); COMPARE_STRING_FIELD(tablespacename);
COMPARE_SCALAR_FIELD(if_not_exists);
return true; return true;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.386 2010/07/12 17:01:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.387 2010/07/25 23:21:21 rhaas Exp $
* *
* NOTES * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * Every node type that can appear in stored rules' parsetrees *must*
...@@ -1795,6 +1795,7 @@ _outCreateStmt(StringInfo str, CreateStmt *node) ...@@ -1795,6 +1795,7 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
WRITE_NODE_FIELD(options); WRITE_NODE_FIELD(options);
WRITE_ENUM_FIELD(oncommit, OnCommitAction); WRITE_ENUM_FIELD(oncommit, OnCommitAction);
WRITE_STRING_FIELD(tablespacename); WRITE_STRING_FIELD(tablespacename);
WRITE_BOOL_FIELD(if_not_exists);
} }
static void static void
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.713 2010/06/13 17:43:12 rhaas Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.714 2010/07/25 23:21:21 rhaas Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -2212,6 +2212,23 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' ...@@ -2212,6 +2212,23 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->options = $9; n->options = $9;
n->oncommit = $10; n->oncommit = $10;
n->tablespacename = $11; n->tablespacename = $11;
n->if_not_exists = false;
$$ = (Node *)n;
}
| CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '('
OptTableElementList ')' OptInherit OptWith OnCommitOption
OptTableSpace
{
CreateStmt *n = makeNode(CreateStmt);
$7->istemp = $2;
n->relation = $7;
n->tableElts = $9;
n->inhRelations = $11;
n->constraints = NIL;
n->options = $12;
n->oncommit = $13;
n->tablespacename = $14;
n->if_not_exists = true;
$$ = (Node *)n; $$ = (Node *)n;
} }
| CREATE OptTemp TABLE qualified_name OF any_name | CREATE OptTemp TABLE qualified_name OF any_name
...@@ -2227,6 +2244,22 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' ...@@ -2227,6 +2244,22 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
n->options = $8; n->options = $8;
n->oncommit = $9; n->oncommit = $9;
n->tablespacename = $10; n->tablespacename = $10;
n->if_not_exists = false;
$$ = (Node *)n;
}
| CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name
OptTypedTableElementList OptWith OnCommitOption OptTableSpace
{
CreateStmt *n = makeNode(CreateStmt);
n->relation = $7;
n->tableElts = $10;
n->ofTypename = makeTypeNameFromNameList($9);
n->ofTypename->location = @9;
n->constraints = NIL;
n->options = $11;
n->oncommit = $12;
n->tablespacename = $13;
n->if_not_exists = true;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.335 2010/02/26 02:01:04 momjian Exp $ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.336 2010/07/25 23:21:22 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -512,6 +512,13 @@ standard_ProcessUtility(Node *parsetree, ...@@ -512,6 +512,13 @@ standard_ProcessUtility(Node *parsetree,
relOid = DefineRelation((CreateStmt *) stmt, relOid = DefineRelation((CreateStmt *) stmt,
RELKIND_RELATION); RELKIND_RELATION);
/*
* If "IF NOT EXISTS" was specified and the relation
* already exists, do nothing further.
*/
if (relOid == InvalidOid)
continue;
/* /*
* Let AlterTableCreateToastTable decide if this one * Let AlterTableCreateToastTable decide if this one
* needs a secondary relation too. * needs a secondary relation too.
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.98 2010/02/26 02:01:21 momjian Exp $ * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.99 2010/07/25 23:21:22 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -61,7 +61,8 @@ extern Oid heap_create_with_catalog(const char *relname, ...@@ -61,7 +61,8 @@ extern Oid heap_create_with_catalog(const char *relname,
OnCommitAction oncommit, OnCommitAction oncommit,
Datum reloptions, Datum reloptions,
bool use_user_acl, bool use_user_acl,
bool allow_system_table_mods); bool allow_system_table_mods,
bool if_not_exists);
extern void heap_drop_with_catalog(Oid relid); extern void heap_drop_with_catalog(Oid relid);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.432 2010/02/26 02:01:25 momjian Exp $ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.433 2010/07/25 23:21:22 rhaas Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1375,6 +1375,7 @@ typedef struct CreateStmt ...@@ -1375,6 +1375,7 @@ typedef struct CreateStmt
List *options; /* options from WITH clause */ List *options; /* options from WITH clause */
OnCommitAction oncommit; /* what do we do at COMMIT? */ OnCommitAction oncommit; /* what do we do at COMMIT? */
char *tablespacename; /* table space to use, or NULL */ char *tablespacename; /* table space to use, or NULL */
bool if_not_exists; /* just do nothing if it already exists? */
} CreateStmt; } CreateStmt;
/* ---------- /* ----------
......
...@@ -196,7 +196,11 @@ CREATE TABLE array_index_op_test ( ...@@ -196,7 +196,11 @@ CREATE TABLE array_index_op_test (
i int4[], i int4[],
t text[] t text[]
); );
CREATE TABLE test_tsvector( CREATE TABLE IF NOT EXISTS test_tsvector(
t text, t text,
a tsvector a tsvector
); );
CREATE TABLE IF NOT EXISTS test_tsvector(
t text
);
NOTICE: relation "test_tsvector" already exists, skipping
...@@ -2,6 +2,8 @@ CREATE TABLE ttable1 OF nothing; ...@@ -2,6 +2,8 @@ CREATE TABLE ttable1 OF nothing;
ERROR: type "nothing" does not exist ERROR: type "nothing" does not exist
CREATE TYPE person_type AS (id int, name text); CREATE TYPE person_type AS (id int, name text);
CREATE TABLE persons OF person_type; CREATE TABLE persons OF person_type;
CREATE TABLE IF NOT EXISTS persons OF person_type;
NOTICE: relation "persons" already exists, skipping
SELECT * FROM persons; SELECT * FROM persons;
id | name id | name
----+------ ----+------
......
...@@ -232,8 +232,11 @@ CREATE TABLE array_index_op_test ( ...@@ -232,8 +232,11 @@ CREATE TABLE array_index_op_test (
t text[] t text[]
); );
CREATE TABLE test_tsvector( CREATE TABLE IF NOT EXISTS test_tsvector(
t text, t text,
a tsvector a tsvector
); );
CREATE TABLE IF NOT EXISTS test_tsvector(
t text
);
...@@ -2,6 +2,7 @@ CREATE TABLE ttable1 OF nothing; ...@@ -2,6 +2,7 @@ CREATE TABLE ttable1 OF nothing;
CREATE TYPE person_type AS (id int, name text); CREATE TYPE person_type AS (id int, name text);
CREATE TABLE persons OF person_type; CREATE TABLE persons OF person_type;
CREATE TABLE IF NOT EXISTS persons OF person_type;
SELECT * FROM persons; SELECT * FROM persons;
\d persons \d persons
......
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