diff options
| author | Fujii Masao <fujii@postgresql.org> | 2014-11-06 18:48:33 +0900 |
|---|---|---|
| committer | Fujii Masao <fujii@postgresql.org> | 2014-11-06 18:48:33 +0900 |
| commit | 08309aaf74ee879699165ec8a2d53e56f2d2e947 (patch) | |
| tree | 81f6326b3d2f6b47d6d4a2a50494e82709dcf534 /src/backend | |
| parent | 171c377a0abe12d1418540dc154feccd9355995e (diff) | |
| download | postgresql-08309aaf74ee879699165ec8a2d53e56f2d2e947.tar.gz | |
Implement IF NOT EXIST for CREATE INDEX.
FabrÃzio de Royes Mello, reviewed by Marti Raudsepp, Adam Brightwell and me.
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/catalog/index.c | 17 | ||||
| -rw-r--r-- | src/backend/catalog/toasting.c | 2 | ||||
| -rw-r--r-- | src/backend/commands/indexcmds.c | 9 | ||||
| -rw-r--r-- | src/backend/nodes/copyfuncs.c | 1 | ||||
| -rw-r--r-- | src/backend/nodes/equalfuncs.c | 1 | ||||
| -rw-r--r-- | src/backend/parser/gram.y | 26 |
6 files changed, 53 insertions, 3 deletions
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 01ed880b1c..0c31aa95d7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -674,6 +674,8 @@ UpdateIndexRelation(Oid indexoid, * will be marked "invalid" and the caller must take additional steps * to fix it up. * is_internal: if true, post creation hook for new index + * if_not_exists: if true, do not throw an error if a relation with + * the same name already exists. * * Returns the OID of the created index. */ @@ -697,7 +699,8 @@ index_create(Relation heapRelation, bool allow_system_table_mods, bool skip_build, bool concurrent, - bool is_internal) + bool is_internal, + bool if_not_exists) { Oid heapRelationId = RelationGetRelid(heapRelation); Relation pg_class; @@ -773,10 +776,22 @@ index_create(Relation heapRelation, elog(ERROR, "shared relations must be placed in pg_global tablespace"); if (get_relname_relid(indexRelationName, namespaceId)) + { + if (if_not_exists) + { + ereport(NOTICE, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" already exists, skipping", + indexRelationName))); + heap_close(pg_class, RowExclusiveLock); + return InvalidOid; + } + ereport(ERROR, (errcode(ERRCODE_DUPLICATE_TABLE), errmsg("relation \"%s\" already exists", indexRelationName))); + } /* * construct tuple descriptor for index tuples diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 160f006ecd..5ef6dccb91 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -342,7 +342,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, rel->rd_rel->reltablespace, collationObjectId, classObjectId, coloptions, (Datum) 0, true, false, false, false, - true, false, false, true); + true, false, false, true, false); heap_close(toast_rel, NoLock); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 3c1e90eb0e..02055950b5 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -610,7 +610,14 @@ DefineIndex(Oid relationId, stmt->isconstraint, stmt->deferrable, stmt->initdeferred, allowSystemTableMods, skip_build || stmt->concurrent, - stmt->concurrent, !check_rights); + stmt->concurrent, !check_rights, + stmt->if_not_exists); + + if (!OidIsValid(indexRelationId)) + { + heap_close(rel, NoLock); + return indexRelationId; + } /* Add any requested comment */ if (stmt->idxcomment != NULL) diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 21b070acda..7b51d33177 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2907,6 +2907,7 @@ _copyIndexStmt(const IndexStmt *from) COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); COPY_SCALAR_FIELD(concurrent); + COPY_SCALAR_FIELD(if_not_exists); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 358395f61f..d5db71d3a8 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1210,6 +1210,7 @@ _equalIndexStmt(const IndexStmt *a, const IndexStmt *b) COMPARE_SCALAR_FIELD(deferrable); COMPARE_SCALAR_FIELD(initdeferred); COMPARE_SCALAR_FIELD(concurrent); + COMPARE_SCALAR_FIELD(if_not_exists); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 0de9584e53..bd180e7e87 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -6434,6 +6434,32 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name n->isconstraint = false; n->deferrable = false; n->initdeferred = false; + n->if_not_exists = false; + $$ = (Node *)n; + } + | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS index_name + ON qualified_name access_method_clause '(' index_params ')' + opt_reloptions OptTableSpace where_clause + { + IndexStmt *n = makeNode(IndexStmt); + n->unique = $2; + n->concurrent = $4; + n->idxname = $8; + n->relation = $10; + n->accessMethod = $11; + n->indexParams = $13; + n->options = $15; + n->tableSpace = $16; + n->whereClause = $17; + n->excludeOpNames = NIL; + n->idxcomment = NULL; + n->indexOid = InvalidOid; + n->oldNode = InvalidOid; + n->primary = false; + n->isconstraint = false; + n->deferrable = false; + n->initdeferred = false; + n->if_not_exists = true; $$ = (Node *)n; } ; |
