create_user_mapping_if_not_exists.patch
text/x-patch
Filename: create_user_mapping_if_not_exists.patch
Type: text/x-patch
Part: 1
Patch
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/create_user_mapping.sgml | 13 | 1 |
| src/backend/commands/foreigncmds.c | 16 | 1 |
| src/backend/parser/gram.y | 10 | 0 |
| src/include/nodes/parsenodes.h | 1 | 0 |
commit 4237a23d6674da774b0772ffc953e5f499c04803
Author: Anastasia <a.lubennikova@postgrespro.ru>
Date: Fri Jan 13 16:23:53 2017 +0300
Add [IF NOT EXISTS] option to CREATE USER MAPPING statement
diff --git a/doc/src/sgml/ref/create_user_mapping.sgml b/doc/src/sgml/ref/create_user_mapping.sgml
index 44fe302..680906b 100644
--- a/doc/src/sgml/ref/create_user_mapping.sgml
+++ b/doc/src/sgml/ref/create_user_mapping.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
-CREATE USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_USER | PUBLIC }
+CREATE USER MAPPING [IF NOT EXISTS] FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_USER | PUBLIC }
SERVER <replaceable class="parameter">server_name</replaceable>
[ OPTIONS ( <replaceable class="PARAMETER">option</replaceable> '<replaceable class="PARAMETER">value</replaceable>' [ , ... ] ) ]
</synopsis>
@@ -49,6 +49,18 @@ CREATE USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable>
<refsect1>
<title>Parameters</title>
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</></term>
+ <listitem>
+ <para>
+ Do not throw an error if a user mapping with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing user mapping is anything like the one that would have been
+ created.
+ </para>
+ </listitem>
+ </varlistentry>
+
<variablelist>
<varlistentry>
<term><replaceable class="parameter">user_name</replaceable></term>
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 0b0114c..32fa6a5 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -1172,12 +1172,27 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER,
ObjectIdGetDatum(useId),
ObjectIdGetDatum(srv->serverid));
+
if (OidIsValid(umId))
- ereport(ERROR,
+ {
+ if (stmt->if_not_exists)
+ {
+ ereport(NOTICE,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("user mapping \"%s\" already exists for server %s, skipping",
+ MappingUserName(useId),
+ stmt->servername)));
+
+ heap_close(rel, RowExclusiveLock);
+ return InvalidObjectAddress;
+ }
+ else
+ ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("user mapping \"%s\" already exists for server %s",
MappingUserName(useId),
stmt->servername)));
+ }
fdw = GetForeignDataWrapper(srv->fdwid);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ab4b3b1..2fb713f 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4897,6 +4897,16 @@ CreateUserMappingStmt: CREATE USER MAPPING FOR auth_ident SERVER name create_gen
n->user = $5;
n->servername = $7;
n->options = $8;
+ n->if_not_exists = false;
+ $$ = (Node *) n;
+ }
+ | CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options
+ {
+ CreateUserMappingStmt *n = makeNode(CreateUserMappingStmt);
+ n->user = $8;
+ n->servername = $10;
+ n->options = $11;
+ n->if_not_exists = true;
$$ = (Node *) n;
}
;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 8a79ec0..bb7c02f 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2110,6 +2110,7 @@ typedef struct CreateUserMappingStmt
NodeTag type;
RoleSpec *user; /* user role */
char *servername; /* server name */
+ bool if_not_exists; /* just do nothing if it already exists? */
List *options; /* generic options to server */
} CreateUserMappingStmt;