Re: [HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
From: "Michael Meskes" However, I'd prefer to solve the problem slightly differently by not creating an empty host variable instead of checking for it after the fact. But I take it you don't mind that. Fixed in HEAD and all back branches. Thanks for the report. Thank you for committing the fix. I'm comfortable with your change. Regards MauMau -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
On Sun, Dec 29, 2013 at 05:35:22AM +0900, MauMau wrote: > Your test case seems different from my original mail. In my test As it turned out that wasn't the problem. It was simple typo on my side. Sorry for the hassle. However, I'd prefer to solve the problem slightly differently by not creating an empty host variable instead of checking for it after the fact. But I take it you don't mind that. Fixed in HEAD and all back branches. Thanks for the report. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org Jabber: michael.meskes at gmail dot com VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
From: "Michael Meskes" Or in other words, I used the connect command you had in your email with a services file pointing to a local database and it connected to that database. Instead of adding an additional output I checked the log output which suggested that host was NULL. Your test case seems different from my original mail. In my test case, I want to connect to a database on another machine, not on the local one. For example: 1. The ECPG app runs on a machine called client-host. 2. The database server to connect to runs on a machine called server-host. 3. There's no database server running on client-host. 4. The ECPG app uses the connection service file whose contents is: [my_service] host=server-host ... other necessary parameters like port, dbname, etc. The app mistakenly tries to connect to the database server on the local machine (client-host), instead of the desired server-host, and fails to connect because the database server is not running on client-host. This is because ECPGconnect() passes an empty string (""), not NULL, to PQconnectdbParams(). Regards MauMau -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
On Sat, Dec 28, 2013 at 04:37:44PM +0900, MauMau wrote: > You can confirm it by adding the following code fragment to > ecpglib/connect.c. The attached file contains this. > ... Sorry for not being precide enough. I did run some tests and it works like a charm for me. Or in other words, I used the connect command you had in your email with a services file pointing to a local database and it connected to that database. Instead of adding an additional output I checked the log output which suggested that host was NULL. While I cannot see how your patch could do any harm, I'd still like to figure out why I don't see the same behaviour. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org Jabber: michael.meskes at gmail dot com VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
From: "Michael Meskes" On Tue, Dec 17, 2013 at 09:26:49PM +0900, MauMau wrote: [Problem] The ECPG app runs the statement: EXEC SQL CONNECT TO 'tcp:postgresql://?service=my_service'; ... ECPGconnect() parses the URI and produces an empty host name. It passes an empty string as the value for "host" connection parameter to PQconnectdbParams(). Interestingly enough it works flawlessly on my system. Any idea where the empoty host name comes from? Before accepting the patch I'd like to find out why you got an empty host variable and I don't. You can confirm it by adding the following code fragment to ecpglib/connect.c. The attached file contains this. if (host) printf("host=%s\n", host); else printf("host=NULL\n"); Build and run the attached sample program like this (this is an example on Windows, but the result should be the same on Linux): ecpg connect.pgc cl /nologo /MD /I\include connect.c /link /libpath:\lib libecpg.lib connect.exe The added code in ecpglib/connect.c displays "host=", which shows that an empty host is passed to PQconnectdbParams(). Of course, on Linux, you can use gdb to run the sample program, set a breakpoint at PQconnectDbParams(), and display the keywords/values arrays of the argument. An empty string is set to the host local variable at line 430 in ecpglib/connect.c (this line number is that of PostgreSQL 9.4). That is the else block shown below: if (strncmp(dbname, "unix:", 5) == 0) { ... } else { host = ecpg_strdup(dbname + offset, lineno); connect_params++; } Regards MauMau connect.pgc Description: Binary data /* src/interfaces/ecpg/ecpglib/connect.c */ #define POSTGRES_ECPG_INTERNAL #include "postgres_fe.h" #include "ecpg-pthread-win32.h" #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" #include "extern.h" #include "sqlca.h" #ifdef ENABLE_THREAD_SAFETY static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t actual_connection_key; static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT; #endif static struct connection *actual_connection = NULL; static struct connection *all_connections = NULL; #ifdef ENABLE_THREAD_SAFETY static void ecpg_actual_connection_init(void) { pthread_key_create(&actual_connection_key, NULL); } void ecpg_pthreads_init(void) { pthread_once(&actual_connection_key_once, ecpg_actual_connection_init); } #endif static struct connection * ecpg_get_connection_nr(const char *connection_name) { struct connection *ret = NULL; if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0)) { #ifdef ENABLE_THREAD_SAFETY ret = pthread_getspecific(actual_connection_key); /* * if no connection in TSD for this thread, get the global default * connection and hope the user knows what they're doing (i.e. using * their own mutex to protect that connection from concurrent accesses */ /* if !ret then we got the connection from TSD */ if (NULL == ret) /* no TSD connection, going for global */ ret = actual_connection; #else ret = actual_connection; #endif } else { struct connection *con; for (con = all_connections; con != NULL; con = con->next) { if (strcmp(connection_name, con->name) == 0) break; } ret = con; } return (ret); } struct connection * ecpg_get_connection(const char *connection_name) { struct connection *ret = NULL; if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0)) { #ifdef ENABLE_THREAD_SAFETY ret = pthread_getspecific(actual_connection_key); /* * if no connection in TSD for this thread, get the global default * connection and hope the user knows what they're doing (i.e. using * their own mutex to protect that connection from concurrent accesses */ /* if !ret then we got the connection from TSD */ if (NULL == ret) /* no TSD connection here either, using global */ ret = actual_connection; #else ret = actual_connection; #endif } else { #ifdef ENABLE_THREAD_SAFETY pthread_mutex_lock(&connections_mutex); #endif ret = ecpg_get_connection_nr(connection_name); #ifdef ENABLE_THREAD_SAFETY pthread_mutex_unlock(&connections_mutex); #endif } return (ret); } static void ecpg_finish(struct connection * act) { if (act != NULL) { struct ECPGtype_information_cache *
Re: [HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
On Tue, Dec 17, 2013 at 09:26:49PM +0900, MauMau wrote: > [Problem] > The ECPG app runs the statement: > > EXEC SQL CONNECT TO 'tcp:postgresql://?service=my_service'; > ... > ECPGconnect() parses the URI and produces an empty host name. It > passes an empty string as the value for "host" connection parameter > to PQconnectdbParams(). Interestingly enough it works flawlessly on my system. Any idea where the empoty host name comes from? Before accepting the patch I'd like to find out why you got an empty host variable and I don't. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org Jabber: michael.meskes at gmail dot com VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] [bug fix] connection service file doesn't take effect with ECPG apps
Hello, I've found a small bug of ECPG and attached a patch. I tested the fix with 9.4. I'd like the fix to be back-ported. [Problem] The ECPG app runs the statement: EXEC SQL CONNECT TO 'tcp:postgresql://?service=my_service'; I want this app to connect to any database based on the connection service file. For example, I wrote the following connection service file pg_service.conf, placed it in the current directory, set PGSERVICEFILE environment variable to point to it: [my_service] dbname = mydb host = myhost port = myhost is a different host than the one where the app runs. Unfortunately, the app could not connect to the intended database. It tried to connect to the (non-existent) database server on the local machine and failed. [Cause] ECPGconnect() parses the URI and produces an empty host name. It passes an empty string as the value for "host" connection parameter to PQconnectdbParams(). Given an empty host name, PQconnectdbParams() ignores the host parameter in pg_service.conf. When host is "", PQconnectdbParams() try to connect via local UNIX domain socket. [Fix] It doesn't make sense for ECPGconnect() to pass an empty host name to PQconnectdbParams(), so prevent it from passing host parameter for the service setting to take effect. port is the same. Regards MauMau ecpg_service.patch Description: Binary data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers