Using the new libpq connection functions in PostgreSQL binaries

Started by Guillaume Lelargealmost 16 years ago7 messages
#1Guillaume Lelarge
guillaume@lelarge.info
1 attachment(s)

Hi,

I worked on a patch to make PostgreSQL binaries use the new
PQconnectdbParams() libpq functions. I tried to mimic the way Joe Conway
changed my previous patch.

I know I'm way over the deadline for this commitfest. I couldn't do it
before because my previous patch (on this commit fest) proposed two
methods to do the new connection functions (a one array method, and a
two-arrays method). Joe chose the two arrays method. Anyways, I would
understand if it gets postponed to the first commitfest for 9.1.

Regards.

--
Guillaume.
http://www.postgresqlfr.org
http://dalibo.com

Attachments:

appname.patchtext/x-patch; name=appname.patchDownload
Index: contrib/oid2name/oid2name.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/contrib/oid2name/oid2name.c,v
retrieving revision 1.36
diff -c -p -c -r1.36 oid2name.c
*** contrib/oid2name/oid2name.c	11 Jun 2009 14:48:51 -0000	1.36
--- contrib/oid2name/oid2name.c	31 Jan 2010 01:36:38 -0000
*************** sql_conn(struct options * my_opts)
*** 301,306 ****
--- 301,308 ----
  	PGconn	   *conn;
  	char	   *password = NULL;
  	bool		new_pass;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	/*
  	 * Start the connection.  Loop until we have a password if requested by
*************** sql_conn(struct options * my_opts)
*** 308,321 ****
  	 */
  	do
  	{
  		new_pass = false;
! 		conn = PQsetdbLogin(my_opts->hostname,
! 							my_opts->port,
! 							NULL,		/* options */
! 							NULL,		/* tty */
! 							my_opts->dbname,
! 							my_opts->username,
! 							password);
  		if (!conn)
  		{
  			fprintf(stderr, "%s: could not connect to database %s\n",
--- 310,327 ----
  	 */
  	do
  	{
+         const char *values[] = {
+                   my_opts->hostname,
+                   my_opts->port,
+                   my_opts->dbname,
+                   my_opts->username,
+                   password,
+                   "oid2name",
+                   NULL
+               };
+         
  		new_pass = false;
!         conn = PQconnectdbParams(keywords, values);
  		if (!conn)
  		{
  			fprintf(stderr, "%s: could not connect to database %s\n",
Index: contrib/pgbench/pgbench.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/contrib/pgbench/pgbench.c,v
retrieving revision 1.96
diff -c -p -c -r1.96 pgbench.c
*** contrib/pgbench/pgbench.c	6 Jan 2010 01:30:03 -0000	1.96
--- contrib/pgbench/pgbench.c	31 Jan 2010 01:41:45 -0000
*************** doConnect(void)
*** 345,350 ****
--- 345,352 ----
  	PGconn	   *conn;
  	static char *password = NULL;
  	bool		new_pass;
+ 	const char *keywords[] = {"host","port","options","tty","dbname","user",
+ 							  "password","application_name",NULL};
  
  	/*
  	 * Start the connection.  Loop until we have a password if requested by
*************** doConnect(void)
*** 352,361 ****
  	 */
  	do
  	{
  		new_pass = false;
! 
! 		conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName,
! 							login, password);
  		if (!conn)
  		{
  			fprintf(stderr, "Connection to database \"%s\" failed\n",
--- 354,373 ----
  	 */
  	do
  	{
+         const char *values[] = {
+                   pghost,
+                   pgport,
+                   pgoptions,
+                   pgtty,
+                   dbName,
+                   login,
+                   password,
+                   "pgbench",
+                   NULL
+               };
+         
  		new_pass = false;
!         conn = PQconnectdbParams(keywords, values);
  		if (!conn)
  		{
  			fprintf(stderr, "Connection to database \"%s\" failed\n",
Index: contrib/vacuumlo/vacuumlo.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/contrib/vacuumlo/vacuumlo.c,v
retrieving revision 1.44
diff -c -p -c -r1.44 vacuumlo.c
*** contrib/vacuumlo/vacuumlo.c	2 Jan 2010 16:57:33 -0000	1.44
--- contrib/vacuumlo/vacuumlo.c	31 Jan 2010 01:44:55 -0000
*************** vacuumlo(char *database, struct _param *
*** 70,75 ****
--- 70,77 ----
  	int			i;
  	static char *password = NULL;
  	bool		new_pass;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	if (param->pg_prompt == TRI_YES && password == NULL)
  		password = simple_prompt("Password: ", 100, false);
*************** vacuumlo(char *database, struct _param *
*** 80,94 ****
  	 */
  	do
  	{
  		new_pass = false;
! 
! 		conn = PQsetdbLogin(param->pg_host,
! 							param->pg_port,
! 							NULL,
! 							NULL,
! 							database,
! 							param->pg_user,
! 							password);
  		if (!conn)
  		{
  			fprintf(stderr, "Connection to database \"%s\" failed\n",
--- 82,99 ----
  	 */
  	do
  	{
+         const char *values[] = {
+                   param->pg_host,
+                   param->pg_port,
+                   database,
+                   param->pg_user,
+                   password,
+                   "vacuumlo",
+                   NULL
+               };
+         
  		new_pass = false;
!         conn = PQconnectdbParams(keywords, values);
  		if (!conn)
  		{
  			fprintf(stderr, "Connection to database \"%s\" failed\n",
Index: src/bin/pg_ctl/pg_ctl.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/src/bin/pg_ctl/pg_ctl.c,v
retrieving revision 1.118
diff -c -p -c -r1.118 pg_ctl.c
*** src/bin/pg_ctl/pg_ctl.c	2 Jan 2010 16:57:58 -0000	1.118
--- src/bin/pg_ctl/pg_ctl.c	30 Jan 2010 22:33:42 -0000
*************** test_postmaster_connection(bool do_check
*** 407,413 ****
  	char		portstr[32];
  	char	   *p;
  	char	   *q;
! 	char		connstr[128];	/* Should be way more than enough! */
  
  	*portstr = '\0';
  
--- 407,414 ----
  	char		portstr[32];
  	char	   *p;
  	char	   *q;
! 	const char *keywords[] = {"dbname","port","connect_timeout",
! 							  "application_name",NULL};
  
  	*portstr = '\0';
  
*************** test_postmaster_connection(bool do_check
*** 501,512 ****
  	 * We need to set a connect timeout otherwise on Windows the SCM will
  	 * probably timeout first
  	 */
! 	snprintf(connstr, sizeof(connstr),
! 			 "dbname=postgres port=%s connect_timeout=5", portstr);
! 
  	for (i = 0; i < wait_seconds; i++)
  	{
! 		if ((conn = PQconnectdb(connstr)) != NULL &&
  			(PQstatus(conn) == CONNECTION_OK ||
  			 PQconnectionNeedsPassword(conn)))
  		{
--- 502,518 ----
  	 * We need to set a connect timeout otherwise on Windows the SCM will
  	 * probably timeout first
  	 */
!     const char *values[] = {
!               "postgres",
!               portstr,
!               5,
!               "pg_ctl",
!               NULL
!           };
!     
  	for (i = 0; i < wait_seconds; i++)
  	{
! 		if ((conn = PQconnectdbParams(keywords, values)) != NULL &&
  			(PQstatus(conn) == CONNECTION_OK ||
  			 PQconnectionNeedsPassword(conn)))
  		{
Index: src/bin/pg_dump/pg_backup_db.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/src/bin/pg_dump/pg_backup_db.c,v
retrieving revision 1.85
diff -c -p -c -r1.85 pg_backup_db.c
*** src/bin/pg_dump/pg_backup_db.c	14 Dec 2009 00:39:11 -0000	1.85
--- src/bin/pg_dump/pg_backup_db.c	30 Jan 2010 22:13:38 -0000
*************** _connectDB(ArchiveHandle *AH, const char
*** 131,136 ****
--- 131,138 ----
  	const char *newuser;
  	char	   *password = AH->savedPassword;
  	bool		new_pass;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	if (!reqdb)
  		newdb = PQdb(AH->connection);
*************** _connectDB(ArchiveHandle *AH, const char
*** 154,163 ****
  
  	do
  	{
! 		new_pass = false;
! 		newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
! 							   NULL, NULL, newdb,
! 							   newuser, password);
  		if (!newConn)
  			die_horribly(AH, modulename, "failed to reconnect to database\n");
  
--- 156,173 ----
  
  	do
  	{
!         const char *values[] = {
!                   PQhost(AH->connection),
!                   PQport(AH->connection),
!                   newdb,
!                   newuser,
!                   password,
!                   progname,
!                   NULL
!               };
!         
!         new_pass = false;
!         newConn = PQconnectdbParams(keywords, values);
  		if (!newConn)
  			die_horribly(AH, modulename, "failed to reconnect to database\n");
  
*************** ConnectDatabase(Archive *AHX,
*** 219,224 ****
--- 229,236 ----
  	ArchiveHandle *AH = (ArchiveHandle *) AHX;
  	char	   *password = AH->savedPassword;
  	bool		new_pass;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	if (AH->connection)
  		die_horribly(AH, modulename, "already connected to a database\n");
*************** ConnectDatabase(Archive *AHX,
*** 237,245 ****
  	 */
  	do
  	{
! 		new_pass = false;
! 		AH->connection = PQsetdbLogin(pghost, pgport, NULL, NULL,
! 									  dbname, username, password);
  
  		if (!AH->connection)
  			die_horribly(AH, modulename, "failed to connect to database\n");
--- 249,266 ----
  	 */
  	do
  	{
!         const char *values[] = {
!                   pghost,
!                   pgport,
!                   dbname,
!                   username,
!                   password,
!                   progname,
!                   NULL
!               };
!         
!         new_pass = false;
!         AH->connection = PQconnectdbParams(keywords, values);
  
  		if (!AH->connection)
  			die_horribly(AH, modulename, "failed to connect to database\n");
Index: src/bin/pg_dump/pg_dumpall.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/src/bin/pg_dump/pg_dumpall.c,v
retrieving revision 1.131
diff -c -p -c -r1.131 pg_dumpall.c
*** src/bin/pg_dump/pg_dumpall.c	6 Jan 2010 03:34:41 -0000	1.131
--- src/bin/pg_dump/pg_dumpall.c	30 Jan 2010 22:11:02 -0000
*************** connectDatabase(const char *dbname, cons
*** 1608,1613 ****
--- 1608,1615 ----
  	const char *remoteversion_str;
  	int			my_version;
  	static char *password = NULL;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	if (prompt_password == TRI_YES && !password)
  		password = simple_prompt("Password: ", 100, false);
*************** connectDatabase(const char *dbname, cons
*** 1618,1625 ****
  	 */
  	do
  	{
! 		new_pass = false;
! 		conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
  
  		if (!conn)
  		{
--- 1620,1637 ----
  	 */
  	do
  	{
!         const char *values[] = {
!                   pghost,
!                   pgport,
!                   dbname,
!                   pguser,
!                   password,
!                   progname,
!                   NULL
!               };
!         
!         new_pass = false;
!         conn = PQconnectdbParams(keywords, values);
  
  		if (!conn)
  		{
Index: src/bin/psql/command.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/src/bin/psql/command.c,v
retrieving revision 1.213
diff -c -p -c -r1.213 command.c
*** src/bin/psql/command.c	2 Jan 2010 16:57:59 -0000	1.213
--- src/bin/psql/command.c	30 Jan 2010 22:23:52 -0000
*************** param_is_newly_set(const char *old_val, 
*** 1212,1219 ****
   *
   * Connects to a database with given parameters. If there exists an
   * established connection, NULL values will be replaced with the ones
!  * in the current connection. Otherwise NULL will be passed for that
!  * parameter to PQsetdbLogin(), so the libpq defaults will be used.
   *
   * In interactive mode, if connection fails with the given parameters,
   * the old connection will be kept.
--- 1212,1218 ----
   *
   * Connects to a database with given parameters. If there exists an
   * established connection, NULL values will be replaced with the ones
!  * in the current connection. Otherwise the libpq defaults will be used.
   *
   * In interactive mode, if connection fails with the given parameters,
   * the old connection will be kept.
*************** do_connect(char *dbname, char *user, cha
*** 1224,1229 ****
--- 1223,1230 ----
  	PGconn	   *o_conn = pset.db,
  			   *n_conn;
  	char	   *password = NULL;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	if (!dbname)
  		dbname = PQdb(o_conn);
*************** do_connect(char *dbname, char *user, cha
*** 1255,1262 ****
  
  	while (true)
  	{
! 		n_conn = PQsetdbLogin(host, port, NULL, NULL,
! 							  dbname, user, password);
  
  		/* We can immediately discard the password -- no longer needed */
  		if (password)
--- 1256,1272 ----
  
  	while (true)
  	{
!         const char *values[] = {
!                   host,
!                   port,
!                   dbname,
!                   user,
!                   password,
!                   pset.progname,
!                   NULL
!               };
!         
!         n_conn = PQconnectdbParams(keywords, values);
  
  		/* We can immediately discard the password -- no longer needed */
  		if (password)
Index: src/bin/scripts/common.c
===================================================================
RCS file: /opt/cvsroot_postgresql/pgsql/src/bin/scripts/common.c,v
retrieving revision 1.38
diff -c -p -c -r1.38 common.c
*** src/bin/scripts/common.c	2 Jan 2010 16:58:00 -0000	1.38
--- src/bin/scripts/common.c	30 Jan 2010 22:17:01 -0000
*************** connectDatabase(const char *dbname, cons
*** 98,103 ****
--- 98,105 ----
  	PGconn	   *conn;
  	char	   *password = NULL;
  	bool		new_pass;
+ 	const char *keywords[] = {"host","port","dbname","user",
+ 							  "password","application_name",NULL};
  
  	if (prompt_password == TRI_YES)
  		password = simple_prompt("Password: ", 100, false);
*************** connectDatabase(const char *dbname, cons
*** 108,115 ****
  	 */
  	do
  	{
  		new_pass = false;
! 		conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
  
  		if (!conn)
  		{
--- 110,127 ----
  	 */
  	do
  	{
+         const char *values[] = {
+                   pghost,
+                   pgport,
+                   dbname,
+                   pguser,
+                   password,
+                   progname,
+                   NULL
+               };
+         
  		new_pass = false;
!         conn = PQconnectdbParams(keywords, values);
  
  		if (!conn)
  		{
#2Magnus Hagander
magnus@hagander.net
In reply to: Guillaume Lelarge (#1)
Re: Using the new libpq connection functions in PostgreSQL binaries

On Sun, Jan 31, 2010 at 09:34, Guillaume Lelarge <guillaume@lelarge.info> wrote:

Hi,

I worked on a patch to make PostgreSQL binaries use the new
PQconnectdbParams() libpq functions. I tried to mimic the way Joe Conway
changed my previous patch.

I know I'm way over the deadline for this commitfest. I couldn't do it
before because my previous patch (on this commit fest) proposed two
methods to do the new connection functions (a one array method, and a
two-arrays method). Joe chose the two arrays method. Anyways, I would
understand if it gets postponed to the first commitfest for 9.1.

I think this can reasonably be seen as the final step of that patch,
rather than a completely new feature. Please add it to this CF - we
can always remove it if too many others object ;)

--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/

#3Guillaume Lelarge
guillaume@lelarge.info
In reply to: Magnus Hagander (#2)
Re: Using the new libpq connection functions in PostgreSQL binaries

Le 31/01/2010 13:39, Magnus Hagander a �crit :

On Sun, Jan 31, 2010 at 09:34, Guillaume Lelarge <guillaume@lelarge.info> wrote:

Hi,

I worked on a patch to make PostgreSQL binaries use the new
PQconnectdbParams() libpq functions. I tried to mimic the way Joe Conway
changed my previous patch.

I know I'm way over the deadline for this commitfest. I couldn't do it
before because my previous patch (on this commit fest) proposed two
methods to do the new connection functions (a one array method, and a
two-arrays method). Joe chose the two arrays method. Anyways, I would
understand if it gets postponed to the first commitfest for 9.1.

I think this can reasonably be seen as the final step of that patch,
rather than a completely new feature. Please add it to this CF - we
can always remove it if too many others object ;)

Done (https://commitfest.postgresql.org/action/patch_view?id=278). Thanks.

--
Guillaume.
http://www.postgresqlfr.org
http://dalibo.com

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Guillaume Lelarge (#1)
Re: Using the new libpq connection functions in PostgreSQL binaries

Guillaume Lelarge <guillaume@lelarge.info> writes:

*/
do
{
+         const char *values[] = {
+                   my_opts->hostname,
+                   my_opts->port,
+                   my_opts->dbname,
+                   my_opts->username,
+                   password,
+                   "oid2name",
+                   NULL
+               };
+         
new_pass = false;

Is that really legal C89 syntax? I seem to recall that array
constructors can only be used for static assignments with older
compilers.

Also, as a matter of style, I find it pretty horrid that this isn't
immediately adjacent to the keywords array that it MUST match.

regards, tom lane

#5Guillaume Lelarge
guillaume@lelarge.info
In reply to: Tom Lane (#4)
Re: Using the new libpq connection functions in PostgreSQL binaries

Le 31/01/2010 17:35, Tom Lane a �crit :

Guillaume Lelarge <guillaume@lelarge.info> writes:

*/
do
{
+         const char *values[] = {
+                   my_opts->hostname,
+                   my_opts->port,
+                   my_opts->dbname,
+                   my_opts->username,
+                   password,
+                   "oid2name",
+                   NULL
+               };
+         
new_pass = false;

Is that really legal C89 syntax?

I don't really know. gcc (4.4.1 release) didn't complain about it,
whereas it complained with a warning for not-legal-syntax when I had the
"new_pass = false;" statement before the array declaration.

I seem to recall that array
constructors can only be used for static assignments with older
compilers.

Also, as a matter of style, I find it pretty horrid that this isn't
immediately adjacent to the keywords array that it MUST match.

I don't find that horrid. AFAICT, that's the only advantage of the
two-arrays method. By the way, it's that kind of code (keywords
declaration separated from values declaration) that got commited in the
previous patch
(http://archives.postgresql.org/pgsql-committers/2010-01/msg00398.php).
I merely used the same code for the other binaries.

--
Guillaume.
http://www.postgresqlfr.org
http://dalibo.com

#6Joe Conway
mail@joeconway.com
In reply to: Guillaume Lelarge (#5)
Re: Using the new libpq connection functions in PostgreSQL binaries

On 01/31/2010 09:42 AM, Guillaume Lelarge wrote:

I don't find that horrid. AFAICT, that's the only advantage of the
two-arrays method. By the way, it's that kind of code (keywords
declaration separated from values declaration) that got commited in the
previous patch
(http://archives.postgresql.org/pgsql-committers/2010-01/msg00398.php).
I merely used the same code for the other binaries.

Yes, I separated them, because otherwise the compiler complained about
the declaration not being at the top of a block. Of course Tom's other
complaint and this one can both be satisfied by not doing the static
assignment in the declaration.

I'll fix the already committed code and take a look at refactoring this
latest patch. I stand by the two arrays mthod decision though -- I find
combining them into a single array to be unseemly.

Joe

#7Peter Eisentraut
peter_e@gmx.net
In reply to: Guillaume Lelarge (#1)
Re: Using the new libpq connection functions in PostgreSQL binaries

On sön, 2010-01-31 at 09:34 +0100, Guillaume Lelarge wrote:

I worked on a patch to make PostgreSQL binaries use the new
PQconnectdbParams() libpq functions.

Can someone dig out the patch that Heikki had started to support psql
automatically setting the client encoding? I think that's what started
this whole API revision.