int fd, const char *task,
const char *user, const char *db,
const char *addr, int port,
- uint64 ckey, int link)
+ uint64 ckey, int link,
+ const char *client_enc,
+ const char *std_strings,
+ const char *datestyle,
+ const char *timezone)
{
struct msghdr msg;
struct cmsghdr *cmsg;
uint8 cntbuf[CMSG_SPACE(sizeof(int))];
iovec.iov_base = pktbuf;
- BUILD_DataRow(res, pktbuf, sizeof(pktbuf), "issssiqi",
- fd, task, user, db, addr, port, ckey, link);
+ BUILD_DataRow(res, pktbuf, sizeof(pktbuf), "issssiqissss",
+ fd, task, user, db, addr, port, ckey, link,
+ client_enc, std_strings, datestyle, timezone);
if (res < 0)
return false;
iovec.iov_len = res;
{
PgAddr *addr = &sk->addr;
MBuf tmp;
+ VarCache *v = &sk->vars;
mbuf_init(&tmp, sk->cancel_key, 8);
addr->is_unix ? "unix" : inet_ntoa(addr->ip_addr),
addr->port,
mbuf_get_uint64(&tmp),
- sk->link ? sbuf_socket(&sk->link->sbuf) : 0);
+ sk->link ? sbuf_socket(&sk->link->sbuf) : 0,
+ v->client_encoding[0] ? v->client_encoding : NULL,
+ v->std_strings[0] ? v->std_strings : NULL,
+ v->datestyle[0] ? v->datestyle : NULL,
+ v->timezone[0] ? v->timezone : NULL);
}
/* send a row with sendmsg, optionally attaching a fd */
if (fd_net)
res = send_one_fd(admin, fd_net, "pooler", NULL, NULL,
- cf_listen_addr, cf_listen_port, 0, 0);
+ cf_listen_addr, cf_listen_port, 0, 0,
+ NULL, NULL, NULL, NULL);
if (fd_unix && res)
res = send_one_fd(admin, fd_unix, "pooler", NULL, NULL,
- "unix", cf_listen_port, 0, 0);
+ "unix", cf_listen_port, 0, 0,
+ NULL, NULL, NULL, NULL);
return res;
}
/*
* send resultset
*/
- SEND_RowDescription(res, admin, "issssiqi",
+ SEND_RowDescription(res, admin, "issssiqissss",
"fd", "task",
"user", "database",
"addr", "port",
- "cancel", "link");
+ "cancel", "link",
+ "client_encoding", "std_strings",
+ "datestyle", "timezone");
if (res)
res = show_pooler_fds(admin);
bool use_client_socket(int fd, PgAddr *addr,
const char *dbname, const char *username,
- uint64 ckey, int oldfd, int linkfd)
+ uint64 ckey, int oldfd, int linkfd,
+ const char *client_enc, const char *std_string,
+ const char *datestyle, const char *timezone)
{
PgSocket *client;
PktBuf tmp;
client->tmp_sk_oldfd = oldfd;
client->tmp_sk_linkfd = linkfd;
+ varcache_set(&client->vars, "client_encoding", client_enc, true);
+ varcache_set(&client->vars, "standard_conforming_strings", std_string, true);
+ varcache_set(&client->vars, "datestyle", datestyle, true);
+ varcache_set(&client->vars, "timezone", timezone, true);
+
return true;
}
bool use_server_socket(int fd, PgAddr *addr,
const char *dbname, const char *username,
- uint64 ckey, int oldfd, int linkfd)
+ uint64 ckey, int oldfd, int linkfd,
+ const char *client_enc, const char *std_string,
+ const char *datestyle, const char *timezone)
{
PgDatabase *db = find_database(dbname);
PgUser *user;
server->tmp_sk_oldfd = oldfd;
server->tmp_sk_linkfd = linkfd;
+ varcache_set(&server->vars, "client_encoding", client_enc, true);
+ varcache_set(&server->vars, "standard_conforming_strings", std_string, true);
+ varcache_set(&server->vars, "datestyle", datestyle, true);
+ varcache_set(&server->vars, "timezone", timezone, true);
+
return true;
}
void launch_new_connection(PgPool *pool);
-bool use_client_socket(int fd, PgAddr *addr, const char *dbname, const char *username, uint64 ckey, int oldfd, int linkfd);
-bool use_server_socket(int fd, PgAddr *addr, const char *dbname, const char *username, uint64 ckey, int oldfd, int linkfd);
+bool use_client_socket(int fd, PgAddr *addr, const char *dbname, const char *username, uint64 ckey, int oldfd, int linkfd,
+ const char *client_end, const char *std_string, const char *datestyle, const char *timezone);
+bool use_server_socket(int fd, PgAddr *addr, const char *dbname, const char *username, uint64 ckey, int oldfd, int linkfd,
+ const char *client_end, const char *std_string, const char *datestyle, const char *timezone);
void pause_client(PgSocket *client);
void activate_client(PgSocket *client);
int len;
unsigned ncol, i;
va_list ap;
+ int asked;
+ int *int_p;
+ uint64 *long_p;
+ char **str_p;
+ asked = strlen(tupdesc);
ncol = mbuf_get_uint16(pkt);
- if (ncol != strlen(tupdesc))
- fatal("different number of cols");
va_start(ap, tupdesc);
- for (i = 0; i < ncol; i++) {
- len = mbuf_get_uint32(pkt);
- if (len < 0)
- val = NULL;
- else
- val = (char *)mbuf_get_bytes(pkt, len);
-
- if (tupdesc[i] == 'i') {
- int *dst_p = va_arg(ap, int *);
- *dst_p = atoi(val);
- } else if (tupdesc[i] == 'q') {
- uint64 *dst_p = va_arg(ap, uint64 *);
- *dst_p = atoll(val);
- } else if (tupdesc[i] == 's') {
- char **dst_p = va_arg(ap, char **);
- *dst_p = val;
+ for (i = 0; i < asked; i++) {
+ if (i < ncol) {
+ len = mbuf_get_uint32(pkt);
+ if (len < 0)
+ val = NULL;
+ else
+ val = (char *)mbuf_get_bytes(pkt, len);
} else
+ /* tuple was shorter than requested */
+ val = NULL;
+
+ switch (tupdesc[i]) {
+ case 'i':
+ int_p = va_arg(ap, int *);
+ *int_p = atoi(val);
+ break;
+ case 'q':
+ long_p = va_arg(ap, uint64 *);
+ *long_p = atoll(val);
+ break;
+ case 's':
+ str_p = va_arg(ap, char **);
+ *str_p = val;
+ break;
+ default:
fatal("bad tupdesc: %s", tupdesc);
+ }
}
va_end(ap);
- if (mbuf_avail(pkt))
- fatal("scan_text_result: unparsed data");
-
return ncol;
}
{
int fd;
char *task, *s_addr, *user, *db;
+ char *client_enc, *std_string, *datestyle, *timezone;
int oldfd, port, linkfd;
+ int got;
uint64 ckey;
PgAddr addr;
fatal("broken fd packet");
/* parse row contents */
- scan_text_result(pkt, "issssiqi", &oldfd, &task, &user, &db,
- &s_addr, &port, &ckey, &linkfd);
+ got = scan_text_result(pkt, "issssiqissss", &oldfd, &task, &user, &db,
+ &s_addr, &port, &ckey, &linkfd,
+ &client_enc, &std_string, &datestyle, &timezone);
if (task == NULL || s_addr == NULL)
fatal("NULL data from old process");
- log_debug("FD row: fd=%d(%d) linkfd=%d task=%s user=%s db=%s",
+ log_debug("FD row: fd=%d(%d) linkfd=%d task=%s user=%s db=%s enc=%s",
oldfd, fd, linkfd, task,
- user ? user : "NULL",
- db ? db : "NULL");
+ user ? user : "NULL", db ? db : "NULL",
+ client_enc ? client_enc : "NULL");
/* fill address */
addr.is_unix = strcmp(s_addr, "unix") == 0 ? true : false;
/* decide what to do with it */
if (strcmp(task, "client") == 0)
- use_client_socket(fd, &addr, db, user, ckey, oldfd, linkfd);
+ use_client_socket(fd, &addr, db, user, ckey, oldfd, linkfd,
+ client_enc, std_string, datestyle, timezone);
else if (strcmp(task, "server") == 0)
- use_server_socket(fd, &addr, db, user, ckey, oldfd, linkfd);
+ use_server_socket(fd, &addr, db, user, ckey, oldfd, linkfd,
+ client_enc, std_string, datestyle, timezone);
else if (strcmp(task, "pooler") == 0)
use_pooler_socket(fd, addr.is_unix);
else