From 8258b05a51ad30dd05d404c562be2b78aec26fdc Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Sun, 12 Aug 2007 13:32:20 +0000 Subject: [PATCH] add server vars to SHOW FDS, relax result parsing --- src/admin.c | 30 +++++++++++++++++++++-------- src/objects.c | 18 ++++++++++++++++-- src/objects.h | 6 ++++-- src/proto.c | 51 +++++++++++++++++++++++++++++--------------------- src/takeover.c | 19 ++++++++++++------- 5 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/admin.c b/src/admin.c index 6677c9d..c9c7ded 100644 --- a/src/admin.c +++ b/src/admin.c @@ -152,7 +152,11 @@ static bool send_one_fd(PgSocket *admin, 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; @@ -162,8 +166,9 @@ static bool send_one_fd(PgSocket *admin, 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; @@ -205,6 +210,7 @@ static bool show_one_fd(PgSocket *admin, PgSocket *sk) { PgAddr *addr = &sk->addr; MBuf tmp; + VarCache *v = &sk->vars; mbuf_init(&tmp, sk->cancel_key, 8); @@ -215,7 +221,11 @@ static bool show_one_fd(PgSocket *admin, PgSocket *sk) 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 */ @@ -228,10 +238,12 @@ static bool show_pooler_fds(PgSocket *admin) 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; } @@ -278,11 +290,13 @@ static bool admin_show_fds(PgSocket *admin, const char *arg) /* * 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); diff --git a/src/objects.c b/src/objects.c index d9ccad8..42c33ff 100644 --- a/src/objects.c +++ b/src/objects.c @@ -928,7 +928,9 @@ void forward_cancel_request(PgSocket *server) 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; @@ -950,12 +952,19 @@ bool use_client_socket(int fd, PgAddr *addr, 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; @@ -1000,6 +1009,11 @@ bool use_server_socket(int fd, PgAddr *addr, 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; } diff --git a/src/objects.h b/src/objects.h index bf862fb..ac421e1 100644 --- a/src/objects.h +++ b/src/objects.h @@ -44,8 +44,10 @@ void forward_cancel_request(PgSocket *server); 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); diff --git a/src/proto.c b/src/proto.c index 3ac9f56..1da40f5 100644 --- a/src/proto.c +++ b/src/proto.c @@ -320,36 +320,45 @@ int scan_text_result(MBuf *pkt, const char *tupdesc, ...) 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; } diff --git a/src/takeover.c b/src/takeover.c index 745e7f8..4599897 100644 --- a/src/takeover.c +++ b/src/takeover.c @@ -44,7 +44,9 @@ static bool takeover_load_fd(MBuf *pkt, const struct cmsghdr *cmsg) { 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; @@ -61,15 +63,16 @@ static bool takeover_load_fd(MBuf *pkt, const struct cmsghdr *cmsg) 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; @@ -82,9 +85,11 @@ static bool takeover_load_fd(MBuf *pkt, const struct cmsghdr *cmsg) /* 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 -- 2.40.0