pgpool2.git / summary / log / commit / refs
commit 78921f3bcbab6174af964e34cdcb371ecb73d71d
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Wed Dec 16 07:19:15 2009 +0000
Enhance "kind mismatch" message. If kind is ERROR or NOTICE, print the
ERROR/NOTICE message to help users to find what's going on.
For this pupose, add new function pool_extract_error_message() into
pool_process_query.c.
pool.h | 1 +
pool_process_query.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 121 insertions(+), 2 deletions(-)
diff --git a/pool.h b/pool.h
index 8e93b7640..d499835c2 100644
--- a/pool.h
+++ b/pool.h
@@ -668,6 +668,7 @@ extern void check_stop_request(void);
void free_select_result(POOL_SELECT_RESULT *result);
void reset_variables(void);
void per_node_statement_log(POOL_CONNECTION_POOL *backend, int node_id, char *query);
+POOL_STATUS pool_extract_error_message(POOL_CONNECTION *backend, int major, bool unread, char **message);
/* pool_relcache.c */
POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql,
diff --git a/pool_process_query.c b/pool_process_query.c
index ba94818bb..df0d387df 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -3321,8 +3321,29 @@ POOL_STATUS read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_PO
if (kind_list[i])
{
- snprintf(buf, sizeof(buf), " %d[%c]", i, kind_list[i]);
- string_append_char(msg, buf);
+
+ if (kind_list[i] == 'E' || kind_list[i] == 'N')
+ {
+ char *m;
+
+ snprintf(buf, sizeof(buf), " %d[%c: ", i, kind_list[i]);
+ string_append_char(msg, buf);
+
+ if (pool_extract_error_message(CONNECTION(backend, i), MAJOR(backend), true, &m) == POOL_CONTINUE)
+ {
+ string_append_char(msg, m);
+ string_append_char(msg, "]");
+ }
+ else
+ {
+ string_append_char(msg, "unknown message]");
+ }
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), " %d[%c]", i, kind_list[i]);
+ string_append_char(msg, buf);
+ }
}
}
@@ -4016,6 +4037,103 @@ static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, c
return is_error;
}
+/*
+ * pool_error_message: Extract human readble message from ERROR/NOTICE
+ * reponse packet and return it. Packet kind should have already been
+ * read, and it should be either 'E' or 'N'. The returned string is
+ * placed in static buffer. Message larger than the buffer will be
+ * silently truncated. Be warned that next call to this function will
+ * break the buffer. If unread is true, the packet will be returned
+ * to the stream.
+ */
+POOL_STATUS pool_extract_error_message(POOL_CONNECTION *backend, int major, bool unread, char **message)
+{
+ int readlen = 0, len;
+ static char buf[8192]; /* unread buffer */
+ static char message_buf[8192]; /* mesasge buffer */
+ char *p, *str;
+
+ p = buf;
+
+ /* read actual message */
+ if (major == PROTO_MAJOR_V3)
+ {
+ char *e;
+
+ if (pool_read(backend, &len, sizeof(len)) < 0)
+ return POOL_END;
+ readlen += sizeof(len);
+ memcpy(p, &len, sizeof(len));
+ p += sizeof(len);
+
+ len = ntohl(len) - 4;
+ str = malloc(len);
+ if (!str)
+ {
+ pool_error("pool_extract_error_message: malloc failed");
+ return POOL_END;
+ }
+
+ pool_read(backend, str, len);
+ readlen += len;
+
+ if (readlen >= sizeof(buf))
+ {
+ pool_error("pool_extract_error_message: not enough buffer space");
+ free(str);
+ return POOL_END;
+ }
+
+ memcpy(p, str, len);
+
+ /*
+ * Checks error code which is formatted 'Mxxxxxx'
+ * (xxxxxx is error message).
+ */
+ e = str;
+ while (*e)
+ {
+ if (*e == 'M')
+ {
+ e++;
+ len = Max(sizeof(message_buf)-1, strlen(e));
+ memcpy(message_buf, e, len);
+ message_buf[sizeof(message_buf)] = '\0';
+ break;
+ }
+ else
+ e = e + strlen(e) + 1;
+ }
+ free(str);
+ }
+ else
+ {
+ str = pool_read_string(backend, &len, 0);
+ len = Max(sizeof(message_buf)-1, len);
+ readlen += len;
+
+ if (readlen >= sizeof(buf))
+ {
+ pool_error("pool_extract_error_message: not enough buffer space");
+ return POOL_END;
+ }
+
+ memcpy(p, str, len);
+ memcpy(message_buf, str, len);
+ message_buf[sizeof(message_buf)] = '\0';
+ }
+
+ if (unread)
+ {
+ /* Put the message to read buffer */
+ if (pool_unread(backend, buf, readlen) != 0)
+ return POOL_END;
+ }
+
+ *message = message_buf;
+ return POOL_CONTINUE;
+}
+
/*
* read message length and rest of the packet then discard it
*/
[parent: f6f643a8e21b]