*** a/doc/src/sgml/ref/pg_basebackup.sgml
--- b/doc/src/sgml/ref/pg_basebackup.sgml
***************
*** 357,362 **** PostgreSQL documentation
--- 357,375 ----
     <para>
      The following command-line options control the database connection parameters.
  
+ 	<variablelist>
+      <varlistentry>
+       <term><option>-C <replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <term><option>--connection-string=<replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <listitem>
+        <para>
+         Specifies connection string options, used for connecting to server.
+         These options can be used along with other user supplied options.
+         In case of conflicting option, user supplied option is choosen.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
      <variablelist>
       <varlistentry>
        <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
*** a/doc/src/sgml/ref/pg_dump.sgml
--- b/doc/src/sgml/ref/pg_dump.sgml
***************
*** 815,820 **** PostgreSQL documentation
--- 815,833 ----
  
     <para>
      The following command-line options control the database connection parameters.
+     
+     <variablelist>
+      <varlistentry>
+       <term><option>-K <replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <term><option>--connection-string=<replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <listitem>
+        <para>
+         Specifies connection string options, used for connecting to server.
+         These options can be used along with other user supplied options.
+         In case of conflicting option, user supplied option is choosen.
+        </para>
+       </listitem>
+      </varlistentry>
  
      <variablelist>
       <varlistentry>
*** a/doc/src/sgml/ref/pg_dumpall.sgml
--- b/doc/src/sgml/ref/pg_dumpall.sgml
***************
*** 403,408 **** PostgreSQL documentation
--- 403,421 ----
  
    <para>
     The following command-line options control the database connection parameters.
+    
+    <variablelist>
+      <varlistentry>
+       <term><option>-K <replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <term><option>--connection-string=<replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <listitem>
+        <para>
+         Specifies connection string options, used for connecting to server.
+         These options can be used along with other user supplied options.
+         In case of conflicting option, user supplied option is choosen.
+        </para>
+       </listitem>
+      </varlistentry>
  
     <variablelist>
       <varlistentry>
*** a/doc/src/sgml/ref/pg_receivexlog.sgml
--- b/doc/src/sgml/ref/pg_receivexlog.sgml
***************
*** 121,126 **** PostgreSQL documentation
--- 121,139 ----
     <para>
      The following command-line options control the database connection parameters.
  
+ 	<variablelist>
+      <varlistentry>
+       <term><option>-C <replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <term><option>--connection-string=<replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <listitem>
+        <para>
+         Specifies connection string options, used for connecting to server.
+         These options can be used along with other user supplied options.
+         In case of conflicting option, user supplied option is choosen.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
      <variablelist>
       <varlistentry>
        <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
*** a/src/bin/pg_basebackup/pg_basebackup.c
--- b/src/bin/pg_basebackup/pg_basebackup.c
***************
*** 126,131 **** usage(void)
--- 126,132 ----
  	printf(_("  -V, --version          output version information, then exit\n"));
  	printf(_("  -?, --help             show this help, then exit\n"));
  	printf(_("\nConnection options:\n"));
+ 	printf(_("  -C, --connection-string=\"OPTIONS\" connect to server using OPTIONS\n"));
  	printf(_("  -h, --host=HOSTNAME    database server host or socket directory\n"));
  	printf(_("  -p, --port=PORT        database server port number\n"));
  	printf(_("  -s, --status-interval=INTERVAL\n"
***************
*** 1534,1539 **** main(int argc, char **argv)
--- 1535,1541 ----
  		{"pgdata", required_argument, NULL, 'D'},
  		{"format", required_argument, NULL, 'F'},
  		{"checkpoint", required_argument, NULL, 'c'},
+ 		{"connection-string", required_argument, NULL, 'C'},
  		{"write-recovery-conf", no_argument, NULL, 'R'},
  		{"xlog", no_argument, NULL, 'x'},
  		{"xlog-method", required_argument, NULL, 'X'},
***************
*** 1572,1578 **** main(int argc, char **argv)
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:wWvP",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
--- 1574,1580 ----
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:C:c:h:p:U:s:wWvP",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
***************
*** 1663,1668 **** main(int argc, char **argv)
--- 1665,1673 ----
  					exit(1);
  				}
  				break;
+ 			case 'C':
+ 				connection_string = pg_strdup(optarg);
+ 				break;
  			case 'h':
  				dbhost = pg_strdup(optarg);
  				break;
*** a/src/bin/pg_basebackup/pg_receivexlog.c
--- b/src/bin/pg_basebackup/pg_receivexlog.c
***************
*** 58,63 **** usage(void)
--- 58,64 ----
  	printf(_("  -V, --version          output version information, then exit\n"));
  	printf(_("  -?, --help             show this help, then exit\n"));
  	printf(_("\nConnection options:\n"));
+ 	printf(_("  -C, --connection-string=\"OPTIONS\" connect to server using OPTIONS\n"));
  	printf(_("  -h, --host=HOSTNAME    database server host or socket directory\n"));
  	printf(_("  -p, --port=PORT        database server port number\n"));
  	printf(_("  -s, --status-interval=INTERVAL\n"
***************
*** 305,310 **** main(int argc, char **argv)
--- 306,312 ----
  	static struct option long_options[] = {
  		{"help", no_argument, NULL, '?'},
  		{"version", no_argument, NULL, 'V'},
+ 		{"connection-string", required_argument, NULL, 'C'},
  		{"directory", required_argument, NULL, 'D'},
  		{"host", required_argument, NULL, 'h'},
  		{"port", required_argument, NULL, 'p'},
***************
*** 338,348 **** main(int argc, char **argv)
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
  			case 'D':
  				basedir = pg_strdup(optarg);
  				break;
--- 340,353 ----
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "C:D:h:p:U:s:nwWv",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
+ 			case 'C':
+ 				connection_string = pg_strdup(optarg);
+ 				break;
  			case 'D':
  				basedir = pg_strdup(optarg);
  				break;
*** a/src/bin/pg_basebackup/streamutil.c
--- b/src/bin/pg_basebackup/streamutil.c
***************
*** 24,29 **** char	   *dbport = NULL;
--- 24,31 ----
  int			dbgetpassword = 0;	/* 0=auto, -1=never, 1=always */
  static char *dbpassword = NULL;
  PGconn	   *conn = NULL;
+ char	   *connection_string = NULL;
+ 
  
  /*
   * Connect to the server. Returns a valid PGconn pointer if connected,
***************
*** 34,64 **** PGconn *
  GetConnection(void)
  {
  	PGconn	   *tmpconn;
! 	int			argcount = 4;	/* dbname, replication, fallback_app_name,
! 								 * password */
! 	int			i;
  	const char **keywords;
  	const char **values;
  	char	   *password = NULL;
  	const char *tmpparam;
  
- 	if (dbhost)
- 		argcount++;
- 	if (dbuser)
- 		argcount++;
- 	if (dbport)
- 		argcount++;
- 
- 	keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
- 	values = pg_malloc0((argcount + 1) * sizeof(*values));
- 
- 	keywords[0] = "dbname";
- 	values[0] = "replication";
- 	keywords[1] = "replication";
- 	values[1] = "true";
- 	keywords[2] = "fallback_application_name";
- 	values[2] = progname;
- 	i = 3;
  	if (dbhost)
  	{
  		keywords[i] = "host";
--- 36,97 ----
  GetConnection(void)
  {
  	PGconn	   *tmpconn;
! 	int			i = 0;
  	const char **keywords;
  	const char **values;
  	char	   *password = NULL;
  	const char *tmpparam;
+ 	PQconninfoOption *conn_opts = NULL,
+ 			   *conn_opts_merged = NULL;
+ 	PQconninfoOption *conn_opt;
+ 	char	   *err_msg = NULL;
+ 
+ 
+ 	keywords = pg_malloc0(MAX_CONNINFO_OPTIONS * sizeof(*keywords));
+ 	values = pg_malloc0(MAX_CONNINFO_OPTIONS * sizeof(*values));
+ 
+ 	/*
+ 	 * Merge the connection info inputs given in form of connection string,
+ 	 * options and default values (dbname=replication, replication=true,
+ 	 * etc.). We could have written new function to connect using
+ 	 * PQconninfoOption, but it's not a lot of code to iterate through the
+ 	 * PGconnInfoOption array and turn it back into keywords and values
+ 	 * arrays, so just do that straight in the client code.
+ 	 */
+ 
+ 	if (connection_string)
+ 	{
+ 		conn_opts = PQconninfoParse(connection_string, &err_msg);
+ 		if (conn_opts != NULL)
+ 		{
+ 			for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
+ 			{
+ 				if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
+ 				{
+ 					keywords[i] = conn_opt->keyword;
+ 					values[i] = conn_opt->val;
+ 					i++;
+ 				}
+ 			}
+ 		}
+ 		else
+ 		{
+ 			fprintf(stderr, "%s: %s\n", progname, err_msg);
+ 			return NULL;
+ 		}
+ 
+ 	}
+ 
+ 	keywords[i] = "dbname";
+ 	values[i] = "replication";
+ 	i++;
+ 	keywords[i] = "replication";
+ 	values[i] = "true";
+ 	i++;
+ 	keywords[i] = "fallback_application_name";
+ 	values[i] = progname;
+ 	i++;
  
  	if (dbhost)
  	{
  		keywords[i] = "host";
***************
*** 78,83 **** GetConnection(void)
--- 111,143 ----
  		i++;
  	}
  
+ 	if (connection_string)
+ 	{
+ 		conn_opts_merged = PQconninfoParseParams(keywords, values,
+ 												 true, &err_msg);
+ 		if (conn_opts_merged != NULL)
+ 		{
+ 			i = 0;
+ 			MemSet(keywords, 0, MAX_CONNINFO_OPTIONS * sizeof(*keywords));
+ 			MemSet(values, 0, MAX_CONNINFO_OPTIONS * sizeof(*values));
+ 			for (conn_opt = conn_opts_merged; conn_opt->keyword != NULL; conn_opt++)
+ 			{
+ 				if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
+ 				{
+ 					keywords[i] = conn_opt->keyword;
+ 					values[i] = conn_opt->val;
+ 					i++;
+ 				}
+ 			}
+ 		}
+ 		else
+ 		{
+ 			fprintf(stderr, "%s: %s\n", progname, err_msg);
+ 			PQconninfoFree(conn_opts);
+ 			return NULL;
+ 		}
+ 	}
+ 
  	while (true)
  	{
  		if (password)
***************
*** 90,104 **** GetConnection(void)
  			 * meaning this is the call for a second session to the same
  			 * database, so just forcibly reuse that password.
  			 */
! 			keywords[argcount - 1] = "password";
! 			values[argcount - 1] = dbpassword;
  			dbgetpassword = -1; /* Don't try again if this fails */
  		}
  		else if (dbgetpassword == 1)
  		{
  			password = simple_prompt(_("Password: "), 100, false);
! 			keywords[argcount - 1] = "password";
! 			values[argcount - 1] = password;
  		}
  
  		tmpconn = PQconnectdbParams(keywords, values, true);
--- 150,164 ----
  			 * meaning this is the call for a second session to the same
  			 * database, so just forcibly reuse that password.
  			 */
! 			keywords[i] = "password";
! 			values[i] = dbpassword;
  			dbgetpassword = -1; /* Don't try again if this fails */
  		}
  		else if (dbgetpassword == 1)
  		{
  			password = simple_prompt(_("Password: "), 100, false);
! 			keywords[i] = "password";
! 			values[i] = password;
  		}
  
  		tmpconn = PQconnectdbParams(keywords, values, true);
***************
*** 130,141 **** GetConnection(void)
--- 190,205 ----
  			PQfinish(tmpconn);
  			free(values);
  			free(keywords);
+ 			PQconninfoFree(conn_opts);
+ 			PQconninfoFree(conn_opts_merged);
  			return NULL;
  		}
  
  		/* Connection ok! */
  		free(values);
  		free(keywords);
+ 		PQconninfoFree(conn_opts);
+ 		PQconninfoFree(conn_opts_merged);
  
  		/*
  		 * Ensure we have the same value of integer timestamps as the server
*** a/src/bin/pg_basebackup/streamutil.h
--- b/src/bin/pg_basebackup/streamutil.h
***************
*** 5,10 **** extern char *dbhost;
--- 5,11 ----
  extern char *dbuser;
  extern char *dbport;
  extern int	dbgetpassword;
+ extern char *connection_string;
  
  /* Connection kept global so we can disconnect easily */
  extern PGconn *conn;
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 28,33 **** extern const int NumFEScanKeywords;
--- 28,34 ----
  /* Globals exported by this file */
  int			quote_all_identifiers = 0;
  const char *progname = NULL;
+ char	   *connection_string = NULL;
  
  #define MAX_ON_EXIT_NICELY				20
  
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
***************
*** 44,49 **** typedef void (*on_exit_nicely_callback) (int code, void *arg);
--- 44,50 ----
  
  extern int	quote_all_identifiers;
  extern const char *progname;
+ extern char *connection_string;
  
  extern void init_parallel_dump_utils(void);
  extern const char *fmtId(const char *identifier);
*** a/src/bin/pg_dump/pg_backup_db.c
--- b/src/bin/pg_dump/pg_backup_db.c
***************
*** 254,283 **** ConnectDatabase(Archive *AHX,
  	 */
  	do
  	{
! #define PARAMS_ARRAY_SIZE	7
! 		const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
! 		const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
  
- 		keywords[0] = "host";
- 		values[0] = pghost;
- 		keywords[1] = "port";
- 		values[1] = pgport;
- 		keywords[2] = "user";
- 		values[2] = username;
- 		keywords[3] = "password";
- 		values[3] = password;
- 		keywords[4] = "dbname";
- 		values[4] = dbname;
- 		keywords[5] = "fallback_application_name";
- 		values[5] = progname;
- 		keywords[6] = NULL;
- 		values[6] = NULL;
  
  		new_pass = false;
  		AH->connection = PQconnectdbParams(keywords, values, true);
  
  		free(keywords);
  		free(values);
  
  		if (!AH->connection)
  			exit_horribly(modulename, "failed to connect to database\n");
--- 254,349 ----
  	 */
  	do
  	{
! 		const char **keywords = pg_malloc(MAX_CONNINFO_OPTIONS * sizeof(*keywords));
! 		const char **values = pg_malloc(MAX_CONNINFO_OPTIONS * sizeof(*values));
! 		PQconninfoOption *conn_opts = NULL,
! 				   *conn_opts_merged = NULL;
! 		PQconninfoOption *conn_opt;
! 		char	   *err_msg = NULL;
! 		int			i = 0;
! 
! 		/*
! 		 * Merge the connection info inputs given in form of connection string
! 		 * and options. We could have written new function to connect using
! 		 * PQconninfoOption, but it's not a lot of code to iterate through the
! 		 * PGconnInfoOption array and turn it back into keywords and values
! 		 * arrays, so just do that straight in the client code.
! 		 */
! 		if (connection_string)
! 		{
! 			conn_opts = PQconninfoParse(connection_string, &err_msg);
! 			if (conn_opts != NULL)
! 			{
! 				for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
! 				{
! 					if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
! 					{
! 						keywords[i] = conn_opt->keyword;
! 						values[i] = conn_opt->val;
! 						i++;
! 					}
! 				}
! 			}
! 			else
! 				exit_horribly(modulename, "%s\n", err_msg);
! 		}
! 
! 		keywords[i] = "host";
! 		values[i] = pghost;
! 		i++;
! 		keywords[i] = "port";
! 		values[i] = pgport;
! 		i++;
! 		keywords[i] = "user";
! 		values[i] = username;
! 		i++;
! 		keywords[i] = "password";
! 		values[i] = password;
! 		i++;
! 		keywords[i] = "dbname";
! 		values[i] = dbname;
! 		i++;
! 		keywords[i] = "fallback_application_name";
! 		values[i] = progname;
! 		i++;
! 		keywords[i] = NULL;
! 		values[i] = NULL;
! 
! 		if (connection_string)
! 		{
! 			conn_opts_merged = PQconninfoParseParams(keywords, values,
! 													 true, &err_msg);
! 			if (conn_opts_merged != NULL)
! 			{
! 				i = 0;
! 				MemSet(keywords, 0, MAX_CONNINFO_OPTIONS * sizeof(*keywords));
! 				MemSet(values, 0, MAX_CONNINFO_OPTIONS * sizeof(*values));
! 				for (conn_opt = conn_opts_merged; conn_opt->keyword != NULL; conn_opt++)
! 				{
! 					if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
! 					{
! 						keywords[i] = conn_opt->keyword;
! 						values[i] = conn_opt->val;
! 						i++;
! 					}
! 				}
! 			}
! 			else
! 			{
! 				PQconninfoFree(conn_opts);
! 				exit_horribly(modulename, "%s\n", err_msg);
! 
! 			}
! 		}
  
  
  		new_pass = false;
  		AH->connection = PQconnectdbParams(keywords, values, true);
  
  		free(keywords);
  		free(values);
+ 		PQconninfoFree(conn_opts);
+ 		PQconninfoFree(conn_opts_merged);
  
  		if (!AH->connection)
  			exit_horribly(modulename, "failed to connect to database\n");
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
***************
*** 311,316 **** main(int argc, char **argv)
--- 311,317 ----
  		{"format", required_argument, NULL, 'F'},
  		{"host", required_argument, NULL, 'h'},
  		{"ignore-version", no_argument, NULL, 'i'},
+ 		{"connection-string", required_argument, NULL, 'K'},
  		{"no-reconnect", no_argument, NULL, 'R'},
  		{"oids", no_argument, NULL, 'o'},
  		{"no-owner", no_argument, NULL, 'O'},
***************
*** 387,393 **** main(int argc, char **argv)
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "abcCE:f:F:h:in:N:oOp:RsS:t:T:U:vwWxZ:",
  							long_options, &optindex)) != -1)
  	{
  		switch (c)
--- 388,394 ----
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "abcCE:f:F:h:iK:n:N:oOp:RsS:t:T:U:vwWxZ:",
  							long_options, &optindex)) != -1)
  	{
  		switch (c)
***************
*** 428,433 **** main(int argc, char **argv)
--- 429,438 ----
  				/* ignored, deprecated option */
  				break;
  
+ 			case 'K':
+ 				connection_string = pg_strdup(optarg);
+ 				break;
+ 
  			case 'n':			/* include schema(s) */
  				simple_string_list_append(&schema_include_patterns, optarg);
  				include_everything = false;
***************
*** 872,877 **** help(const char *progname)
--- 877,883 ----
  			 "                               ALTER OWNER commands to set ownership\n"));
  
  	printf(_("\nConnection options:\n"));
+ 	printf(_("  -K, --connection-string=\"OPTIONS\" connect to server using OPTIONS\n"));
  	printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
  	printf(_("  -p, --port=PORT          database server port number\n"));
  	printf(_("  -U, --username=NAME      connect as specified database user\n"));
*** a/src/bin/pg_dump/pg_dumpall.c
--- b/src/bin/pg_dump/pg_dumpall.c
***************
*** 79,85 **** static int	server_version;
  static FILE *OPF;
  static char *filename = NULL;
  
- 
  int
  main(int argc, char *argv[])
  {
--- 79,84 ----
***************
*** 90,95 **** main(int argc, char *argv[])
--- 89,95 ----
  		{"globals-only", no_argument, NULL, 'g'},
  		{"host", required_argument, NULL, 'h'},
  		{"ignore-version", no_argument, NULL, 'i'},
+ 		{"connection-string", required_argument, NULL, 'K'},
  		{"database", required_argument, NULL, 'l'},
  		{"oids", no_argument, NULL, 'o'},
  		{"no-owner", no_argument, NULL, 'O'},
***************
*** 187,193 **** main(int argc, char *argv[])
  
  	pgdumpopts = createPQExpBuffer();
  
! 	while ((c = getopt_long(argc, argv, "acf:gh:il:oOp:rsS:tU:vwWx", long_options, &optindex)) != -1)
  	{
  		switch (c)
  		{
--- 187,193 ----
  
  	pgdumpopts = createPQExpBuffer();
  
! 	while ((c = getopt_long(argc, argv, "acf:gh:iK:l:oOp:rsS:tU:vwWx", long_options, &optindex)) != -1)
  	{
  		switch (c)
  		{
***************
*** 220,225 **** main(int argc, char *argv[])
--- 220,231 ----
  				/* ignored, deprecated option */
  				break;
  
+ 			case 'K':
+ 				connection_string = pg_strdup(optarg);
+ 				appendPQExpBuffer(pgdumpopts, " -K ");
+ 				doShellQuoting(pgdumpopts, connection_string);
+ 				break;
+ 
  			case 'l':
  				pgdb = pg_strdup(optarg);
  				break;
***************
*** 567,572 **** help(void)
--- 573,579 ----
  			 "                               ALTER OWNER commands to set ownership\n"));
  
  	printf(_("\nConnection options:\n"));
+ 	printf(_("  -K, --connection-string=\"OPTIONS\" connect to server using OPTIONS\n"));
  	printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
  	printf(_("  -l, --database=DBNAME    alternative default database\n"));
  	printf(_("  -p, --port=PORT          database server port number\n"));
***************
*** 1710,1739 **** connectDatabase(const char *dbname, const char *pghost, const char *pgport,
  	 */
  	do
  	{
! #define PARAMS_ARRAY_SIZE	7
! 		const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
! 		const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
! 
! 		keywords[0] = "host";
! 		values[0] = pghost;
! 		keywords[1] = "port";
! 		values[1] = pgport;
! 		keywords[2] = "user";
! 		values[2] = pguser;
! 		keywords[3] = "password";
! 		values[3] = password;
! 		keywords[4] = "dbname";
! 		values[4] = dbname;
! 		keywords[5] = "fallback_application_name";
! 		values[5] = progname;
! 		keywords[6] = NULL;
! 		values[6] = NULL;
  
  		new_pass = false;
  		conn = PQconnectdbParams(keywords, values, true);
  
  		free(keywords);
  		free(values);
  
  		if (!conn)
  		{
--- 1717,1814 ----
  	 */
  	do
  	{
! 		const char **keywords = pg_malloc(MAX_CONNINFO_OPTIONS * sizeof(*keywords));
! 		const char **values = pg_malloc(MAX_CONNINFO_OPTIONS * sizeof(*values));
! 		PQconninfoOption *conn_opts = NULL,
! 				   *conn_opts_merged = NULL;
! 		PQconninfoOption *conn_opt;
! 		char	   *err_msg = NULL;
! 		int			i = 0;
! 
! 		/*
! 		 * Merge the connection info inputs given in form of connection string
! 		 * and options. We could have written new function to connect using
! 		 * PQconninfoOption, but it's not a lot of code to iterate through the
! 		 * PGconnInfoOption array and turn it back into keywords and values
! 		 * arrays, so just do that straight in the client code.
! 		 */
! 		if (connection_string)
! 		{
! 			conn_opts = PQconninfoParse(connection_string, &err_msg);
! 			if (conn_opts != NULL)
! 			{
! 				for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
! 				{
! 					if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
! 					{
! 						keywords[i] = conn_opt->keyword;
! 						values[i] = conn_opt->val;
! 						i++;
! 					}
! 				}
! 			}
! 			else
! 			{
! 				fprintf(stderr, "%s: %s\n", progname, err_msg);
! 				return NULL;
! 			}
! 		}
! 
! 		keywords[i] = "host";
! 		values[i] = pghost;
! 		i++;
! 		keywords[i] = "port";
! 		values[i] = pgport;
! 		i++;
! 		keywords[i] = "user";
! 		values[i] = pguser;
! 		i++;
! 		keywords[i] = "password";
! 		values[i] = password;
! 		i++;
! 		keywords[i] = "dbname";
! 		values[i] = dbname;
! 		i++;
! 		keywords[i] = "fallback_application_name";
! 		values[i] = progname;
! 		i++;
! 		keywords[i] = NULL;
! 		values[i] = NULL;
! 
! 		if (connection_string)
! 		{
! 			conn_opts_merged = PQconninfoParseParams(keywords, values,
! 													 true, &err_msg);
! 			if (conn_opts_merged != NULL)
! 			{
! 				i = 0;
! 				MemSet(keywords, 0, MAX_CONNINFO_OPTIONS * sizeof(*keywords));
! 				MemSet(values, 0, MAX_CONNINFO_OPTIONS * sizeof(*values));
! 				for (conn_opt = conn_opts_merged; conn_opt->keyword != NULL; conn_opt++)
! 				{
! 					if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
! 					{
! 						keywords[i] = conn_opt->keyword;
! 						values[i] = conn_opt->val;
! 						i++;
! 					}
! 				}
! 			}
! 			else
! 			{
! 				fprintf(stderr, "%s: %s\n", progname, err_msg);
! 				PQconninfoFree(conn_opts);
! 				return NULL;
! 			}
! 		}
  
  		new_pass = false;
  		conn = PQconnectdbParams(keywords, values, true);
  
  		free(keywords);
  		free(values);
+ 		PQconninfoFree(conn_opts);
+ 		PQconninfoFree(conn_opts_merged);
  
  		if (!conn)
  		{
*** a/src/include/pg_config_manual.h
--- b/src/include/pg_config_manual.h
***************
*** 200,205 ****
--- 200,213 ----
  #endif
  
  /*
+  * MAX_CONNINFO_OPTIONS: maximum number of options for connection.
+  *				It refers to PQconninfoOptions, currently it is less than 50, kept
+  *				this considering future additions, however it can be kept same.
+  */
+ #define MAX_CONNINFO_OPTIONS		50
+ 
+ 
+ /*
   *------------------------------------------------------------------------
   * The following symbols are for enabling debugging code, not for
   * controlling user-visible features or resource limits.
*** a/src/interfaces/libpq/exports.txt
--- b/src/interfaces/libpq/exports.txt
***************
*** 165,167 **** lo_lseek64                162
--- 165,169 ----
  lo_tell64                 163
  lo_truncate64             164
  PQconninfo                165
+ PQconninfoParseParams     166
+ PQconninfodefaultsMerge   167
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***************
*** 4002,4007 **** PQconninfoParse(const char *conninfo, char **errmsg)
--- 4002,4086 ----
  }
  
  /*
+  *		PQconninfoParseParams
+  *
+  * Parse a string like PQconnectdbParams() would do and return the
+  * resulting connection options array.	NULL is returned on failure.
+  * The result contains only options specified directly in the array,
+  * not any possible default values.
+  *
+  * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
+  * string on failure (use PQfreemem to free it).  In out-of-memory conditions
+  * both *errmsg and the result could be NULL.
+  *
+  * NOTE: the returned array is dynamically allocated and should
+  * be freed when no longer needed via PQconninfoFree().
+  */
+ PQconninfoOption *
+ PQconninfoParseParams(const char *const * keywords,
+ 					  const char *const * values, int expand_dbname,
+ 					  char **errmsg)
+ {
+ 	PQExpBufferData errorBuf;
+ 	PQconninfoOption *connOptions;
+ 
+ 	if (errmsg)
+ 		*errmsg = NULL;			/* default */
+ 	initPQExpBuffer(&errorBuf);
+ 	if (PQExpBufferDataBroken(errorBuf))
+ 		return NULL;			/* out of memory already :-( */
+ 	connOptions = conninfo_array_parse(keywords, values,
+ 									   &errorBuf,
+ 									   false, expand_dbname);
+ 
+ 	if (connOptions == NULL && errmsg)
+ 		*errmsg = errorBuf.data;
+ 	else
+ 		termPQExpBuffer(&errorBuf);
+ 	return connOptions;
+ }
+ 
+ /*
+  *		PQconninfodefaultsMerge
+  *
+  * Add the default values for any unspecified options to the connection
+  * options array.
+  *
+  * Defaults are obtained from a service file, environment variables, etc.
+  *
+  * Returns 1 if successful, otherwise 0; connOptions is freed and errmsg is
+  * filled in upon failure.  Note that failure to locate a default value is
+  * not an error condition here --- we just leave the option's value as NULL.
+  *
+  * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
+  * string on failure (use PQfreemem to free it).  In out-of-memory conditions
+  * both *errmsg and the result could be NULL.
+  */
+ int
+ PQconninfodefaultsMerge(PQconninfoOption *connOptions, char **errmsg)
+ {
+ 	PQExpBufferData errorBuf;
+ 
+ 	if (errmsg)
+ 		*errmsg = NULL;
+ 	initPQExpBuffer(&errorBuf);
+ 	if (PQExpBufferDataBroken(errorBuf))
+ 	{
+ 		PQconninfoFree(connOptions);
+ 		return 0;
+ 	}
+ 	if (!conninfo_add_defaults(connOptions, &errorBuf))
+ 	{
+ 		if (errmsg)
+ 			*errmsg = errorBuf.data;
+ 		PQconninfoFree(connOptions);
+ 		return 0;
+ 	}
+ 	termPQExpBuffer(&errorBuf);
+ 	return 1;
+ }
+ 
+ /*
   * Build a working copy of the constant PQconninfoOptions array.
   */
  static PQconninfoOption *
*** a/src/interfaces/libpq/libpq-fe.h
--- b/src/interfaces/libpq/libpq-fe.h
***************
*** 267,276 **** extern PQconninfoOption *PQconndefaults(void);
  /* parse connection options in same way as PQconnectdb */
  extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
  
  /* return the connection options used by a live connection */
  extern PQconninfoOption *PQconninfo(PGconn *conn);
  
! /* free the data structure returned by PQconndefaults() or PQconninfoParse() */
  extern void PQconninfoFree(PQconninfoOption *connOptions);
  
  /*
--- 267,284 ----
  /* parse connection options in same way as PQconnectdb */
  extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
  
+ /* parse connection options in same way as PQconnectdbParams */
+ extern PQconninfoOption *PQconninfoParseParams(const char *const * keywords,
+ 					  const char *const * values, int expand_dbname,
+ 					  char **errmsg);
+ 
+ /* Merge default connection options into an existing PQconninfoOption struct */
+ extern int	PQconninfodefaultsMerge(PQconninfoOption *connOptions, char **errmsg);
+ 
  /* return the connection options used by a live connection */
  extern PQconninfoOption *PQconninfo(PGconn *conn);
  
! /* free the data structure returned by PQconndefaults(), PQconninfoParse(), or PQconninfoParseParams() */
  extern void PQconninfoFree(PQconninfoOption *connOptions);
  
  /*
