diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/auth/pool_auth.c | 85 | ||||
-rw-r--r-- | src/context/pool_query_context.c | 8 | ||||
-rw-r--r-- | src/include/pcp/libpcp_ext.h | 8 | ||||
-rw-r--r-- | src/include/pool.h | 11 | ||||
-rw-r--r-- | src/include/protocol/pool_process_query.h | 4 | ||||
-rw-r--r-- | src/include/protocol/pool_proto_modules.h | 3 | ||||
-rw-r--r-- | src/protocol/child.c | 70 | ||||
-rw-r--r-- | src/protocol/pool_process_query.c | 39 | ||||
-rw-r--r-- | src/protocol/pool_proto_modules.c | 2 | ||||
-rw-r--r-- | src/rewrite/pool_lobj.c | 4 | ||||
-rw-r--r-- | src/tools/pcp/pcp_frontend_client.c | 2 |
11 files changed, 152 insertions, 84 deletions
diff --git a/src/auth/pool_auth.c b/src/auth/pool_auth.c index 54d646bc3..198d8c99e 100644 --- a/src/auth/pool_auth.c +++ b/src/auth/pool_auth.c @@ -58,7 +58,8 @@ #define MAX_SASL_PAYLOAD_LEN 1024 -static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, int key, int protoMajor); +static void pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, + char *key, int32 keylen, int protoMajor); static int do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); static void pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp); static int do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor, @@ -92,9 +93,7 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) int length; int auth_kind; char state; - char *p; - int pid, - key; + int pid; bool keydata_done; /* @@ -244,6 +243,9 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) switch (kind) { + char *p; + int32 keylen; + case 'K': /* backend key data */ keydata_done = true; ereport(DEBUG1, @@ -251,12 +253,14 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) /* read message length */ pool_read_with_error(cp->con, &length, sizeof(length), "message length for authentication kind 'K'"); - if (ntohl(length) != 12) + length = ntohl(length); + keylen = length - sizeof(int32) - sizeof(int32); + if (keylen > MAX_CANCELKEY_LENGTH) { ereport(ERROR, (errmsg("failed to authenticate"), - errdetail("invalid backend key data length. received %d bytes when expecting 12 bytes" - ,ntohl(length)))); + errdetail("invalid backend key data length. received %d bytes exceeding %d", + ntohl(length), MAX_CANCELKEY_LENGTH))); } /* read pid */ @@ -264,9 +268,9 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) cp->pid = pid; /* read key */ - pool_read_with_error(cp->con, &key, sizeof(key), - "key for authentication kind 'K'"); - cp->key = key; + keylen = length - sizeof(int32) - sizeof(int32); + p = pool_read2(cp->con, keylen); + memcpy(cp->key, p, keylen); break; case 'Z': /* Ready for query */ @@ -332,14 +336,15 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) { signed char kind; int pid; - int key; int protoMajor; int length; int authkind; int i; int message_length = 0; StartupPacket *sp; - + int32 keylen; /* cancel key length */ + char cancel_key[MAX_CANCELKEY_LENGTH]; + char *p; protoMajor = MAIN_CONNECTION(cp)->sp->major; @@ -722,17 +727,23 @@ read_kind: } /* - * message length (V3 only) + * Read BackendKeyData message length. */ if (protoMajor == PROTO_MAJOR_V3) { - if ((length = pool_read_message_length(cp)) != 12) + length = pool_read_message_length(cp); + keylen = length - sizeof(int32) - sizeof(int32); + if (keylen > MAX_CANCELKEY_LENGTH) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid messages length(%d) for BackendKeyData", length))); + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("cancel key length exceeds 256 bytes"))); } } + else + keylen = 4; + + elog(DEBUG1, "cancel key length: %d", keylen); /* * OK, read pid and secret key @@ -758,13 +769,17 @@ read_kind: CONNECTION_SLOT(cp, i)->pid = cp->info[i].pid = pid; /* read key */ - if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0) + p = pool_read2(CONNECTION(cp, i), keylen); + if (p == NULL) { ereport(ERROR, (errmsg("authentication failed"), - errdetail("failed to read key in slot %d", i))); + errdetail("failed to read key of length: %d in slot %d", keylen, i))); } - CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key; + memcpy(CONNECTION_SLOT(cp, i)->key, p, keylen); + memcpy(cp->info[i].key, p, keylen); + memcpy(cancel_key, p, keylen); + CONNECTION_SLOT(cp, i)->keylen = cp->info[i].keylen = keylen; cp->info[i].major = sp->major; @@ -791,10 +806,13 @@ read_kind: (errmsg("authentication failed"), errdetail("pool_do_auth: all backends are down"))); } - if (pool_send_backend_key_data(frontend, pid, key, protoMajor)) - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("failed to send backend data to frontend"))); + + /* + * We send the BackendKeyData to frontend, which belongs to the last + * backend in the backend group. + */ + pool_send_backend_key_data(frontend, pid, cancel_key, + MAIN_CONNECTION(cp)->keylen, protoMajor); return 0; } @@ -872,7 +890,8 @@ pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) pool_write_and_flush(frontend, &msglen, sizeof(msglen)); /* send BackendKeyData */ - pool_send_backend_key_data(frontend, MAIN_CONNECTION(cp)->pid, MAIN_CONNECTION(cp)->key, protoMajor); + pool_send_backend_key_data(frontend, MAIN_CONNECTION(cp)->pid, MAIN_CONNECTION(cp)->key, + MAIN_CONNECTION(cp)->keylen, protoMajor); return 0; } @@ -903,29 +922,27 @@ pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) } /* - * Send backend key data to frontend. if success return 0 otherwise non 0. + * Send backend key data to frontend. */ -static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, int key, int protoMajor) +static void +pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, + char *key, int32 keylen, int protoMajor) { char kind; - int len; + int32 len; /* Send backend key data */ kind = 'K'; pool_write(frontend, &kind, 1); if (protoMajor == PROTO_MAJOR_V3) { - len = htonl(12); + len = htonl(sizeof(int32) + sizeof(int32) + keylen); pool_write(frontend, &len, sizeof(len)); } ereport(DEBUG1, - (errmsg("sending backend key data"), - errdetail("send pid %d to frontend", ntohl(pid)))); - + (errmsg("sending backend key data"))); pool_write(frontend, &pid, sizeof(pid)); - pool_write_and_flush(frontend, &key, sizeof(key)); - - return 0; + pool_write_and_flush(frontend, key, keylen); } static void diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c index 3b9028497..d398bee6d 100644 --- a/src/context/pool_query_context.c +++ b/src/context/pool_query_context.c @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2024 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -663,7 +663,8 @@ pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, CONNECTION(backend, i), MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key); + MAIN_CONNECTION(backend)->key, + MAIN_CONNECTION(backend)->keylen); /* * Check if some error detected. If so, emit log. This is useful when @@ -880,7 +881,8 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, CONNECTION(backend, i), MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key); + MAIN_CONNECTION(backend)->key, + MAIN_CONNECTION(backend)->keylen); /* * Check if some error detected. If so, emit log. This is useful diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h index d79ddc156..3a6d87858 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -137,6 +137,11 @@ typedef enum } ProcessStatus; /* + * mamimum cancel key length +*/ +#define MAX_CANCELKEY_LENGTH 256 + +/* * Connection pool information. Placed on shared memory area. */ typedef struct @@ -147,7 +152,8 @@ typedef struct int major; /* protocol major version */ int minor; /* protocol minor version */ int pid; /* backend process id */ - int key; /* cancel key */ + char key[MAX_CANCELKEY_LENGTH]; /* cancel key */ + int32 keylen; /* cancel key length */ int counter; /* used counter */ time_t create_time; /* connection creation time */ time_t client_connection_time; /* client connection time */ diff --git a/src/include/pool.h b/src/include/pool.h index 28cf1757c..c34a06d2a 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -185,7 +185,7 @@ typedef struct CancelPacket { int protoVersion; /* Protocol version */ int pid; /* backend process id */ - int key; /* cancel key */ + char key[MAX_CANCELKEY_LENGTH]; /* cancel key */ } CancelPacket; #define MAX_PASSWORD_SIZE 1024 @@ -294,7 +294,12 @@ typedef struct { StartupPacket *sp; /* startup packet info */ int pid; /* backend pid */ - int key; /* cancel key */ + char key[MAX_CANCELKEY_LENGTH]; /* cancel key */ + /* + * Cancel key length. In protocol version 3.0, it is 4. + * In 3.2 or later, the maximum length is 256. + */ + int32 keylen; POOL_CONNECTION *con; time_t closetime; /* absolute time in second when the connection * closed if 0, that means the connection is @@ -655,7 +660,7 @@ extern void pcp_main(int *fds); extern void do_child(int *fds); extern void child_exit(int code); -extern void cancel_request(CancelPacket * sp); +extern void cancel_request(CancelPacket * sp, int32 len); extern void check_stop_request(void); extern void pool_initialize_private_backend_status(void); extern int send_to_pg_frontend(char *data, int len, bool flush); diff --git a/src/include/protocol/pool_process_query.h b/src/include/protocol/pool_process_query.h index 7f91dbbcd..e799b4d9d 100644 --- a/src/include/protocol/pool_process_query.h +++ b/src/include/protocol/pool_process_query.h @@ -3,7 +3,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2020 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -35,7 +35,7 @@ extern void per_node_statement_log(POOL_CONNECTION_POOL * backend, extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION * backend, int major, bool unread, char **message); extern POOL_STATUS do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, - char *query, int protoMajor, int pid, int key, int no_ready_for_query); + char *query, int protoMajor, int pid, char *key, int keylen, int no_ready_for_query); extern void do_query(POOL_CONNECTION * backend, char *query, POOL_SELECT_RESULT * *result, int major); extern void free_select_result(POOL_SELECT_RESULT * result); extern int compare(const void *p1, const void *p2); diff --git a/src/include/protocol/pool_proto_modules.h b/src/include/protocol/pool_proto_modules.h index 663dcc984..28668aa6e 100644 --- a/src/include/protocol/pool_proto_modules.h +++ b/src/include/protocol/pool_proto_modules.h @@ -151,7 +151,8 @@ extern int RowDescription(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, short *result); -extern void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion, int pid, int key); +extern void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, + int protoVersion, int pid, char *key, int keylen); extern POOL_STATUS wait_for_query_response(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion); extern bool is_select_query(Node *node, char *sql); extern bool is_commit_query(Node *node); diff --git a/src/protocol/child.c b/src/protocol/child.c index 7aea33540..1ef88910d 100644 --- a/src/protocol/child.c +++ b/src/protocol/child.c @@ -624,14 +624,16 @@ read_startup_packet(POOL_CONNECTION * cp) len = ntohl(len); len -= sizeof(len); - if (len <= 0 || len >= MAX_STARTUP_PACKET_LENGTH) + if (len < 4 || len > MAX_STARTUP_PACKET_LENGTH) ereport(ERROR, (errmsg("failed while reading startup packet"), errdetail("incorrect packet length (%d)", len))); sp->startup_packet = palloc0(len); - /* read startup packet */ + /* + * Read startup packet except the length of the message. + */ pool_read_with_error(cp, sp->startup_packet, len, "startup packet"); @@ -861,7 +863,8 @@ connect_using_existing_connection(POOL_CONNECTION * frontend, do_command(frontend, CONNECTION(backend, i), command_buf, MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->key, + MAIN_CONNECTION(backend)->keylen, 0); } PG_CATCH(); { @@ -902,7 +905,7 @@ connect_using_existing_connection(POOL_CONNECTION * frontend, * process cancel request */ void -cancel_request(CancelPacket * sp) +cancel_request(CancelPacket * sp, int32 splen) { int len; int fd; @@ -911,8 +914,8 @@ cancel_request(CancelPacket * sp) j, k; ConnectionInfo *c = NULL; - CancelPacket cp; bool found = false; + int32 keylen; /* cancel key length */ if (pool_config->log_client_messages) ereport(LOG, @@ -921,7 +924,20 @@ cancel_request(CancelPacket * sp) ereport(DEBUG1, (errmsg("Cancel request received"))); - /* look for cancel key from shmem info */ + /* + * Cancel key length is cancel message length - cancel request code - + * process id. + */ + keylen = splen - sizeof(int32) - sizeof(int32); + + /* + * Look for cancel key from shmem info. Frontend should have saved one of + * cancel key among backend groups and sent it in the cancel request + * message. We are looking for the backend which has the same cancel key + * and pid. The query we want to cancel should have been running one the + * backend group. So some of query cancel requests may not work but it + * should not be a problem. They are just ignored by the backend. + */ for (i = 0; i < pool_config->num_init_children; i++) { for (j = 0; j < pool_config->max_pool; j++) @@ -931,14 +947,19 @@ cancel_request(CancelPacket * sp) c = pool_coninfo(i, j, k); ereport(DEBUG2, (errmsg("processing cancel request"), - errdetail("connection info: address:%p database:%s user:%s pid:%d key:%d i:%d", - c, c->database, c->user, ntohl(c->pid), ntohl(c->key), i))); - if (c->pid == sp->pid && c->key == sp->key) + errdetail("connection info: address:%p database:%s user:%s pid:%d sp.pid:%d keylen:%d sp.keylen:%d i:%d", + c, c->database, c->user, ntohl(c->pid), ntohl(sp->pid), + c->keylen, keylen, i))); + if (c->pid == sp->pid && c->keylen == keylen && + memcmp(c->key, sp->key, keylen) == 0) { ereport(DEBUG1, (errmsg("processing cancel request"), - errdetail("found pid:%d key:%d i:%d", ntohl(c->pid), ntohl(c->key), i))); + errdetail("found pid:%d keylen:%d i:%d", ntohl(c->pid), c->keylen, i))); + /* + * "c" is a pointer to i th child, j th pool, and 0 th backend. + */ c = pool_coninfo(i, j, 0); found = true; goto found; @@ -951,12 +972,19 @@ found: if (!found) { ereport(LOG, - (errmsg("invalid cancel key: pid:%d key:%d", ntohl(sp->pid), ntohl(sp->key)))); + (errmsg("invalid cancel key: pid:%d keylen:%d", ntohl(sp->pid), keylen))); return; /* invalid key */ } + /* + * We are sending cancel request message to all backend groups. So some + * of query cancel requests may not work but it should not be a + * problem. They are just ignored by the backend. + */ for (i = 0; i < NUM_BACKENDS; i++, c++) { + int32 cancel_request_code; + if (!VALID_BACKEND(i)) continue; @@ -978,18 +1006,18 @@ found: pool_set_db_node_id(con, i); - len = htonl(sizeof(len) + sizeof(CancelPacket)); - pool_write(con, &len, sizeof(len)); - - cp.protoVersion = sp->protoVersion; - cp.pid = c->pid; - cp.key = c->key; + len = htonl(splen + sizeof(int32)); /* splen does not include packet length field */ + pool_write(con, &len, sizeof(len)); /* send cancel messages length */ + cancel_request_code = htonl(PG_PROTOCOL(1234,5678)); /* cancel request code */ + pool_write(con, &cancel_request_code, sizeof(int32)); + pool_write(con, &c->pid, sizeof(int32)); /* send pid */ + pool_write(con, c->key, keylen); /* send cancel key */ ereport(LOG, - (errmsg("forwarding cancel request to backend"), - errdetail("canceling backend pid:%d key: %d", ntohl(cp.pid), ntohl(cp.key)))); + (errmsg("forwarding cancel request to backend %d", i), + errdetail("canceling backend pid: %d keylen: %d", ntohl(sp->pid), keylen))); - if (pool_write_and_flush_noerror(con, &cp, sizeof(CancelPacket)) < 0) + if (pool_flush_noerror(con) < 0) ereport(WARNING, (errmsg("failed to send cancel request to backend %d", i))); @@ -1978,7 +2006,7 @@ retry_startup: /* cancel request? */ if (sp->major == 1234 && sp->minor == 5678) { - cancel_request((CancelPacket *) sp->startup_packet); + cancel_request((CancelPacket *) sp->startup_packet, sp->len); pool_free_startup_packet(sp); connection_count_down(); return NULL; diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index cb72e9c54..5a6b97ba1 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -3,7 +3,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2024 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -512,7 +512,8 @@ send_simplequery_message(POOL_CONNECTION * backend, int len, char *string, int m */ void -wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion, int pid, int key) +wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, + int protoVersion, int pid, char *key, int keylen) { PG_TRY(); { @@ -527,8 +528,8 @@ wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONN cancel_packet.protoVersion = htonl(PROTO_CANCEL); cancel_packet.pid = pid; - cancel_packet.key = key; - cancel_request(&cancel_packet); + memcpy(cancel_packet.key, key, keylen); + cancel_request(&cancel_packet, keylen + sizeof(int32) + sizeof(int32)); } PG_RE_THROW(); @@ -1481,7 +1482,7 @@ pool_send_readyforquery(POOL_CONNECTION * frontend) */ POOL_STATUS do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, - char *query, int protoMajor, int pid, int key, int no_ready_for_query) + char *query, int protoMajor, int pid, char *key, int keylen, int no_ready_for_query) { int len; char kind; @@ -1502,7 +1503,8 @@ do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, backend, protoMajor, pid, - key); + key, + keylen); /* * We must check deadlock error here. If a deadlock error is detected by a @@ -2767,7 +2769,7 @@ insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *qu else { status = do_command(frontend, MAIN(backend), qbuf, MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); } } else if (lock_kind == 2) @@ -2825,7 +2827,7 @@ insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *qu else { status = do_command(frontend, MAIN(backend), qbuf, MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen ,0); } } } @@ -2843,7 +2845,8 @@ insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *qu { if (deadlock_detected) status = do_command(frontend, CONNECTION(backend, i), POOL_ERROR_QUERY, PROTO_MAJOR_V3, - MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); else { if (lock_kind == 1) @@ -2858,7 +2861,8 @@ insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *qu else { status = do_command(frontend, CONNECTION(backend, i), qbuf, PROTO_MAJOR_V3, - MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); } } else if (lock_kind == 2 || lock_kind == 3) @@ -2933,7 +2937,8 @@ static POOL_STATUS add_lock_target(POOL_CONNECTION * frontend, POOL_CONNECTION_P per_node_statement_log(backend, MAIN_NODE_ID, "LOCK TABLE pgpool_catalog.insert_lock IN SHARE ROW EXCLUSIVE MODE"); if (do_command(frontend, MAIN(backend), "LOCK TABLE pgpool_catalog.insert_lock IN SHARE ROW EXCLUSIVE MODE", - PROTO_MAJOR_V3, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 0) != POOL_CONTINUE) + PROTO_MAJOR_V3, MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0) != POOL_CONTINUE) ereport(ERROR, (errmsg("unable to add lock target"), errdetail("do_command returned DEADLOCK status"))); @@ -3043,7 +3048,8 @@ static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION * frontend, per_node_statement_log(backend, MAIN_NODE_ID, qbuf); status = do_command(frontend, MAIN(backend), qbuf, PROTO_MAJOR_V3, - MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); return status; } @@ -4140,7 +4146,8 @@ start_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * ba per_node_statement_log(backend, i, "BEGIN"); if (do_command(frontend, CONNECTION(backend, i), "BEGIN", MAJOR(backend), - MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 0) != POOL_CONTINUE) + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0) != POOL_CONTINUE) ereport(ERROR, (errmsg("unable to start the internal transaction"), errdetail("do_command returned DEADLOCK status"))); @@ -4205,7 +4212,8 @@ end_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * back PG_TRY(); { if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), - MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 1) != POOL_CONTINUE) + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 1) != POOL_CONTINUE) { ereport(ERROR, (errmsg("unable to COMMIT the transaction"), @@ -4258,7 +4266,8 @@ end_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * back PG_TRY(); { if (do_command(frontend, MAIN(backend), "COMMIT", MAJOR(backend), - MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, 1) != POOL_CONTINUE) + MAIN_CONNECTION(backend)->pid, + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 1) != POOL_CONTINUE) { ereport(ERROR, (errmsg("unable to COMMIT the transaction"), diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c index a6336f8e2..c2802998a 100644 --- a/src/protocol/pool_proto_modules.c +++ b/src/protocol/pool_proto_modules.c @@ -2490,7 +2490,7 @@ static POOL_STATUS close_standby_transactions(POOL_CONNECTION * frontend, per_node_statement_log(backend, i, "COMMIT"); if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key, 0) != POOL_CONTINUE) + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0) != POOL_CONTINUE) ereport(ERROR, (errmsg("unable to close standby transactions"), errdetail("do_command returned DEADLOCK status"))); diff --git a/src/rewrite/pool_lobj.c b/src/rewrite/pool_lobj.c index 38187fe14..7601a9316 100644 --- a/src/rewrite/pool_lobj.c +++ b/src/rewrite/pool_lobj.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2010 PgPool Global Development Group + * Copyright (c) 2003-2025 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -174,7 +174,7 @@ pool_rewrite_lo_creat(char kind, char *packet, int packet_len, snprintf(qbuf, sizeof(qbuf), "LOCK TABLE %s IN SHARE ROW EXCLUSIVE MODE", pool_config->lobj_lock_table); per_node_statement_log(backend, MAIN_NODE_ID, qbuf); status = do_command(frontend, MAIN(backend), qbuf, MAJOR(backend), MAIN_CONNECTION(backend)->pid, - MAIN_CONNECTION(backend)->key, 0); + MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); if (status == POOL_END) { ereport(WARNING, diff --git a/src/tools/pcp/pcp_frontend_client.c b/src/tools/pcp/pcp_frontend_client.c index be192dd27..ecc922b93 100644 --- a/src/tools/pcp/pcp_frontend_client.c +++ b/src/tools/pcp/pcp_frontend_client.c @@ -751,7 +751,7 @@ output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose) format = format_titles(titles, types, sizeof(titles)/sizeof(char *)); else { - format = "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n"; + format = "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n"; } for (i = 0; i < array_size; i++) |