Repository: pgjdbc/pgjdbc
Pull request #1356 (2018-11-27 11:18:13)

Support custom 'options' connection property
Add support for custom `options` connection property. The property is [described in PostgreSQL documentation](https://www.postgresql.org/docs/8.2/libpq-envars.html); the motivation for its introduction was discussed in https://github.com/pgjdbc/pgjdbc/issues/222 (which is closed by this PR).

Implementation is straightforward: a new `PGProperty` is introduced to store `options` parameter value. It works the same way as any other `PGProperty`, thus it can be passed either in URL or in `Properties` object.

The documentation is updated to mention new connection property. Also, a note is added that when some property is present both in URL and in `Properties` object, the first one is prioritized.

`TestUtil` is updated so that it reads `options` property provided by testing environment.

A new `OptionsPropertyTest` is added.

### All Submissions:
* [x] Have you followed the guidelines in our [Contributing](CONTRIBUTING.md) document?
* [x] Have you checked to ensure there aren't other open [Pull Requests](../../pulls) for the same update/change?

### New Feature Submissions:
1. [x] Does your submission pass tests?
2. [x] Does mvn checkstyle:check pass?

### Changes to Existing Features:
* [x] Does this preserve the existing behaviour? If not, please explain.
* [x] Have you added an explanation of what your changes do and why you'd like us to include them?
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?

codecov-io: # [Codecov](https://codecov.io/gh/pgjdbc/pgjdbc/pull/1356?src=pr&el=h1) Report
> Merging [#1356](https://codecov.io/gh/pgjdbc/pgjdbc/pull/1356?src=pr&el=desc) into [master](https://codecov.io/gh/pgjdbc/pgjdbc/commit/381cf45cd1029d53ef748731d93361a814f711b6?src=pr&el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `71.42%`.



```diff
@@             Coverage Diff              @@
##             master    #1356      +/-   ##
============================================
+ Coverage     68.65%   68.67%   +0.01%     
- Complexity     3889     3892       +3     
============================================
  Files           179      179              
  Lines         16391    16398       +7     
  Branches       2669     2670       +1     
============================================
+ Hits          11253    11261       +8     
  Misses         3888     3888              
+ Partials       1250     1249       -1
```


Patch:
diff --git a/README.md b/README.md
index b6b303aa..a854963e 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,7 @@ where:
  * **host** (Optional) is the server address to connect. This could be a DNS or IP address, or it could be *localhost* or *127.0.0.1* for the local computer. To specify an IPv6 address your must enclose the host parameter with square brackets (jdbc:postgresql://[::1]:5740/accounting). Defaults to `localhost`.
  * **port** (Optional) is the port number listening on the host. Defaults to `5432`.
  * **database** (Optional) is the database name. Defaults to the same name as the *user name* used in the connection.
- * **propertyX** (Optional) is one or more option connection properties. For more information see *Connection properties*. 
+ * **propertyX** (Optional) is one or more option connection properties. For more information see *Connection properties*.
 
 #### Connection Properties
 In addition to the standard connection parameters the driver supports a number of additional properties which can be used to specify additional driver behaviour specific to PostgreSQL™. These properties may be specified in either the connection URL or an additional Properties object parameter to DriverManager.getConnection.
@@ -109,6 +109,7 @@ In addition to the standard connection parameters the driver supports a number o
 | ----------------------------- | ------- | :-----: | ------------- |
 | user                          | String  | null    | The database user on whose behalf the connection is being made. |
 | password                      | String  | null    | The database user's password. |
+| options                       | String  | null    | Specify 'options' connection initialization parameter. |
 | ssl                           | Boolean | false   | Control use of SSL (true value causes SSL to be required) |
 | sslfactory                    | String  | null    | Provide a SSLSocketFactory class when using SSL. |
 | sslfactoryarg (deprecated)    | String  | null    | Argument forwarded to constructor of SSLSocketFactory class. |
@@ -149,7 +150,7 @@ In addition to the standard connection parameters the driver supports a number o
 | preferQueryMode               | String  | extended | Specifies which mode is used to execute queries to database, possible values: extended, extendedForPrepared, extendedCacheEverything, simple |
 | reWriteBatchedInserts         | Boolean | false  | Enable optimization to rewrite and collapse compatible INSERT statements that are batched. |
 
-## Contributing 
+## Contributing
 For information on how to contribute to the project see the [Contributing Guidelines](CONTRIBUTING.md)
 
 ----------------------------------------------------
diff --git a/build.properties b/build.properties
index 548d2aaf..a62afc7f 100644
--- a/build.properties
+++ b/build.properties
@@ -5,10 +5,10 @@
 
 server=localhost
 port=5432
-secondaryServer=localhost
-secondaryPort=5433
+secondaryServer1=localhost
+secondaryPort1=5433
 secondaryServer2=localhost
-secondaryServerPort2=5434
+secondaryPort2=5434
 database=test
 username=test
 password=test
diff --git a/docs/_posts/2017-02-20-42.0.0-release.md b/docs/_posts/2017-02-20-42.0.0-release.md
index bf2ef38a..c75d7642 100644
--- a/docs/_posts/2017-02-20-42.0.0-release.md
+++ b/docs/_posts/2017-02-20-42.0.0-release.md
@@ -13,7 +13,7 @@ version: 42.0.0
 - Add support for PreparedStatement.setCharacterStream(int, Reader). [ee4c4265](https://github.com/pgjdbc/pgjdbc/commit/ee4c4265aebc1c73a1d1fabac5ba259d1fbfd1e4)
 
 ### Changed
-- Version bumped to 42.0.0 to avoid version clash with PostgreSQL version and follow a better sematic versioning. [46634923](https://github.com/pgjdbc/pgjdbc/commit/466349236622c6b03bb9cd8d7f517c3ce0586751)
+- Version bumped to 42.0.0 to avoid version clash with PostgreSQL version and follow a better semantic versioning. [46634923](https://github.com/pgjdbc/pgjdbc/commit/466349236622c6b03bb9cd8d7f517c3ce0586751)
 - Ensure executeBatch() can be used with pgbouncer. Previously pgjdbc could use server-prepared statements for batch execution even with prepareThreshold=0. [Issue 742](https://github.com/pgjdbc/pgjdbc/issues/742)
 - Error position is displayed when SQL has unterminated literals, comments, etc. [Issue 688](https://github.com/pgjdbc/pgjdbc/issues/688)
 - Strict handling of accepted values in getBoolean and setObject(BOOLEAN), now it follows PostgreSQL accepted values, only 1 and 0 for numeric types are acepted (previusly !=0 was true). [PR 732](https://github.com/pgjdbc/pgjdbc/pull/732)
diff --git a/docs/_posts/2018-01-17-42.2.0-release.md b/docs/_posts/2018-01-17-42.2.0-release.md
index 5a376b3a..d4b60ff6 100644
--- a/docs/_posts/2018-01-17-42.2.0-release.md
+++ b/docs/_posts/2018-01-17-42.2.0-release.md
@@ -22,7 +22,7 @@ version: 42.2.0
 
 ### Changed
 - Improve behaviour of ResultSet.getObject(int, Class). [PR 932](https://github.com/pgjdbc/pgjdbc/pull/932)
-- Parse CommandComplete message using a regular expresion, allows complete catch of server returned commands for INSERT, UPDATE, DELETE, SELECT, FETCH, MOVE, COPY and future commands. [PR 962](https://github.com/pgjdbc/pgjdbc/pull/962)
+- Parse CommandComplete message using a regular expression, allows complete catch of server returned commands for INSERT, UPDATE, DELETE, SELECT, FETCH, MOVE, COPY and future commands. [PR 962](https://github.com/pgjdbc/pgjdbc/pull/962)
 - Use 'time with timezone' and 'timestamp with timezone' as is and ignore the user provided Calendars, 'time' and 'timestamp' work as earlier except "00:00:00" now maps to 1970-01-01 and "24:00:00" uses the system provided Calendar ignoring the user-provided one [PR 1053](https://github.com/pgjdbc/pgjdbc/pull/1053)
 - Change behaviour of multihost connection. The new behaviour is to try all secondaries first before trying the master [PR 844](https://github.com/pgjdbc/pgjdbc/pull/844).
 - Avoid reflective access to TimeZone.defaultTimeZone in Java 9+ [PR 1002](https://github.com/pgjdbc/pgjdbc/pull/1002) fixes [Issue 986](https://github.com/pgjdbc/pgjdbc/issues/986)
diff --git a/docs/documentation/92/escaped-functions.md b/docs/documentation/92/escaped-functions.md
index 38b9adf8..e028f5f9 100644
--- a/docs/documentation/92/escaped-functions.md
+++ b/docs/documentation/92/escaped-functions.md
@@ -10,7 +10,7 @@ next: ext.html
 ---
 
 The JDBC specification defines functions with an escape call syntax : `{fn function_name(arguments)}`.
-The following tables show which functions are supported by the PostgresSQL™ driver. 
+The following tables show which functions are supported by the PostgreSQL™ driver.
 The driver supports the nesting and the mixing of escaped functions and escaped
 values. The appendix C of the JDBC specification describes the functions.
 
diff --git a/docs/documentation/92/geometric.md b/docs/documentation/92/geometric.md
index 284985c2..a13a9ef1 100644
--- a/docs/documentation/92/geometric.md
+++ b/docs/documentation/92/geometric.md
@@ -12,7 +12,7 @@ next: largeobjects.html
 PostgreSQL™ has a set of data types that can store geometric features into a
 table. These include single points, lines, and polygons.  We support these types
 in Java with the org.postgresql.geometric package. Please consult the Javadoc
-for the details of available classes and features metioned in [Chapter 12, *Further Reading*](reading.html).
+for the details of available classes and features mentioned in [Chapter 12, *Further Reading*](reading.html).
 
 <a name="geometric-circle-example"></a>
 **Example 9.1. Using the CIRCLE datatype JDBC**
diff --git a/docs/documentation/92/ssl.md b/docs/documentation/92/ssl.md
index af932386..57fbb7c9 100644
--- a/docs/documentation/92/ssl.md
+++ b/docs/documentation/92/ssl.md
@@ -23,7 +23,7 @@ Configuring the PostgreSQL™ server for SSL is covered in the [main
 documentation](http://www.postgresql.org/docs/current/static/ssl-tcp.html),
 so it will not be repeated here. Before trying to access your SSL enabled
 server from Java, make sure you can get to it via **psql**. You should
-see output like the following if you have established a SSL  connnection. 
+see output like the following if you have established a SSL  connection. 
 
 `$ ./bin/psql -h localhost`  
 `Welcome to psql 8.0.0rc5, the PostgreSQL interactive terminal.`
diff --git a/docs/documentation/92/use.md b/docs/documentation/92/use.md
index 97f27f91..4e5cb4cf 100644
--- a/docs/documentation/92/use.md
+++ b/docs/documentation/92/use.md
@@ -14,7 +14,7 @@ next: load.html
 
 * [Importing JDBC](use.html#import)
 * [Loading the Driver](load.html)
-* [Connecting to the Databas](connect.html)
+* [Connecting to the Database](connect.html)
    * [Connection Parameters](connect.html#connection-parameters)
 
 This section describes how to load and initialize the JDBC driver in your programs.
diff --git a/docs/documentation/93/escaped-functions.md b/docs/documentation/93/escaped-functions.md
index 38b9adf8..e028f5f9 100644
--- a/docs/documentation/93/escaped-functions.md
+++ b/docs/documentation/93/escaped-functions.md
@@ -10,7 +10,7 @@ next: ext.html
 ---
 
 The JDBC specification defines functions with an escape call syntax : `{fn function_name(arguments)}`.
-The following tables show which functions are supported by the PostgresSQL™ driver. 
+The following tables show which functions are supported by the PostgreSQL™ driver.
 The driver supports the nesting and the mixing of escaped functions and escaped
 values. The appendix C of the JDBC specification describes the functions.
 
diff --git a/docs/documentation/93/geometric.md b/docs/documentation/93/geometric.md
index 284985c2..a13a9ef1 100644
--- a/docs/documentation/93/geometric.md
+++ b/docs/documentation/93/geometric.md
@@ -12,7 +12,7 @@ next: largeobjects.html
 PostgreSQL™ has a set of data types that can store geometric features into a
 table. These include single points, lines, and polygons.  We support these types
 in Java with the org.postgresql.geometric package. Please consult the Javadoc
-for the details of available classes and features metioned in [Chapter 12, *Further Reading*](reading.html).
+for the details of available classes and features mentioned in [Chapter 12, *Further Reading*](reading.html).
 
 <a name="geometric-circle-example"></a>
 **Example 9.1. Using the CIRCLE datatype JDBC**
diff --git a/docs/documentation/93/ssl.md b/docs/documentation/93/ssl.md
index af932386..57fbb7c9 100644
--- a/docs/documentation/93/ssl.md
+++ b/docs/documentation/93/ssl.md
@@ -23,7 +23,7 @@ Configuring the PostgreSQL™ server for SSL is covered in the [main
 documentation](http://www.postgresql.org/docs/current/static/ssl-tcp.html),
 so it will not be repeated here. Before trying to access your SSL enabled
 server from Java, make sure you can get to it via **psql**. You should
-see output like the following if you have established a SSL  connnection. 
+see output like the following if you have established a SSL  connection. 
 
 `$ ./bin/psql -h localhost`  
 `Welcome to psql 8.0.0rc5, the PostgreSQL interactive terminal.`
diff --git a/docs/documentation/93/use.md b/docs/documentation/93/use.md
index 97f27f91..4e5cb4cf 100644
--- a/docs/documentation/93/use.md
+++ b/docs/documentation/93/use.md
@@ -14,7 +14,7 @@ next: load.html
 
 * [Importing JDBC](use.html#import)
 * [Loading the Driver](load.html)
-* [Connecting to the Databas](connect.html)
+* [Connecting to the Database](connect.html)
    * [Connection Parameters](connect.html#connection-parameters)
 
 This section describes how to load and initialize the JDBC driver in your programs.
diff --git a/docs/documentation/94/escaped-functions.md b/docs/documentation/94/escaped-functions.md
index 38b9adf8..e028f5f9 100644
--- a/docs/documentation/94/escaped-functions.md
+++ b/docs/documentation/94/escaped-functions.md
@@ -10,7 +10,7 @@ next: ext.html
 ---
 
 The JDBC specification defines functions with an escape call syntax : `{fn function_name(arguments)}`.
-The following tables show which functions are supported by the PostgresSQL™ driver. 
+The following tables show which functions are supported by the PostgreSQL™ driver.
 The driver supports the nesting and the mixing of escaped functions and escaped
 values. The appendix C of the JDBC specification describes the functions.
 
diff --git a/docs/documentation/94/geometric.md b/docs/documentation/94/geometric.md
index 284985c2..a13a9ef1 100644
--- a/docs/documentation/94/geometric.md
+++ b/docs/documentation/94/geometric.md
@@ -12,7 +12,7 @@ next: largeobjects.html
 PostgreSQL™ has a set of data types that can store geometric features into a
 table. These include single points, lines, and polygons.  We support these types
 in Java with the org.postgresql.geometric package. Please consult the Javadoc
-for the details of available classes and features metioned in [Chapter 12, *Further Reading*](reading.html).
+for the details of available classes and features mentioned in [Chapter 12, *Further Reading*](reading.html).
 
 <a name="geometric-circle-example"></a>
 **Example 9.1. Using the CIRCLE datatype JDBC**
diff --git a/docs/documentation/94/ssl.md b/docs/documentation/94/ssl.md
index af932386..57fbb7c9 100644
--- a/docs/documentation/94/ssl.md
+++ b/docs/documentation/94/ssl.md
@@ -23,7 +23,7 @@ Configuring the PostgreSQL™ server for SSL is covered in the [main
 documentation](http://www.postgresql.org/docs/current/static/ssl-tcp.html),
 so it will not be repeated here. Before trying to access your SSL enabled
 server from Java, make sure you can get to it via **psql**. You should
-see output like the following if you have established a SSL  connnection. 
+see output like the following if you have established a SSL  connection. 
 
 `$ ./bin/psql -h localhost`  
 `Welcome to psql 8.0.0rc5, the PostgreSQL interactive terminal.`
diff --git a/docs/documentation/94/use.md b/docs/documentation/94/use.md
index 97f27f91..4e5cb4cf 100644
--- a/docs/documentation/94/use.md
+++ b/docs/documentation/94/use.md
@@ -14,7 +14,7 @@ next: load.html
 
 * [Importing JDBC](use.html#import)
 * [Loading the Driver](load.html)
-* [Connecting to the Databas](connect.html)
+* [Connecting to the Database](connect.html)
    * [Connection Parameters](connect.html#connection-parameters)
 
 This section describes how to load and initialize the JDBC driver in your programs.
diff --git a/docs/documentation/changelog.md b/docs/documentation/changelog.md
index 5a97d1a0..2941f115 100644
--- a/docs/documentation/changelog.md
+++ b/docs/documentation/changelog.md
@@ -1504,7 +1504,7 @@ Date:   Fri Feb 10 00:34:59 2012 -0800
     
     The concrete JDBC implementation classes should do as little work
     as possible.  They exist solely to connect the right set of concrete
-    implemention classes, leaving all the real work to the Abstract
+    implementation classes, leaving all the real work to the Abstract
     versions.  Some logic had started to creep out into these concrete
     classes which is bad because it duplicates code in paths that aren't
     likely to be tested by a developer who is working primarily with a
diff --git a/docs/documentation/head/connect.md b/docs/documentation/head/connect.md
index 106f3ca0..8cbf2b05 100644
--- a/docs/documentation/head/connect.md
+++ b/docs/documentation/head/connect.md
@@ -54,6 +54,9 @@ URL or an additional `Properties` object parameter to `DriverManager.getConnecti
 The following examples illustrate the use of both methods to establish a SSL
 connection.
 
+If a property is specified both in URL and in `Properties` object, the value from
+`Properties` object is ignored.
+
 ```java
 String url = "jdbc:postgresql://localhost/test";
 Properties props = new Properties();
@@ -68,11 +71,20 @@ Connection conn = DriverManager.getConnection(url);
 
 * **user** = String
 
-	The database user on whose behalf the connection is being made. 
+	The database user on whose behalf the connection is being made.
 
 * **password** = String
 
-	The database user's password. 
+	The database user's password.
+
+* **options** = String
+
+	Specify 'options' connection initialization parameter.
+
+	The value of this property may contain spaces or other special characters,
+	and it should be properly encoded if provided in the connection URL. Spaces
+	are considered to separate command-line arguments, unless escaped with
+	a backslash (`\`); `\\` represents a literal backslash.
 
 * **ssl** = boolean
 
@@ -459,4 +471,4 @@ And read pool balances connections between slaves nodes, but allows connections
 
 If a slave fails, all slaves in the list will be tried first. If the case that there are no available slaves
 the master will be tried. If all of the servers are marked as "can't connect" in the cache then an attempt
-will be made to connect to all of the hosts in the URL in order.
\ No newline at end of file
+will be made to connect to all of the hosts in the URL in order.
diff --git a/docs/documentation/head/server-prepare.md b/docs/documentation/head/server-prepare.md
index 5c94942c..76f1504e 100644
--- a/docs/documentation/head/server-prepare.md
+++ b/docs/documentation/head/server-prepare.md
@@ -129,7 +129,7 @@ Server side prepared statements are linked to database object IDs, so it could f
 
 The recommendation is:
 1. Avoid changing `search_path` often, as it invalidates server side prepared statements
-1. Use simple `set search_path...` commands, avoid nesting the comands into pl/pgsql or alike, otherwise
+1. Use simple `set search_path...` commands, avoid nesting the commands into pl/pgsql or alike, otherwise
 pgjdbc won't be able to identify `search_path` change
 
 #### Re-execution of failed statements
@@ -154,7 +154,7 @@ uses simple queries in the case where `replication` connection property is activ
 
 #### Use of server-prepared statements for con.createStatement()
 
-By default, pgjdbc uses server-prepard statements for `PreparedStatement` only, however you might want
+By default, pgjdbc uses server-prepared statements for `PreparedStatement` only, however you might want
 to activate server side prepared statements for regular `Statement` as well. For instance, if you
 execute the same statement through `con.createStatement().executeQuery(...)`, then you might improve
 performance by caching the statement. Of course it is better to use `PreparedStatements` explicitly,
diff --git a/docs/documentation/head/ssl.md b/docs/documentation/head/ssl.md
index 041306d4..a32027b6 100644
--- a/docs/documentation/head/ssl.md
+++ b/docs/documentation/head/ssl.md
@@ -23,7 +23,7 @@ Configuring the PostgreSQL™ server for SSL is covered in the [main
 documentation](http://www.postgresql.org/docs/current/static/ssl-tcp.html),
 so it will not be repeated here. Before trying to access your SSL enabled
 server from Java, make sure you can get to it via **psql**. You should
-see output like the following if you have established a SSL  connnection. 
+see output like the following if you have established a SSL  connection. 
 
 ```
 $ ./bin/psql -h localhost -U postgres
diff --git a/docs/documentation/head/use.md b/docs/documentation/head/use.md
index 3d333765..25537cd8 100644
--- a/docs/documentation/head/use.md
+++ b/docs/documentation/head/use.md
@@ -14,7 +14,7 @@ next: load.html
 
 * [Importing JDBC](use.html#import)
 * [Loading the Driver](load.html)
-* [Connecting to the Databas](connect.html)
+* [Connecting to the Database](connect.html)
    * [Connection Parameters](connect.html#connection-parameters)
 
 This section describes how to load and initialize the JDBC driver in your programs.
diff --git a/pgjdbc/src/main/java/org/postgresql/PGProperty.java b/pgjdbc/src/main/java/org/postgresql/PGProperty.java
index 4afefe23..7aace06e 100644
--- a/pgjdbc/src/main/java/org/postgresql/PGProperty.java
+++ b/pgjdbc/src/main/java/org/postgresql/PGProperty.java
@@ -55,6 +55,12 @@ public enum PGProperty {
       "Force use of a particular protocol version when connecting, currently only version 3 is supported.",
       false, "3"),
 
+  /**
+   * Specify 'options' connection initialization parameter.
+   * The value of this parameter may contain spaces and other special characters or their URL representation.
+   */
+  OPTIONS("options", null, "Specify 'options' connection initialization parameter."),
+
   /**
    * <p>Logger level of the driver. Allowed values: {@code OFF}, {@code DEBUG} or {@code TRACE}.</p>
    *
diff --git a/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java b/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java
index c83ce34c..91b4ae59 100644
--- a/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java
+++ b/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java
@@ -339,6 +339,12 @@ public class ConnectionFactoryImpl extends ConnectionFactory {
     if (currentSchema != null) {
       paramList.add(new String[]{"search_path", currentSchema});
     }
+
+    String options = PGProperty.OPTIONS.get(info);
+    if (options != null) {
+      paramList.add(new String[]{"options", options});
+    }
+
     return paramList;
   }
 
diff --git a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
index 7f78f404..8d9c484f 100644
--- a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
+++ b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
@@ -232,6 +232,21 @@ public abstract class BaseDataSource implements CommonDataSource, Referenceable
     this.portNumber = portNumber;
   }
 
+  /**
+   * @return command line options for this connection
+   */
+  public String getOptions() {
+    return PGProperty.OPTIONS.get(properties);
+  }
+
+  /**
+   * Set command line options for this connection
+   * @param options string to set options to
+   */
+  public void setOptions(String options) {
+    PGProperty.OPTIONS.set(properties, options);
+  }
+
   /**
    * @return login timeout
    * @see PGProperty#LOGIN_TIMEOUT


Test patch:
diff --git a/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java b/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java
index b300749c..a1f12733 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/TestUtil.java
@@ -69,6 +69,11 @@ public class TestUtil {
       protocolVersion = "&protocolVersion=" + getProtocolVersion();
     }
 
+    String options = "";
+    if (getOptions() != null) {
+      options = "&options=" + getOptions();
+    }
+
     String binaryTransfer = "";
     if (getBinaryTransfer() != null && !getBinaryTransfer().equals("")) {
       binaryTransfer = "&binaryTransfer=" + getBinaryTransfer();
@@ -96,6 +101,7 @@ public class TestUtil {
         + logLevel
         + logFile
         + protocolVersion
+        + options
         + binaryTransfer
         + receiveBufferSize
         + sendBufferSize
@@ -127,6 +133,10 @@ public class TestUtil {
     return Integer.parseInt(System.getProperty("protocolVersion", "0"));
   }
 
+  public static String getOptions() {
+    return System.getProperty("options");
+  }
+
   /*
    * Returns the Test database
    */
@@ -242,7 +252,7 @@ public class TestUtil {
     return p;
   }
 
-  public static void initDriver() throws Exception {
+  public static void initDriver() {
     synchronized (TestUtil.class) {
       if (initialized) {
         return;
@@ -281,7 +291,7 @@ public class TestUtil {
    * @return connection using a privileged user mostly for tests that the ability to load C
    *         functions now as of 4/14
    */
-  public static Connection openPrivilegedDB() throws Exception {
+  public static Connection openPrivilegedDB() throws SQLException {
     initDriver();
     Properties properties = new Properties();
     properties.setProperty("user", getPrivilegedUser());
@@ -295,7 +305,7 @@ public class TestUtil {
    *
    * @return connection
    */
-  public static Connection openDB() throws Exception {
+  public static Connection openDB() throws SQLException {
     return openDB(new Properties());
   }
 
@@ -303,7 +313,7 @@ public class TestUtil {
    * Helper - opens a connection with the allowance for passing additional parameters, like
    * "compatible".
    */
-  public static Connection openDB(Properties props) throws Exception {
+  public static Connection openDB(Properties props) throws SQLException {
     initDriver();
 
     // Allow properties to override the user name.
@@ -375,17 +385,15 @@ public class TestUtil {
   public static void dropSchema(Connection con, String schema) throws SQLException {
     Statement stmt = con.createStatement();
     try {
-      String sql = "DROP SCHEMA " + schema + " CASCADE ";
-
-      stmt.executeUpdate(sql);
-    } catch (SQLException ex) {
-      // Since every create schema issues a drop schema
-      // it's easy to get a schema doesn't exist error.
-      // we want to ignore these, but if we're in a
-      // transaction then we've got trouble
-      if (!con.getAutoCommit()) {
-        throw ex;
+      if (con.getAutoCommit()) {
+        // Not in a transaction so ignore error for missing object
+        stmt.executeUpdate("DROP SCHEMA IF EXISTS " + schema + " CASCADE");
+      } else {
+        // In a transaction so do not ignore errors for missing object
+        stmt.executeUpdate("DROP SCHEMA " + schema + " CASCADE");
       }
+    } finally {
+      closeQuietly(stmt);
     }
   }
 
@@ -459,16 +467,26 @@ public class TestUtil {
    * @param name String
    * @param values String
    */
+  public static void createCompositeType(Connection con, String name, String values) throws SQLException {
+    createCompositeType(con, name, values, true);
+  }
 
-  public static void createCompositeType(Connection con, String name, String values)
+  /**
+   * Helper creates an composite type.
+   *
+   * @param con Connection
+   * @param name String
+   * @param values String
+   */
+  public static void createCompositeType(Connection con, String name, String values, boolean shouldDrop)
       throws SQLException {
     Statement st = con.createStatement();
     try {
-      dropType(con, name);
-
-
-      // Now create the table
-      st.executeUpdate("create type " + name + " as (" + values + ")");
+      if (shouldDrop) {
+        dropType(con, name);
+      }
+      // Now create the type
+      st.executeUpdate("CREATE TYPE " + name + " AS (" + values + ")");
     } finally {
       closeQuietly(st);
     }
@@ -482,15 +500,17 @@ public class TestUtil {
    */
   public static void dropDomain(Connection con, String name)
       throws SQLException {
-    Statement st = con.createStatement();
+    Statement stmt = con.createStatement();
     try {
-      st.executeUpdate("drop domain " + name + " cascade");
-    } catch (SQLException ex) {
-      if (!con.getAutoCommit()) {
-        throw ex;
+      if (con.getAutoCommit()) {
+        // Not in a transaction so ignore error for missing object
+        stmt.executeUpdate("DROP DOMAIN IF EXISTS " + name + " CASCADE");
+      } else {
+        // In a transaction so do not ignore errors for missing object
+        stmt.executeUpdate("DROP DOMAIN " + name + " CASCADE");
       }
     } finally {
-      closeQuietly(st);
+      closeQuietly(stmt);
     }
   }
 
@@ -519,12 +539,15 @@ public class TestUtil {
   public static void dropSequence(Connection con, String sequence) throws SQLException {
     Statement stmt = con.createStatement();
     try {
-      String sql = "DROP SEQUENCE " + sequence;
-      stmt.executeUpdate(sql);
-    } catch (SQLException sqle) {
-      if (!con.getAutoCommit()) {
-        throw sqle;
+      if (con.getAutoCommit()) {
+        // Not in a transaction so ignore error for missing object
+        stmt.executeUpdate("DROP SEQUENCE IF EXISTS " + sequence + " CASCADE");
+      } else {
+        // In a transaction so do not ignore errors for missing object
+        stmt.executeUpdate("DROP SEQUENCE " + sequence + " CASCADE");
       }
+    } finally {
+      closeQuietly(stmt);
     }
   }
 
@@ -534,16 +557,15 @@ public class TestUtil {
   public static void dropTable(Connection con, String table) throws SQLException {
     Statement stmt = con.createStatement();
     try {
-      String sql = "DROP TABLE " + table + " CASCADE ";
-      stmt.executeUpdate(sql);
-    } catch (SQLException ex) {
-      // Since every create table issues a drop table
-      // it's easy to get a table doesn't exist error.
-      // we want to ignore these, but if we're in a
-      // transaction then we've got trouble
-      if (!con.getAutoCommit()) {
-        throw ex;
+      if (con.getAutoCommit()) {
+        // Not in a transaction so ignore error for missing object
+        stmt.executeUpdate("DROP TABLE IF EXISTS " + table + " CASCADE ");
+      } else {
+        // In a transaction so do not ignore errors for missing object
+        stmt.executeUpdate("DROP TABLE " + table + " CASCADE ");
       }
+    } finally {
+      closeQuietly(stmt);
     }
   }
 
@@ -553,12 +575,15 @@ public class TestUtil {
   public static void dropType(Connection con, String type) throws SQLException {
     Statement stmt = con.createStatement();
     try {
-      String sql = "DROP TYPE " + type + " CASCADE";
-      stmt.executeUpdate(sql);
-    } catch (SQLException ex) {
-      if (!con.getAutoCommit()) {
-        throw ex;
+      if (con.getAutoCommit()) {
+        // Not in a transaction so ignore error for missing object
+        stmt.executeUpdate("DROP TYPE IF EXISTS " + type + " CASCADE");
+      } else {
+        // In a transaction so do not ignore errors for missing object
+        stmt.executeUpdate("DROP TYPE " + type + " CASCADE");
       }
+    } finally {
+      closeQuietly(stmt);
     }
   }
 
diff --git a/pgjdbc/src/test/java/org/postgresql/test/core/OptionsPropertyTest.java b/pgjdbc/src/test/java/org/postgresql/test/core/OptionsPropertyTest.java
new file mode 100644
index 00000000..20a78302
--- /dev/null
+++ b/pgjdbc/src/test/java/org/postgresql/test/core/OptionsPropertyTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2004, PostgreSQL Global Development Group
+ * See the LICENSE file in the project root for more information.
+ */
+
+package org.postgresql.test.core;
+
+import org.postgresql.PGProperty;
+import org.postgresql.test.TestUtil;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Properties;
+
+public class OptionsPropertyTest {
+  private static final String schemaName = "options_property_test";
+  private static final String optionsValue = "-c search_path=" + schemaName;
+
+  @Before
+  public void setUp() throws Exception {
+    Connection con = TestUtil.openDB();
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP SCHEMA IF EXISTS " + schemaName + ";");
+    stmt.execute("CREATE SCHEMA " + schemaName + ";");
+    stmt.close();
+    TestUtil.closeDB(con);
+  }
+
+  @Test
+  public void testOptionsInProperties() throws Exception {
+    Properties props = new Properties();
+    props.setProperty(PGProperty.OPTIONS.getName(), optionsValue);
+
+    Connection con = TestUtil.openDB(props);
+    Statement stmt = con.createStatement();
+    stmt.execute("SHOW search_path");
+
+    ResultSet rs = stmt.getResultSet();
+    if (!rs.next()) {
+      Assert.fail("'options' connection initialization parameter should be passed to the database.");
+    }
+    Assert.assertEquals("'options' connection initialization parameter should be passed to the database.", schemaName, rs.getString(1));
+
+    stmt.close();
+    TestUtil.closeDB(con);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    Connection con = TestUtil.openDB();
+    Statement stmt = con.createStatement();
+    stmt.execute("DROP SCHEMA " + schemaName + ";");
+    stmt.close();
+    TestUtil.closeDB(con);
+  }
+}
diff --git a/pgjdbc/src/test/java/org/postgresql/test/hostchooser/MultiHostsConnectionTest.java b/pgjdbc/src/test/java/org/postgresql/test/hostchooser/MultiHostsConnectionTest.java
index 0b945ca6..8c202946 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/hostchooser/MultiHostsConnectionTest.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/hostchooser/MultiHostsConnectionTest.java
@@ -46,7 +46,7 @@ public class MultiHostsConnectionTest {
   private static final String user = TestUtil.getUser();
   private static final String password = TestUtil.getPassword();
   private static final String master1 = TestUtil.getServer() + ":" + TestUtil.getPort();
-  private static final String secondary1 = getSecondaryServer() + ":" + getSecondaryPort();
+  private static final String secondary1 = getSecondaryServer1() + ":" + getSecondaryPort1();
   private static final String secondary2 = getSecondaryServer2() + ":" + getSecondaryPort2();
   private static final String fake1 = "127.127.217.217:1";
 
@@ -95,7 +95,7 @@ public class MultiHostsConnectionTest {
 
     Properties props = userAndPassword();
 
-    return DriverManager.getConnection(TestUtil.getURL(getSecondaryServer(), getSecondaryPort()), props);
+    return DriverManager.getConnection(TestUtil.getURL(getSecondaryServer1(), getSecondaryPort1()), props);
   }
 
   private static Properties userAndPassword() {
@@ -106,12 +106,12 @@ public class MultiHostsConnectionTest {
     return props;
   }
 
-  private static String getSecondaryServer() {
-    return System.getProperty("secondaryServer", TestUtil.getServer());
+  private static String getSecondaryServer1() {
+    return System.getProperty("secondaryServer1", TestUtil.getServer());
   }
 
-  private static int getSecondaryPort() {
-    return Integer.parseInt(System.getProperty("secondaryPort", String.valueOf(TestUtil.getPort() + 1)));
+  private static int getSecondaryPort1() {
+    return Integer.parseInt(System.getProperty("secondaryPort1", String.valueOf(TestUtil.getPort() + 1)));
   }
 
   private static Connection openSecondaryDB2() throws Exception {
diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
index 2538aabb..73d39e24 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
@@ -52,8 +52,10 @@ public class DatabaseMetaDataTest {
     TestUtil.createTable(con, "\"a'\"", "a int4");
     TestUtil.createTable(con, "arraytable", "a numeric(5,2)[], b varchar(100)[]");
     TestUtil.createTable(con, "intarraytable", "a int4[], b int4[][]");
-    TestUtil.createCompositeType(con, "custom", "i int");
-    TestUtil.createCompositeType(con, "_custom", "f float");
+    TestUtil.dropType(con, "custom");
+    TestUtil.dropType(con, "_custom");
+    TestUtil.createCompositeType(con, "custom", "i int", false);
+    TestUtil.createCompositeType(con, "_custom", "f float", false);
 
 
     // 8.2 does not support arrays of composite types
@@ -107,7 +109,7 @@ public class DatabaseMetaDataTest {
     stmt.execute("DROP FUNCTION f1(int, varchar)");
     stmt.execute("DROP FUNCTION f2(int, varchar)");
     stmt.execute("DROP FUNCTION f3(int, varchar)");
-    TestUtil.dropType(con, "domaintable");
+    TestUtil.dropTable(con, "domaintable");
     TestUtil.dropDomain(con, "nndom");
 
     TestUtil.closeDB(con);
diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
index 18a406b5..b22762e5 100644
--- a/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
+++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
@@ -16,6 +16,7 @@ import org.postgresql.jdbc.DeepBatchedInsertStatementTest;
 import org.postgresql.jdbc.PrimitiveArraySupportTest;
 import org.postgresql.test.core.JavaVersionTest;
 import org.postgresql.test.core.NativeQueryBindLengthTest;
+import org.postgresql.test.core.OptionsPropertyTest;
 import org.postgresql.test.util.ExpressionPropertiesTest;
 import org.postgresql.test.util.LruCacheTest;
 import org.postgresql.test.util.ServerVersionParseTest;
@@ -61,6 +62,7 @@ import org.junit.runners.Suite;
         ReaderInputStreamTest.class,
         ServerVersionParseTest.class,
         ServerVersionTest.class,
+        OptionsPropertyTest.class,
 
         TypeCacheDLLStressTest.class,