From a27af2ef1cd72ae1eeac635823fc2036051c7213 Mon Sep 17 00:00:00 2001
From: Ayush Vatsa <ayuvatsa@amazon.com>
Date: Mon, 12 Aug 2024 01:29:46 +0530
Subject: [PATCH v2 2/2] fix alter_server, alter_foreign_data_wrapper,
 alter_foreign_table and alter_user_mapping documentation

---
 .../sgml/ref/alter_foreign_data_wrapper.sgml  | 51 +++++++++++++---
 doc/src/sgml/ref/alter_foreign_table.sgml     | 43 +++++++++++---
 doc/src/sgml/ref/alter_server.sgml            | 59 ++++++++++++++++---
 doc/src/sgml/ref/alter_user_mapping.sgml      | 42 ++++++++++---
 4 files changed, 167 insertions(+), 28 deletions(-)

diff --git a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml
index dc0957d965..c20cc479d9 100644
--- a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml
+++ b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml
@@ -24,7 +24,7 @@ PostgreSQL documentation
 ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
     [ HANDLER <replaceable class="parameter">handler_function</replaceable> | NO HANDLER ]
     [ VALIDATOR <replaceable class="parameter">validator_function</replaceable> | NO VALIDATOR ]
-    [ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ]) ]
+    [ OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ]) ]
 ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
 ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
 </synopsis>
@@ -113,15 +113,43 @@ ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> REN
    </varlistentry>
 
    <varlistentry>
-    <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+    <term><literal>OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
     <listitem>
      <para>
       Change options for the foreign-data
-      wrapper.  <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
-      specify the action to be performed.  <literal>ADD</literal> is assumed
-      if no operation is explicitly specified.  Option names must be
-      unique; names and values are also validated using the foreign
-      data wrapper's validator function, if any.
+      wrapper.  <literal>ADD</literal>, <literal>SET</literal>, <literal>DROP</literal>,
+      <literal>APPEND</literal> and <literal>REMOVE</literal> specify the action to be
+      performed.  <literal>ADD</literal> is assumed if no operation is explicitly
+      specified.  Option names must be unique; names and values are also validated
+      using the foreign data wrapper's validator function, if any.
+     </para>
+
+     <para>
+      <literal>ADD</literal> can only be used for option names that don't already exist.
+      It sets the specified name's value as provided.
+     </para>
+
+     <para>
+      <literal>SET</literal> can only be used for option names that already exist.
+      It overwrites the entire existing value for the specified option.
+     </para>
+
+     <para>
+      <literal>DROP</literal> can only be used for option names that already exist.
+      It removes the specified name from the list of OPTIONS.
+     </para>
+
+     <para>
+      <literal>APPEND</literal> can be used regardless of whether the option name exists or not.
+      If the option name doesn't exist, it acts like <literal>ADD</literal>.
+      If it does exist, it adds the provided values to the existing ones.
+     </para>
+
+     <para>
+      <literal>REMOVE</literal> can only be used for option names that already exist.
+      It removes the provided values from the values of the specified option name.
+      If some provided values don't exist in the option values, they won't have any effect.
+      Only the values that exist in the options will be removed.
      </para>
     </listitem>
    </varlistentry>
@@ -157,6 +185,15 @@ ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo '1', DROP bar);
 </programlisting>
   </para>
 
+  <para>
+   Change a foreign-data wrapper <literal>dbi</literal>, add
+   values in option <literal>foo</literal>, and remove values from
+   option <literal>bar</literal>:
+<programlisting>
+ALTER FOREIGN DATA WRAPPER dbi OPTIONS (APPEND foo '1, 2, 3', REMOVE bar '1, 2');
+</programlisting>
+  </para>
+
   <para>
    Change the foreign-data wrapper <literal>dbi</literal> validator
    to <literal>bob.myvalidator</literal>:
diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml
index 3cb6f08fcf..b417f74026 100644
--- a/doc/src/sgml/ref/alter_foreign_table.sgml
+++ b/doc/src/sgml/ref/alter_foreign_table.sgml
@@ -42,7 +42,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceab
     ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
     ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )
     ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT }
-    ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ])
+    ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ])
     ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]
     VALIDATE CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
     DROP CONSTRAINT [ IF EXISTS ]  <replaceable class="parameter">constraint_name</replaceable> [ RESTRICT | CASCADE ]
@@ -54,7 +54,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceab
     INHERIT <replaceable class="parameter">parent_table</replaceable>
     NO INHERIT <replaceable class="parameter">parent_table</replaceable>
     OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
-    OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ])
+    OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ])
 </synopsis>
  </refsynopsisdiv>
 
@@ -266,17 +266,46 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceab
    </varlistentry>
 
    <varlistentry>
-    <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+    <term><literal>OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
     <listitem>
      <para>
       Change options for the foreign table or one of its columns.
-      <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
-      specify the action to be performed.  <literal>ADD</literal> is assumed
-      if no operation is explicitly specified.  Duplicate option names are not
+      <literal>ADD</literal>, <literal>SET</literal>, <literal>DROP</literal>,
+      <literal>APPEND</literal> and <literal>REMOVE</literal> specify the action to be
+      performed.  <literal>ADD</literal> is assumed if no operation is explicitly
+      specified.  Duplicate option names are not
       allowed (although it's OK for a table option and a column option to have
       the same name).  Option names and values are also validated using the
       foreign data wrapper library.
      </para>
+
+     <para>
+      <literal>ADD</literal> can only be used for option names that don't already exist.
+      It sets the specified name's value as provided.
+     </para>
+
+     <para>
+      <literal>SET</literal> can only be used for option names that already exist.
+      It overwrites the entire existing value for the specified option.
+     </para>
+
+     <para>
+      <literal>DROP</literal> can only be used for option names that already exist.
+      It removes the specified name from the list of OPTIONS.
+     </para>
+
+     <para>
+      <literal>APPEND</literal> can be used regardless of whether the option name exists or not.
+      If the option name doesn't exist, it acts like <literal>ADD</literal>.
+      If it does exist, it adds the provided values to the existing ones.
+     </para>
+
+     <para>
+      <literal>REMOVE</literal> can only be used for option names that already exist.
+      It removes the provided values from the values of the specified option name.
+      If some provided values don't exist in the option values, they won't have any effect.
+      Only the values that exist in the options will be removed.
+     </para>
     </listitem>
    </varlistentry>
 
@@ -521,7 +550,7 @@ ALTER FOREIGN TABLE distributors ALTER COLUMN street SET NOT NULL;
   <para>
    To change options of a foreign table:
 <programlisting>
-ALTER FOREIGN TABLE myschema.distributors OPTIONS (ADD opt1 'value', SET opt2 'value2', DROP opt3);
+ALTER FOREIGN TABLE myschema.distributors OPTIONS (ADD opt1 'value', SET opt2 'value2', DROP opt3, APPEND opt4 'value3, value4', REMOVE opt5 'value5, value6');
 </programlisting></para>
 
  </refsect1>
diff --git a/doc/src/sgml/ref/alter_server.sgml b/doc/src/sgml/ref/alter_server.sgml
index 467bf85589..953fdf1bc2 100644
--- a/doc/src/sgml/ref/alter_server.sgml
+++ b/doc/src/sgml/ref/alter_server.sgml
@@ -22,7 +22,7 @@ PostgreSQL documentation
  <refsynopsisdiv>
 <synopsis>
 ALTER SERVER <replaceable class="parameter">name</replaceable> [ VERSION '<replaceable class="parameter">new_version</replaceable>' ]
-    [ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] ) ]
+    [ OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] ) ]
 ALTER SERVER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
 ALTER SERVER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
 </synopsis>
@@ -71,15 +71,43 @@ ALTER SERVER <replaceable class="parameter">name</replaceable> RENAME TO <replac
    </varlistentry>
 
    <varlistentry>
-    <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+    <term><literal>OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
     <listitem>
      <para>
       Change options for the
-      server.  <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
-      specify the action to be performed.  <literal>ADD</literal> is assumed
-      if no operation is explicitly specified.  Option names must be
-      unique; names and values are also validated using the server's
-      foreign-data wrapper library.
+      server.  <literal>ADD</literal>, <literal>SET</literal>, <literal>DROP</literal>,
+      <literal>APPEND</literal> and <literal>REMOVE</literal> specify the action to be
+      performed.  <literal>ADD</literal> is assumed if no operation is explicitly
+      specified.  Option names must be unique; names and values are also validated
+      using the server's foreign-data wrapper library.
+     </para>
+
+     <para>
+      <literal>ADD</literal> can only be used for option names that don't already exist.
+      It sets the specified name's value as provided.
+     </para>
+
+     <para>
+      <literal>SET</literal> can only be used for option names that already exist.
+      It overwrites the entire existing value for the specified option.
+     </para>
+
+     <para>
+      <literal>DROP</literal> can only be used for option names that already exist.
+      It removes the specified name from the list of OPTIONS.
+     </para>
+
+     <para>
+      <literal>APPEND</literal> can be used regardless of whether the option name exists or not.
+      If the option name doesn't exist, it acts like <literal>ADD</literal>.
+      If it does exist, it adds the provided values to the existing ones.
+     </para>
+
+     <para>
+      <literal>REMOVE</literal> can only be used for option names that already exist.
+      It removes the provided values from the values of the specified option name.
+      If some provided values don't exist in the option values, they won't have any effect.
+      Only the values that exist in the options will be removed.
      </para>
     </listitem>
    </varlistentry>
@@ -114,6 +142,23 @@ ALTER SERVER foo OPTIONS (host 'foo', dbname 'foodb');
 </programlisting>
   </para>
 
+  <para>
+   Suppose a server already contains few extensions then to add 
+   more extensions into existing values use
+   Alter server <literal>foo</literal>, append extensions:
+<programlisting>
+ALTER SERVER foo OPTIONS (APPEND extensions 'ext1, ext2, ext3');
+</programlisting>
+  </para>
+
+  <para>
+   To remove some selected values from extensions use
+   Alter server <literal>foo</literal>, remove extensions:
+<programlisting>
+ALTER SERVER foo OPTIONS (REMOVE extensions 'ext1, ext3');
+</programlisting>
+  </para>
+
   <para>
    Alter server <literal>foo</literal>, change version,
    change <literal>host</literal> option:
diff --git a/doc/src/sgml/ref/alter_user_mapping.sgml b/doc/src/sgml/ref/alter_user_mapping.sgml
index ee5aee9bc9..ff420f9c72 100644
--- a/doc/src/sgml/ref/alter_user_mapping.sgml
+++ b/doc/src/sgml/ref/alter_user_mapping.sgml
@@ -23,7 +23,7 @@ PostgreSQL documentation
 <synopsis>
 ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC }
     SERVER <replaceable class="parameter">server_name</replaceable>
-    OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )
+    OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )
 </synopsis>
  </refsynopsisdiv>
 
@@ -69,16 +69,44 @@ ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable>
    </varlistentry>
 
    <varlistentry>
-    <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+    <term><literal>OPTIONS ( [ ADD | SET | DROP | APPEND | REMOVE ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
     <listitem>
      <para>
       Change options for the user mapping. The new options override
       any previously specified
-      options.  <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
-      specify the action to be performed.  <literal>ADD</literal> is assumed
-      if no operation is explicitly specified.  Option names must be
-      unique; options are also validated by the server's foreign-data
-      wrapper.
+      options.  <literal>ADD</literal>, <literal>SET</literal>, <literal>DROP</literal>,
+      <literal>APPEND</literal> and <literal>REMOVE</literal> specify the action to be
+      performed.  <literal>ADD</literal> is assumed if no operation is explicitly
+      specified.  Option names must be unique; options are also validated
+      by the server's foreign-data wrapper.
+     </para>
+
+     <para>
+      <literal>ADD</literal> can only be used for option names that don't already exist.
+      It sets the specified name's value as provided.
+     </para>
+
+     <para>
+      <literal>SET</literal> can only be used for option names that already exist.
+      It overwrites the entire existing value for the specified option.
+     </para>
+
+     <para>
+      <literal>DROP</literal> can only be used for option names that already exist.
+      It removes the specified name from the list of OPTIONS.
+     </para>
+
+     <para>
+      <literal>APPEND</literal> can be used regardless of whether the option name exists or not.
+      If the option name doesn't exist, it acts like <literal>ADD</literal>.
+      If it does exist, it adds the provided values to the existing ones.
+     </para>
+
+     <para>
+      <literal>REMOVE</literal> can only be used for option names that already exist.
+      It removes the provided values from the values of the specified option name.
+      If some provided values don't exist in the option values, they won't have any effect.
+      Only the values that exist in the options will be removed.
      </para>
     </listitem>
    </varlistentry>
-- 
2.41.0

