*** pool.h.orig 2010-02-03 17:11:42.000000000 +0900 --- pool.h 2010-02-26 16:40:16.000000000 +0900 *************** *** 118,123 **** --- 118,124 ---- int minor; /* protocol minor version */ char *database; /* database name in startup_packet (malloced area) */ char *user; /* user name in startup_packet (malloced area) */ + char *client_encoding; /* client_encoding in startup_packet (malloced area) */ } StartupPacket; typedef struct CancelPacket *************** *** 644,650 **** extern POOL_STATUS OneNode_do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, char *query, char *database); extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( ! char *hostname, int port, char *dbname, char *user, char *password); /* define pool_system.c */ extern POOL_CONNECTION_POOL_SLOT *pool_system_db_connection(void); --- 645,651 ---- extern POOL_STATUS OneNode_do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, char *query, char *database); extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( ! char *hostname, int port, char *dbname, char *user, char *password, StartupPacket *sp); /* define pool_system.c */ extern POOL_CONNECTION_POOL_SLOT *pool_system_db_connection(void); *** child.c.orig 2010-02-01 18:05:20.000000000 +0900 --- child.c 2010-03-09 10:05:17.000000000 +0900 *************** *** 133,158 **** gettimeofday(&now, &tz); srandom((unsigned int) now.tv_usec); - /* initialize systemdb connection */ - if (pool_config->parallel_mode || pool_config->enable_query_cache) - { - system_db_connect(); - if (PQstatus(system_db_info->pgconn) != CONNECTION_OK) - { - pool_error("Could not make persistent libpq system DB connection"); - } - - system_db_info->connection = make_persistent_db_connection(pool_config->system_db_hostname, - pool_config->system_db_port, - pool_config->system_db_dbname, - pool_config->system_db_user, - pool_config->system_db_password); - if (system_db_info->connection == NULL) - { - pool_error("Could not make persistent system DB connection"); - } - } - /* initialize connection pool */ if (pool_init_cp()) { --- 133,138 ---- *************** *** 268,273 **** --- 248,288 ---- * Ok, negotiaton with frontend has been done. Let's go to the next step. */ + + /* initialize systemdb connection */ + if (pool_config->parallel_mode || pool_config->enable_query_cache) + { + if (! system_db_info->pgconn) + system_db_connect(); + if (PQstatus(system_db_info->pgconn) != CONNECTION_OK) + { + pool_error("Could not make persistent libpq system DB connection"); + } + + if (system_db_info->connection && + strcmp(sp->client_encoding,system_db_info->connection->sp->client_encoding)) + { + pool_debug("client_encoding: frontend:%s systemdb:%s",sp->client_encoding,system_db_info->connection->sp->client_encoding); + pool_free_startup_packet(system_db_info->connection->sp); + pool_close(system_db_info->connection->con); + if (system_db_info->connection) + free(system_db_info->connection); + system_db_info->connection = NULL; + } + + if (! system_db_info->connection) + system_db_info->connection = make_persistent_db_connection(pool_config->system_db_hostname, + pool_config->system_db_port, + pool_config->system_db_dbname, + pool_config->system_db_user, + pool_config->system_db_password, + sp); + if (system_db_info->connection == NULL) + { + pool_error("Could not make persistent system DB connection"); + } + } + /* * if there's no connection associated with user and database, * we need to connect to the backend and send the startup packet. *************** *** 1002,1009 **** --- 1017,1039 ---- return NULL; } } + else if (!strcmp("client_encoding", p)) + { + p += (strlen(p) + 1); + sp->client_encoding = strdup(p); + if (!sp->client_encoding) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + alarm(0); + pool_signal(SIGALRM, SIG_IGN); + return NULL; + } + } p += (strlen(p) + 1); } + if (! sp->client_encoding) + sp->client_encoding = calloc(1, 1); break; case 1234: /* cancel or SSL request */ *************** *** 1026,1031 **** --- 1056,1070 ---- pool_signal(SIGALRM, SIG_IGN); return NULL; } + sp->client_encoding = calloc(1, 1); + if (!sp->client_encoding) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + alarm(0); + pool_signal(SIGALRM, SIG_IGN); + return NULL; + } break; default: *************** *** 1332,1337 **** --- 1371,1378 ---- free(sp->database); if (sp->user) free(sp->user); + if (sp->client_encoding) + free(sp->client_encoding); free(sp); } } *************** *** 1364,1373 **** * create a persistent connection */ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( ! char *hostname, int port, char *dbname, char *user, char *password) { POOL_CONNECTION_POOL_SLOT *cp; int fd; #define MAX_USER_AND_DATABASE 1024 --- 1405,1415 ---- * create a persistent connection */ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( ! char *hostname, int port, char *dbname, char *user, char *password, StartupPacket *sp) { POOL_CONNECTION_POOL_SLOT *cp; int fd; + char *p, *client_encoding; #define MAX_USER_AND_DATABASE 1024 *************** *** 1436,1442 **** len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "database") + 1; if (len1 >= (sizeof(startup_packet->data)-len)) { ! pool_error("make_persistent_db_connection: too long user name"); return NULL; } --- 1478,1484 ---- len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "database") + 1; if (len1 >= (sizeof(startup_packet->data)-len)) { ! pool_error("make_persistent_db_connection: too long database"); return NULL; } *************** *** 1447,1452 **** --- 1489,1518 ---- pool_error("make_persistent_db_connection: too long database name"); return NULL; } + + p = sp->startup_packet; + p += sizeof(int); /* skip protocol version info */ + client_encoding = NULL; + while(*p) + { + if (!strcmp("client_encoding", p)) { + client_encoding = p + (strlen(p) + 1); + break; + } + p += (strlen(p) + 1); + } + + if (client_encoding) { + len += len1; + len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "client_encoding") + 1; + len1+= snprintf(&startup_packet->data[len+len1], sizeof(startup_packet->data)-len+len1, "%s", client_encoding) + 1; + if (len1 >= (sizeof(startup_packet->data)-len)) + { + pool_error("make_persistent_db_connection: too long option(client_encoding)"); + return NULL; + } + } + len += len1; startup_packet->data[len++] = '\0'; *************** *** 1473,1478 **** --- 1539,1554 ---- pool_error("make_persistent_db_connection: could not allocate memory"); return NULL; } + if (client_encoding) { + cp->sp->client_encoding = strdup(client_encoding); + if (cp->sp->client_encoding == NULL) + { + pool_error("make_persistent_db_connection: could not allocate memory"); + return NULL; + } + } else { + cp->sp->client_encoding = calloc(1,1); + } /* * send startup packet