From b7ea1b05fdcd31a5aaad78318c8393f6252937ad Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sat, 10 Oct 2026 16:47:10 +0900 Subject: [PATCH v3 1/2] Reject v2 protocol startup packet. If v2 frontend connects, raise a FATAL error. Remove all v2 protocol branches except some codes in elog.c throwing v2 error messages. Author: Tatsuo Ishii Reviewed-by: Nadav Shatz Discussion: https://www.postgresql.org/message-id/20260625.151428.1666276852188903568.ishii%40postgresql.org Backpatch-through: master only --- src/Makefile.am | 1 - src/auth/pool_auth.c | 344 ++--- src/context/pool_query_context.c | 6 +- src/context/pool_session_context.c | 2 +- src/include/protocol/pool_process_query.h | 18 +- src/include/protocol/pool_proto_modules.h | 22 +- src/protocol/CommandComplete.c | 4 +- src/protocol/child.c | 32 +- src/protocol/pool_process_query.c | 1122 ++++++----------- src/protocol/pool_proto2.c | 741 ----------- src/protocol/pool_proto_modules.c | 727 +++++------ src/query_cache/pool_memqcache.c | 2 +- src/rewrite/pool_lobj.c | 6 +- src/rewrite/pool_timestamp.c | 4 +- src/streaming_replication/pool_worker_child.c | 2 +- src/utils/error/elog.c | 23 +- src/utils/pool_process_reporting.c | 373 ++---- src/utils/pool_relcache.c | 2 +- 18 files changed, 976 insertions(+), 2455 deletions(-) delete mode 100644 src/protocol/pool_proto2.c diff --git a/src/Makefile.am b/src/Makefile.am index 39588af58..525b9a135 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,6 @@ pgpool_SOURCES = main/main.c \ auth/pool_passwd.c \ auth/pool_hba.c \ auth/auth-scram.c \ - protocol/pool_proto2.c \ protocol/child.c \ protocol/pool_pg_utils.c \ protocol/pool_process_query.c \ diff --git a/src/auth/pool_auth.c b/src/auth/pool_auth.c index 95d12d9e2..24cd528ed 100644 --- a/src/auth/pool_auth.c +++ b/src/auth/pool_auth.c @@ -59,22 +59,22 @@ 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); + char *key, int32 keylen); +static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth); 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, +static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, char *storedPassword, PasswordType passwordType); -static void send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt); -static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize); -static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password); -static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor); -static void sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen); +static void send_md5auth_request(POOL_CONNECTION *frontend, char *salt); +static int read_password_packet(POOL_CONNECTION *frontend, char *password, int *pwdSize); +static int send_password_packet(POOL_CONNECTION *backend, char *password); +static int send_auth_ok(POOL_CONNECTION *frontend); +static void sendAuthRequest(POOL_CONNECTION *frontend, int32 auth_req_type, char *extradata, int extralen); static int pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void *sasl_state, bool final); static void *pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *username, char *storedPassword); -static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoMajor, int message_length, +static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int message_length, char *username, char *storedPassword, PasswordType passwordType); -static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); +static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth); static void authenticate_frontend_cert(POOL_CONNECTION *frontend); static void authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth); static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend); @@ -111,7 +111,7 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) if (kind == 'E' || kind == 'N') { - sts = pool_extract_error_message(false, cp->con, cp->sp->major, false, &msg); + sts = pool_extract_error_message(false, cp->con, false, &msg); } if (sts == 1) /* succeeded in extracting error/notice @@ -146,7 +146,7 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) } else if (auth_kind == AUTH_REQ_PASSWORD) /* clear text password? */ { - kind = send_password_packet(cp->con, PROTO_MAJOR_V3, password); + kind = send_password_packet(cp->con, password); if (kind != AUTH_REQ_OK) ereport(ERROR, (errmsg("password authentication failed for user:%s", cp->sp->user), @@ -169,7 +169,7 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) errdetail("failed to encrypt the password"))); /* Send password packet to backend and receive auth response */ - kind = send_password_packet(cp->con, PROTO_MAJOR_V3, crypt_password); + kind = send_password_packet(cp->con, crypt_password); if (kind != AUTH_REQ_OK) ereport(ERROR, (errmsg("crypt authentication failed for user:%s", cp->sp->user), @@ -203,7 +203,7 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) memcpy(buf, "md5", 3); /* Send password packet to backend and receive auth response */ - kind = send_password_packet(cp->con, PROTO_MAJOR_V3, buf); + kind = send_password_packet(cp->con, buf); pfree(buf); if (kind != AUTH_REQ_OK) ereport(ERROR, @@ -214,7 +214,7 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) } else if (auth_kind == AUTH_REQ_SASL) { - if (do_SCRAM(NULL, cp->con, PROTO_MAJOR_V3, length, cp->sp->user, password, PASSWORD_TYPE_PLAINTEXT) == false) + if (do_SCRAM(NULL, cp->con, length, cp->sp->user, password, PASSWORD_TYPE_PLAINTEXT) == false) { ereport(ERROR, (errmsg("failed to authenticate with backend"), @@ -338,7 +338,6 @@ pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { signed char kind; int pid; - int protoMajor; int length; int authkind; int i; @@ -348,8 +347,6 @@ pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) char cancel_key[MAX_CANCELKEY_LENGTH]; char *p; - protoMajor = MAIN_CONNECTION(cp)->sp->major; - read_kind: kind = pool_read_kind(cp); if (kind < 0) @@ -360,19 +357,9 @@ read_kind: /* error response? */ if (kind == 'E') { - /* - * we assume error response at this stage is likely version protocol - * mismatch (v3 frontend vs. v2 backend). So we throw a V2 protocol - * error response in the hope that v3 frontend will negotiate again - * using v2 protocol. - */ - - ErrorResponse(frontend, cp); - ereport(ERROR, (errmsg("backend authentication failed"), - errdetail("backend response with kind \'E\' when expecting \'R\'"), - errhint("This issue can be caused by version mismatch (current version %d)", protoMajor))); + errdetail("backend response with kind \'E\' when expecting \'R\'"))); } else if (kind == 'v') { @@ -386,19 +373,16 @@ read_kind: errdetail("backend response with kind \'%c\' when expecting \'R\'", kind))); /* - * message length (v3 only) + * message length */ - if (protoMajor == PROTO_MAJOR_V3) - { - message_length = pool_read_message_length(cp); - if (message_length <= 0) - ereport(ERROR, - (errmsg("invalid authentication packet from backend"), - errdetail("failed to get the authentication packet length"), - errhint("This is likely caused by the inconsistency of auth method among DB nodes. \ + message_length = pool_read_message_length(cp); + if (message_length <= 0) + ereport(ERROR, + (errmsg("invalid authentication packet from backend"), + errdetail("failed to get the authentication packet length"), + errhint("This is likely caused by the inconsistency of auth method among DB nodes. \ Please check the previous error messages (hint: length field) \ from pool_read_message_length and recheck the pg_hba.conf settings."))); - } /*------------------------------------------------------------------------- * read authentication request kind. @@ -435,11 +419,8 @@ read_kind: pool_write(frontend, "R", 1); - if (protoMajor == PROTO_MAJOR_V3) - { - msglen = htonl(8); - pool_write(frontend, &msglen, sizeof(msglen)); - } + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); msglen = htonl(0); pool_write_and_flush(frontend, &msglen, sizeof(msglen)); @@ -458,7 +439,7 @@ read_kind: (errmsg("authentication backend"), errdetail("trying clear text password authentication"))); - authkind = do_clear_text_password(CONNECTION(cp, i), frontend, 0, protoMajor); + authkind = do_clear_text_password(CONNECTION(cp, i), frontend, 0); if (authkind < 0) { @@ -524,7 +505,7 @@ read_kind: (errmsg("authentication backend: %d", i), errdetail("trying md5 authentication"))); - authkind = do_md5(CONNECTION(cp, i), frontend, 0, protoMajor, password, passwordType); + authkind = do_md5(CONNECTION(cp, i), frontend, 0, password, passwordType); if (authkind < 0) { @@ -599,7 +580,7 @@ read_kind: (errmsg("authentication backend %d", i), errdetail("trying SCRAM authentication"))); - if (do_SCRAM(frontend, CONNECTION(cp, i), protoMajor, message_length, frontend->username, password, passwordType) == false) + if (do_SCRAM(frontend, CONNECTION(cp, i), message_length, frontend->username, password, passwordType) == false) { pool_send_auth_fail(frontend, cp); ereport(ERROR, @@ -613,7 +594,7 @@ read_kind: if (kind == 'R') { - send_auth_ok(frontend, protoMajor); + send_auth_ok(frontend); authkind = 0; } } @@ -648,87 +629,58 @@ read_kind: else if (kind == 'K') break; - if (protoMajor == PROTO_MAJOR_V3) + switch (kind) { - switch (kind) - { - case 'S': - /* process parameter status */ - if (ParameterStatus(frontend, cp) != POOL_CONTINUE) - return -1; - pool_flush(frontend); - break; - - case 'N': - if (pool_extract_error_message(false, MAIN(cp), protoMajor, true, &message) == 1) - { - ereport(NOTICE, - (errmsg("notice from backend"), - errdetail("BACKEND NOTICE: \"%s\"", message))); - pfree(message); - } - /* forward the notice message to frontend */ - forward_message_to_frontend(kind, frontend, cp); - break; + case 'S': + /* process parameter status */ + if (ParameterStatus(frontend, cp) != POOL_CONTINUE) + return -1; + pool_flush(frontend); + break; - case 'E': - if (pool_extract_error_message(false, MAIN(cp), protoMajor, true, &message) == 1) - { - ereport(LOG, - (errmsg("backend throws an error message"), - errdetail("%s", message))); - pfree(message); - } - /* forward the error message to frontend */ - forward_message_to_frontend(kind, frontend, cp); - break; + case 'N': + if (pool_extract_error_message(false, MAIN(cp), true, &message) == 1) + { + ereport(NOTICE, + (errmsg("notice from backend"), + errdetail("BACKEND NOTICE: \"%s\"", message))); + pfree(message); + } + /* forward the notice message to frontend */ + forward_message_to_frontend(kind, frontend, cp); + break; - default: - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("unknown response \"%c\" before processing BackendKeyData", kind))); - break; - } - } - else - { - /* V2 case */ - switch (kind) - { - case 'N': - /* process notice message */ - NoticeResponse(frontend, cp); - break; - - /* process error message */ - case 'E': - ErrorResponse(frontend, cp); - /* fallthrough */ - default: - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid response \"%c\" before processing BackendKeyData", kind))); - break; - } + case 'E': + if (pool_extract_error_message(false, MAIN(cp), true, &message) == 1) + { + ereport(LOG, + (errmsg("backend throws an error message"), + errdetail("%s", message))); + pfree(message); + } + /* forward the error message to frontend */ + forward_message_to_frontend(kind, frontend, cp); + break; + + default: + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("unknown response \"%c\" before processing BackendKeyData", kind))); + break; } } /* * Read BackendKeyData message length. */ - if (protoMajor == PROTO_MAJOR_V3) + length = pool_read_message_length(cp); + keylen = length - sizeof(int32) - sizeof(int32); + if (keylen > MAX_CANCELKEY_LENGTH) { - length = pool_read_message_length(cp); - keylen = length - sizeof(int32) - sizeof(int32); - if (keylen > MAX_CANCELKEY_LENGTH) - { - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("cancel key length exceeds 256 bytes"))); - } + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("cancel key length exceeds 256 bytes"))); } - else - keylen = 4; elog(DEBUG1, "cancel key length: %d", keylen); @@ -799,7 +751,7 @@ read_kind: * backend in the backend group. */ pool_send_backend_key_data(frontend, pid, cancel_key, - MAIN_CONNECTION(cp)->keylen, protoMajor); + MAIN_CONNECTION(cp)->keylen); return 0; } @@ -810,19 +762,16 @@ read_kind: int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { - int protoMajor; int msglen; POOL_CONNECTION_POOL_SLOT *sp; - protoMajor = MAJOR(cp); - /* * If NegotiateProtocolMsg has been received from backend, forward it to * frontend. If the frontend dislike it, it will disconnect the * connection. Otherwise it will silently continue. */ sp = CONNECTION_SLOT(cp, MAIN_NODE_ID); - if (protoMajor == PROTO_MAJOR_V3 && sp->nplen > 0) + if (sp->nplen > 0) { elog(DEBUG1, "negotiateProtocol message is forwarded to frontend at reauth"); pool_write_and_flush(frontend, sp->negotiateProtocolMsg, @@ -842,12 +791,12 @@ pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) case AUTH_REQ_PASSWORD: /* clear text password */ - do_clear_text_password(MAIN(cp), frontend, 1, protoMajor); + do_clear_text_password(MAIN(cp), frontend, 1); break; case AUTH_REQ_MD5: /* md5 password */ - authenticate_frontend_md5(MAIN(cp), frontend, 1, protoMajor); + authenticate_frontend_md5(MAIN(cp), frontend, 1); break; case AUTH_REQ_SASL: @@ -867,18 +816,15 @@ pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) */ pool_write(frontend, "R", 1); - if (protoMajor == PROTO_MAJOR_V3) - { - msglen = htonl(8); - pool_write(frontend, &msglen, sizeof(msglen)); - } + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); msglen = htonl(0); pool_write_and_flush(frontend, &msglen, sizeof(msglen)); /* send BackendKeyData */ pool_send_backend_key_data(frontend, MAIN_CONNECTION(cp)->pid, MAIN_CONNECTION(cp)->key, - MAIN_CONNECTION(cp)->keylen, protoMajor); + MAIN_CONNECTION(cp)->keylen); return 0; } @@ -891,19 +837,15 @@ pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { int messagelen; char *errmessage; - int protoMajor; - bool send_error_to_frontend = true; - protoMajor = MAJOR(cp); - messagelen = strlen(MAIN_CONNECTION(cp)->sp->user) + 100; errmessage = (char *) palloc(messagelen + 1); snprintf(errmessage, messagelen, "password authentication failed for user \"%s\"", MAIN_CONNECTION(cp)->sp->user); if (send_error_to_frontend) - pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage, + pool_send_fatal_message(frontend, "XX000", errmessage, "", "", __FILE__, __LINE__); pfree(errmessage); } @@ -913,7 +855,7 @@ pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) */ static void pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, - char *key, int32 keylen, int protoMajor) + char *key, int32 keylen) { char kind; int32 len; @@ -921,11 +863,9 @@ pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, /* Send backend key data */ kind = 'K'; pool_write(frontend, &kind, 1); - if (protoMajor == PROTO_MAJOR_V3) - { - len = htonl(sizeof(int32) + sizeof(int32) + keylen); - pool_write(frontend, &len, sizeof(len)); - } + len = htonl(sizeof(int32) + sizeof(int32) + keylen); + pool_write(frontend, &len, sizeof(len)); + ereport(DEBUG1, (errmsg("sending backend key data"))); pool_write(frontend, &pid, sizeof(pid)); @@ -941,10 +881,10 @@ authenticate_frontend_clear_text(POOL_CONNECTION *frontend) char *storedPassword = NULL; char *userPwd = NULL; - sendAuthRequest(frontend, frontend->protoVersion, AUTH_REQ_PASSWORD, NULL, 0); + sendAuthRequest(frontend, AUTH_REQ_PASSWORD, NULL, 0); /* Read password packet */ - read_password_packet(frontend, frontend->protoVersion, password, &size); + read_password_packet(frontend, password, &size); /* save the password in frontend */ frontend->auth_kind = AUTH_REQ_PASSWORD; @@ -1020,7 +960,7 @@ authenticate_frontend_clear_text(POOL_CONNECTION *frontend) * perform clear text password authentication */ static int -do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth) { static int size; char *pwd = NULL; @@ -1120,14 +1060,14 @@ do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int return 0; } - kind = send_password_packet(backend, protoMajor, pwd); + kind = send_password_packet(backend, pwd); /* if authenticated, save info */ if (kind == AUTH_REQ_OK) { if (IS_MAIN_NODE_ID(backend->db_node_id)) { - send_auth_ok(frontend, protoMajor); + send_auth_ok(frontend); } backend->auth_kind = AUTH_REQ_PASSWORD; @@ -1194,18 +1134,6 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, (errmsg("authentication failed"), errdetail("failed to build the scram verifier"))); - /* - * SASL auth is not supported for protocol versions before 3, because it - * relies on the overall message length word to determine the SASL payload - * size in AuthenticationSASLContinue and PasswordMessage messages. (We - * used to have a hard rule that protocol messages must be parsable - * without relying on the length word, but we hardly care about older - * protocol version anymore.) - */ - if (frontend->protoVersion < PROTO_MAJOR_V3) - ereport(FATAL, - (errmsg("SASL authentication is not supported in protocol version 2"))); - /* * Send the SASL authentication request to user. It includes the list of * authentication mechanisms (which is trivial, because we only support @@ -1213,7 +1141,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, * terminate the list. */ - sendAuthRequest(frontend, frontend->protoVersion, AUTH_REQ_SASL, SCRAM_SHA_256_NAME "\0", + sendAuthRequest(frontend, AUTH_REQ_SASL, SCRAM_SHA_256_NAME "\0", strlen(SCRAM_SHA_256_NAME) + 2); /* @@ -1242,7 +1170,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, static char data[MAX_PASSWORD_SIZE]; /* Read password packet */ - read_password_packet(frontend, frontend->protoVersion, data, &size); + read_password_packet(frontend, data, &size); ereport(DEBUG4, (errmsg("Processing received SASL response of length %d", size))); @@ -1305,9 +1233,9 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, (errmsg("sending SASL challenge of length %u", outputlen))); if (result == SASL_EXCHANGE_SUCCESS) - sendAuthRequest(frontend, frontend->protoVersion, AUTH_REQ_SASL_FIN, output, outputlen); + sendAuthRequest(frontend, AUTH_REQ_SASL_FIN, output, outputlen); else - sendAuthRequest(frontend, frontend->protoVersion, AUTH_REQ_SASL_CONT, output, outputlen); + sendAuthRequest(frontend, AUTH_REQ_SASL_CONT, output, outputlen); pfree(output); } @@ -1332,7 +1260,7 @@ authenticate_frontend(POOL_CONNECTION *frontend) switch (frontend->pool_hba->auth_method) { case uaMD5: - authenticate_frontend_md5(NULL, frontend, 0, frontend->protoVersion); + authenticate_frontend_md5(NULL, frontend, 0); break; case uaCert: authenticate_frontend_cert(frontend); @@ -1401,7 +1329,7 @@ authenticate_frontend_cert(POOL_CONNECTION *frontend) #endif static void -authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth) { char salt[4]; static int size; @@ -1422,10 +1350,10 @@ authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, i } pool_random_salt(salt); - send_md5auth_request(frontend, frontend->protoVersion, salt); + send_md5auth_request(frontend, salt); /* Read password packet */ - read_password_packet(frontend, frontend->protoVersion, password, &size); + read_password_packet(frontend, password, &size); /* If we have clear text password stored in pool_passwd, convert it to md5 */ if (storedPasswordType == PASSWORD_TYPE_PLAINTEXT || storedPasswordType == PASSWORD_TYPE_AES) @@ -1538,7 +1466,7 @@ get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut * perform MD5 authentication */ static int -do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor, +do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, char *storedPassword, PasswordType passwordType) { char salt[4]; @@ -1604,7 +1532,7 @@ do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int prot } else { - authenticate_frontend_md5(backend, frontend, reauth, protoMajor); + authenticate_frontend_md5(backend, frontend, reauth); } } @@ -1626,7 +1554,7 @@ do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int prot pg_md5_encrypt(pool_passwd + strlen("md5"), salt, sizeof(salt), encbuf); /* Send password packet to backend and receive auth response */ - kind = send_password_packet(backend, protoMajor, encbuf); + kind = send_password_packet(backend, encbuf); if (kind < 0) ereport(ERROR, (errmsg("md5 authentication failed"), @@ -1638,7 +1566,7 @@ do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int prot if (IS_MAIN_NODE_ID(backend->db_node_id)) { /* Send auth ok to frontend */ - send_auth_ok(frontend, protoMajor); + send_auth_ok(frontend); } /* Save the auth info */ @@ -1655,18 +1583,14 @@ do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int prot * Send an authentication request packet to the frontend. */ static void -sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen) +sendAuthRequest(POOL_CONNECTION *frontend, int32 auth_req_type, char *extradata, int extralen) { int kind = htonl(auth_req_type); + int len = 8 + extralen; pool_write(frontend, "R", 1); /* authentication */ - if (protoMajor == PROTO_MAJOR_V3) - { - int len = 8 + extralen; - - len = htonl(len); - pool_write(frontend, &len, sizeof(len)); - } + len = htonl(len); + pool_write(frontend, &len, sizeof(len)); pool_write(frontend, &kind, sizeof(kind)); if (extralen > 0) pool_write_and_flush(frontend, extradata, extralen); @@ -1678,9 +1602,9 @@ sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, * Send md5 authentication request packet to frontend */ static void -send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt) +send_md5auth_request(POOL_CONNECTION *frontend, char *salt) { - sendAuthRequest(frontend, protoMajor, AUTH_REQ_MD5, salt, 4); + sendAuthRequest(frontend, AUTH_REQ_MD5, salt, 4); } @@ -1688,27 +1612,20 @@ send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt) * Read password packet from frontend */ static int -read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize) +read_password_packet(POOL_CONNECTION *frontend, char *password, int *pwdSize) { + char k; int size; - /* Read password packet */ - if (protoMajor == PROTO_MAJOR_V2) - { - pool_read(frontend, &size, sizeof(size)); - } - else - { - char k; - - pool_read(frontend, &k, sizeof(k)); - if (k != 'p') - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid authentication packet. password packet does not start with \"p\""))); + /* Read message kind */ + pool_read(frontend, &k, sizeof(k)); + if (k != 'p') + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid authentication packet. password packet does not start with \"p\""))); - pool_read(frontend, &size, sizeof(size)); - } + /* Read password packet */ + pool_read(frontend, &size, sizeof(size)); *pwdSize = ntohl(size) - 4; if (*pwdSize > MAX_PASSWORD_SIZE) @@ -1741,7 +1658,7 @@ read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, * "password" must be null-terminated. */ static int -send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) +send_password_packet(POOL_CONNECTION *backend, char *password) { int size; int len; @@ -1749,8 +1666,7 @@ send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) char response; /* Send password packet to backend */ - if (protoMajor == PROTO_MAJOR_V3) - pool_write(backend, "p", 1); + pool_write(backend, "p", 1); size = htonl(sizeof(size) + strlen(password) + 1); pool_write(backend, &size, sizeof(size)); pool_write_and_flush(backend, password, strlen(password) + 1); @@ -1763,7 +1679,7 @@ send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) { char *message = NULL; - if (pool_extract_error_message(false, backend, protoMajor, false, &message) == 1) + if (pool_extract_error_message(false, backend, false, &message) == 1) { ereport(ERROR, (errmsg("authentication failed"), @@ -1777,15 +1693,12 @@ send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) errdetail("invalid backend response. Response does not replied with \"R\""))); } - if (protoMajor == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); + pool_read(backend, &len, sizeof(len)); - if (ntohl(len) != 8) - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid authentication packet. incorrect authentication packet size (%d)", ntohl(len)))); - } + if (ntohl(len) != 8) + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid authentication packet. incorrect authentication packet size (%d)", ntohl(len)))); /* Expect to read "Authentication OK" response. kind should be 0... */ pool_read(backend, &kind, sizeof(kind)); @@ -1797,17 +1710,14 @@ send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) * Send auth ok to frontend */ static int -send_auth_ok(POOL_CONNECTION *frontend, int protoMajor) +send_auth_ok(POOL_CONNECTION *frontend) { int msglen; pool_write(frontend, "R", 1); - if (protoMajor == PROTO_MAJOR_V3) - { - msglen = htonl(8); - pool_write(frontend, &msglen, sizeof(msglen)); - } + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); msglen = htonl(0); pool_write_and_flush(frontend, &msglen, sizeof(msglen)); @@ -1836,7 +1746,7 @@ pool_random_salt(char *md5Salt) } static bool -do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoMajor, int message_length, +do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int message_length, char *username, char *storedPassword, PasswordType passwordType) { /* read the packet first */ diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c index 16ac34825..8accd0436 100644 --- a/src/context/pool_query_context.c +++ b/src/context/pool_query_context.c @@ -658,7 +658,7 @@ pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, per_node_statement_log(backend, i, string); per_node_statement_notice(backend, i, string); stat_count_up(i, query_context->parse_tree); - send_simplequery_message(CONNECTION(backend, i), len, string, MAJOR(backend)); + send_simplequery_message(CONNECTION(backend, i), len, string); } /* Wait for response */ @@ -693,7 +693,6 @@ pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, wait_for_query_response_with_trans_cleanup(frontend, CONNECTION(backend, i), - MAJOR(backend), MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen); @@ -912,7 +911,6 @@ pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, wait_for_query_response_with_trans_cleanup(frontend, CONNECTION(backend, i), - MAJOR(backend), MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen); @@ -2509,7 +2507,7 @@ where_to_send_native_replication(POOL_QUERY_CONTEXT *query_context, char *query, POOL_SELECT_RESULT *res; bool load_balance = false; - do_query(CONNECTION(backend, MAIN_NODE_ID), si_query, &res, MAJOR(backend)); + do_query(CONNECTION(backend, MAIN_NODE_ID), si_query, &res); if (res) { if (res->data[0] && !strcmp(res->data[0], "on")) diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c index 61d50e015..403cfab1a 100644 --- a/src/context/pool_session_context.c +++ b/src/context/pool_session_context.c @@ -980,7 +980,7 @@ pool_get_transaction_isolation(void) /* No cached data is available. Ask backend. */ do_query(MAIN(session_context->backend), - "SELECT current_setting('transaction_isolation')", &res, MAJOR(session_context->backend)); + "SELECT current_setting('transaction_isolation')", &res); error_context_stack = callback.previous; diff --git a/src/include/protocol/pool_process_query.h b/src/include/protocol/pool_process_query.h index f54b694a1..b6a4975ff 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-2025 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -33,13 +33,13 @@ extern void reset_connection(void); extern void per_node_statement_log(POOL_CONNECTION_POOL *backend, int node_id, char *query); extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, - int major, bool unread, char **message); + bool unread, char **message); extern POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, - 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); + char *query, int pid, char *key, int keylen, int no_ready_for_query); +extern void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result); extern void free_select_result(POOL_SELECT_RESULT *result); extern int compare(const void *p1, const void *p2); -extern void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major); +extern void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id); extern POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp); extern void pool_dump_valid_backend(int backend_id); extern bool pool_push_pending_data(POOL_CONNECTION *backend); @@ -49,21 +49,21 @@ extern void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend); extern POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, +extern void pool_send_error_message(POOL_CONNECTION *frontend, char *code, char *message, char *detail, char *hint, char *file, int line); -extern void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, +extern void pool_send_fatal_message(POOL_CONNECTION *frontend, char *code, char *message, char *detail, char *hint, char *file, int line); -extern void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, +extern void pool_send_severity_message(POOL_CONNECTION *frontend, char *code, char *message, char *detail, @@ -81,6 +81,6 @@ extern POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, extern bool is_backend_cache_empty(POOL_CONNECTION_POOL *backend); extern void pool_send_readyforquery(POOL_CONNECTION *frontend); -extern char *extract_error_kind(char *message, int major); +extern char *extract_error_kind(char *message); #endif /* pool_process_query_h */ diff --git a/src/include/protocol/pool_proto_modules.h b/src/include/protocol/pool_proto_modules.h index 59eaa3c54..c5a40a605 100644 --- a/src/include/protocol/pool_proto_modules.h +++ b/src/include/protocol/pool_proto_modules.h @@ -6,7 +6,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2025 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -152,8 +152,8 @@ extern int RowDescription(POOL_CONNECTION *frontend, short *result); 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); + int pid, char *key, int keylen); +extern POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend); extern bool is_select_query(Node *node, char *sql); extern bool is_commit_query(Node *node); extern bool is_rollback_query(Node *node); @@ -169,19 +169,19 @@ extern int check_copy_from_stdin(Node *node); /* returns non 0 if this is a extern void query_ps_status(char *query, POOL_CONNECTION_POOL *backend); /* show ps status */ extern POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node); extern POOL_STATUS end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern int detect_deadlock_error(POOL_CONNECTION *backend, int major); -extern int detect_serialization_error(POOL_CONNECTION *backend, int major, bool unread); -extern int detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major); -extern int detect_query_cancel_error(POOL_CONNECTION *backend, int major); -extern int detect_idle_in_transaction_session_timeout_error(POOL_CONNECTION *backend, int major); -extern int detect_idle_session_timeout_error(POOL_CONNECTION *backend, int major); +extern int detect_deadlock_error(POOL_CONNECTION *backend); +extern int detect_serialization_error(POOL_CONNECTION *backend, bool unread); +extern int detect_active_sql_transaction_error(POOL_CONNECTION *backend); +extern int detect_query_cancel_error(POOL_CONNECTION *backend); +extern int detect_idle_in_transaction_session_timeout_error(POOL_CONNECTION *backend); +extern int detect_idle_session_timeout_error(POOL_CONNECTION *backend); extern bool is_partition_table(POOL_CONNECTION_POOL *backend, Node *node); extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp); extern void query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len); extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP * DATABASE command */ -extern void send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major); +extern void send_simplequery_message(POOL_CONNECTION *backend, int len, char *string); extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, int node_id, char *kind, int len, char *string); @@ -189,7 +189,7 @@ extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, extern int synchronize(POOL_CONNECTION *cp); extern void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *decided_kind); extern void read_kind_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *kind, int node); -extern void do_error_command(POOL_CONNECTION *backend, int major); +extern void do_error_command(POOL_CONNECTION *backend); extern void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend); extern void forward_deferred_sync_to_primary(POOL_CONNECTION_POOL *backend); extern void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); diff --git a/src/protocol/CommandComplete.c b/src/protocol/CommandComplete.c index 5578bb10b..e0ee0b9e6 100644 --- a/src/protocol/CommandComplete.c +++ b/src/protocol/CommandComplete.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2025 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -684,7 +684,7 @@ handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, appendStringInfoString(&msg, "pgpool detected difference of the number of inserted, updated or deleted tuples. Possible last query was: \""); appendStringInfoString(&msg, query_string_buffer); appendStringInfoString(&msg, "\""); - pool_send_error_message(frontend, MAJOR(backend), + pool_send_error_message(frontend, "XX001", msg.data, "", "check data consistency between main and other db node", __FILE__, __LINE__); ereport(LOG, diff --git a/src/protocol/child.c b/src/protocol/child.c index 4da5cf12f..1b4a9f5e2 100644 --- a/src/protocol/child.c +++ b/src/protocol/child.c @@ -5,7 +5,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2025 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -158,8 +158,8 @@ bool stop_now = false; static bool connection_pool_initialized = false; /* -* child main loop -*/ + * child main loop + */ void do_child(int *fds) { @@ -385,7 +385,7 @@ do_child(int *fds) continue; } connection_count_down(); - pool_send_fatal_message(cp, 3, "53300", + pool_send_fatal_message(cp, "53300", "Sorry, too many clients already", "", "", @@ -620,12 +620,11 @@ backend_cleanup(POOL_CONNECTION *volatile *frontend, POOL_CONNECTION_POOL *volat * Read startup packet * * Read the startup packet and parse the contents. -*/ + */ static StartupPacket * read_startup_packet(POOL_CONNECTION *cp) { StartupPacket *sp; - StartupPacket_v2 *sp2; int protov; int len; char *p; @@ -667,15 +666,10 @@ read_startup_packet(POOL_CONNECTION *cp) switch (sp->major) { - case PROTO_MAJOR_V2: /* V2 */ - sp2 = (StartupPacket_v2 *) (sp->startup_packet); - - sp->database = palloc0(SM_DATABASE + 1); - strncpy(sp->database, sp2->database, SM_DATABASE); - - sp->user = palloc0(SM_USER + 1); - strncpy(sp->user, sp2->user, SM_USER); - + case PROTO_MAJOR_V2: /* V2 protocol is not supported */ + ereport(FATAL, + (errmsg("unsupported frontend protocol %u.%u", + sp->major, sp->minor))); break; case PROTO_MAJOR_V3: /* V3 */ @@ -781,7 +775,7 @@ read_startup_packet(POOL_CONNECTION *cp) if (sp->major != 1234 && (sp->user == NULL || sp->user[0] == '\0')) { - pool_send_fatal_message(cp, sp->major, "28000", + pool_send_fatal_message(cp, "28000", "no PostgreSQL user name specified in startup packet", "", "", @@ -1065,7 +1059,7 @@ connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend) backend = pool_create_cp(); if (backend == NULL) { - pool_send_error_message(frontend, sp->major, "XX000", "all backend nodes are down, pgpool requires at least one valid node", "", + pool_send_error_message(frontend, "XX000", "all backend nodes are down, pgpool requires at least one valid node", "", "repair the backend nodes and restart pgpool", __FILE__, __LINE__); ereport(ERROR, (errmsg("unable to connect to backend"), @@ -1933,8 +1927,8 @@ validate_backend_connectivity(int front_end_fd) ereport(DEBUG1, (errmsg("forwarding error message to frontend"))); - pool_send_error_message(cp, sp->major, - (sp->major == PROTO_MAJOR_V3) ? "08S01" : NULL, + pool_send_error_message(cp, + "08S01", error_msg, error_detail, error_hint, diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index d5530272d..7c6b21e28 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -83,9 +83,9 @@ static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt); static char *get_insert_command_table_name(InsertStmt *node); static bool is_cache_empty(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -static bool is_panic_or_fatal_error(char *message, int major); -static int extract_message(POOL_CONNECTION *backend, char *error_code, int major, char class, bool unread); -static int detect_postmaster_down_error(POOL_CONNECTION *backend, int major); +static bool is_panic_or_fatal_error(char *message); +static int extract_message(POOL_CONNECTION *backend, char *error_code, char class, bool unread); +static int detect_postmaster_down_error(POOL_CONNECTION *backend); static bool is_internal_transaction_needed(Node *node); static bool pool_has_insert_lock(void); static POOL_STATUS add_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *table); @@ -422,28 +422,15 @@ pool_process_query(POOL_CONNECTION *frontend, (errmsg("pool process query"), errdetail("discard %c packet from backend %d", kind, i))); - - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - pool_read_with_error(CONNECTION(backend, i), &len, sizeof(len), - "reading message length from backend"); - len = ntohl(len) - 4; - string = pool_read2(CONNECTION(backend, i), len); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process query"), - errdetail("error while reading rest of message from backend %d", i))); - } - else - { - string = pool_read_string(CONNECTION(backend, i), &len, 0); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process query"), - errdetail("error while reading rest of message from backend %d", i))); - } + pool_read_with_error(CONNECTION(backend, i), &len, sizeof(len), + "reading message length from backend"); + len = ntohl(len) - 4; + string = pool_read2(CONNECTION(backend, i), len); + if (string == NULL) + ereport(FATAL, + (return_code(2), + errmsg("unable to process query"), + errdetail("error while reading rest of message from backend %d", i))); } } } @@ -488,17 +475,13 @@ pool_process_query(POOL_CONNECTION *frontend, * send simple query message to a node. */ void -send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major) +send_simplequery_message(POOL_CONNECTION *backend, int len, char *string) { + int sendlen = htonl(len + 4); + /* forward the query to the backend */ pool_write(backend, "Q", 1); - - if (major == PROTO_MAJOR_V3) - { - int sendlen = htonl(len + 4); - - pool_write(backend, &sendlen, sizeof(sendlen)); - } + pool_write(backend, &sendlen, sizeof(sendlen)); pool_write_and_flush(backend, string, len); } @@ -512,11 +495,11 @@ send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int ma void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, - int protoVersion, int pid, char *key, int keylen) + int pid, char *key, int keylen) { PG_TRY(); { - wait_for_query_response(frontend, backend, protoVersion); + wait_for_query_response(frontend, backend); } PG_CATCH(); { @@ -544,7 +527,7 @@ wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_CONNE * response. */ POOL_STATUS -wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion) +wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend) { #define DUMMY_PARAMETER "pgpool_dummy_param" #define DUMMY_VALUE "pgpool_dummy_value" @@ -573,50 +556,22 @@ wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int * If data from backend is not ready, check frontend connection by * sending dummy parameter status packet. */ - if (protoVersion == PROTO_MAJOR_V3) - { - /* - * Write dummy parameter status packet to check if the socket - * to frontend is ok - */ - pool_write(frontend, "S", 1); - plen = sizeof(DUMMY_PARAMETER) + sizeof(DUMMY_VALUE) + sizeof(plen); - plen = htonl(plen); - pool_write(frontend, &plen, sizeof(plen)); - pool_write(frontend, DUMMY_PARAMETER, sizeof(DUMMY_PARAMETER)); - pool_write(frontend, DUMMY_VALUE, sizeof(DUMMY_VALUE)); - if (pool_flush_it(frontend) < 0) - { - ereport(FRONTEND_DEBUG, - (errmsg("unable to flush data to frontend"), - errdetail("frontend error occurred while waiting for backend reply"))); - } - } - else /* Protocol version 2 */ + /* + * Write dummy parameter status packet to check if the socket + * to frontend is ok + */ + pool_write(frontend, "S", 1); + plen = sizeof(DUMMY_PARAMETER) + sizeof(DUMMY_VALUE) + sizeof(plen); + plen = htonl(plen); + pool_write(frontend, &plen, sizeof(plen)); + pool_write(frontend, DUMMY_PARAMETER, sizeof(DUMMY_PARAMETER)); + pool_write(frontend, DUMMY_VALUE, sizeof(DUMMY_VALUE)); + if (pool_flush_it(frontend) < 0) { -/* - * If you want to monitor client connection even if you are using V2 protocol, - * define following - */ -#undef SEND_NOTICE_ON_PROTO2 -#ifdef SEND_NOTICE_ON_PROTO2 - static char *notice_message = {"keep alive checking from pgpool-II"}; - - /* - * Write notice message packet to check if the socket to - * frontend is ok - */ - pool_write(frontend, "N", 1); - pool_write(frontend, notice_message, strlen(notice_message) + 1); - if (pool_flush_it(frontend) < 0) - { - ereport(FRONTEND_DEBUG, - (errmsg("unable to flush data to frontend"), - errdetail("frontend error occurred while waiting for backend reply"))); - - } -#endif + ereport(FRONTEND_DEBUG, + (errmsg("unable to flush data to frontend"), + errdetail("frontend error occurred while waiting for backend reply"))); } } else @@ -692,11 +647,8 @@ pool_send_frontend_exits(POOL_CONNECTION_POOL *backend) { pool_write_noerror(CONNECTION(backend, i), "X", 1); - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - len = htonl(4); - pool_write_noerror(CONNECTION(backend, i), &len, sizeof(len)); - } + len = htonl(4); + pool_write_noerror(CONNECTION(backend, i), &len, sizeof(len)); /* * XXX we cannot call pool_flush() here since backend may already @@ -839,7 +791,7 @@ SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, * message and exit since the backend will close the channel * immediately. */ - if (is_panic_or_fatal_error(p1, MAJOR(backend))) + if (is_panic_or_fatal_error(p1)) ereport(ERROR, (errmsg("unable to forward message to frontend"), errdetail("FATAL error occurred on backend"))); @@ -1336,7 +1288,7 @@ is_rollback_to_query(Node *node) * send error message to frontend */ void -pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, +pool_send_error_message(POOL_CONNECTION *frontend, char *code, char *message, char *detail, @@ -1344,14 +1296,14 @@ pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, char *file, int line) { - pool_send_severity_message(frontend, protoMajor, code, message, detail, hint, file, "ERROR", line); + pool_send_severity_message(frontend, code, message, detail, hint, file, "ERROR", line); } /* * send fatal message to frontend */ void -pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, +pool_send_fatal_message(POOL_CONNECTION *frontend, char *code, char *message, char *detail, @@ -1359,14 +1311,14 @@ pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, char *file, int line) { - pool_send_severity_message(frontend, protoMajor, code, message, detail, hint, file, "FATAL", line); + pool_send_severity_message(frontend, code, message, detail, hint, file, "FATAL", line); } /* * send severity message to frontend */ void -pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, +pool_send_severity_message(POOL_CONNECTION *frontend, char *code, char *message, char *detail, @@ -1386,86 +1338,75 @@ pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, */ #define MAXDATA (MAXMSGBUF+1)*7+1 + char data[MAXDATA]; + char msgbuf[MAXMSGBUF + 1]; + int len; + int thislen; + int sendlen; + socket_set_nonblock(frontend->fd); - if (protoMajor == PROTO_MAJOR_V2) - { - pool_write(frontend, "E", 1); - pool_write_and_flush(frontend, message, strlen(message) + 1); - } - else if (protoMajor == PROTO_MAJOR_V3) - { - char data[MAXDATA]; - char msgbuf[MAXMSGBUF + 1]; - int len; - int thislen; - int sendlen; + len = 0; + memset(data, 0, MAXDATA); - len = 0; - memset(data, 0, MAXDATA); + pool_write(frontend, "E", 1); - pool_write(frontend, "E", 1); + /* error level */ + thislen = snprintf(msgbuf, MAXMSGBUF, "S%s", severity); + thislen = Min(thislen, MAXMSGBUF); + memcpy(data + len, msgbuf, thislen + 1); + len += thislen + 1; - /* error level */ - thislen = snprintf(msgbuf, MAXMSGBUF, "S%s", severity); - thislen = Min(thislen, MAXMSGBUF); - memcpy(data + len, msgbuf, thislen + 1); - len += thislen + 1; + /* code */ + thislen = snprintf(msgbuf, MAXMSGBUF, "C%s", code); + thislen = Min(thislen, MAXMSGBUF); + memcpy(data + len, msgbuf, thislen + 1); + len += thislen + 1; - /* code */ - thislen = snprintf(msgbuf, MAXMSGBUF, "C%s", code); - thislen = Min(thislen, MAXMSGBUF); - memcpy(data + len, msgbuf, thislen + 1); - len += thislen + 1; + /* message */ + thislen = snprintf(msgbuf, MAXMSGBUF, "M%s", message); + thislen = Min(thislen, MAXMSGBUF); + memcpy(data + len, msgbuf, thislen + 1); + len += thislen + 1; - /* message */ - thislen = snprintf(msgbuf, MAXMSGBUF, "M%s", message); + /* detail */ + if (detail && *detail != '\0') + { + thislen = snprintf(msgbuf, MAXMSGBUF, "D%s", detail); thislen = Min(thislen, MAXMSGBUF); memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; + } - /* detail */ - if (detail && *detail != '\0') - { - thislen = snprintf(msgbuf, MAXMSGBUF, "D%s", detail); - thislen = Min(thislen, MAXMSGBUF); - memcpy(data + len, msgbuf, thislen + 1); - len += thislen + 1; - } - - /* hint */ - if (hint && *hint != '\0') - { - thislen = snprintf(msgbuf, MAXMSGBUF, "H%s", hint); - thislen = Min(thislen, MAXMSGBUF); - memcpy(data + len, msgbuf, thislen + 1); - len += thislen + 1; - } - - /* file */ - thislen = snprintf(msgbuf, MAXMSGBUF, "F%s", file); + /* hint */ + if (hint && *hint != '\0') + { + thislen = snprintf(msgbuf, MAXMSGBUF, "H%s", hint); thislen = Min(thislen, MAXMSGBUF); memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; + } - /* line */ - thislen = snprintf(msgbuf, MAXMSGBUF, "L%d", line); - thislen = Min(thislen, MAXMSGBUF); - memcpy(data + len, msgbuf, thislen + 1); - len += thislen + 1; + /* file */ + thislen = snprintf(msgbuf, MAXMSGBUF, "F%s", file); + thislen = Min(thislen, MAXMSGBUF); + memcpy(data + len, msgbuf, thislen + 1); + len += thislen + 1; - /* stop null */ - len++; - *(data + len - 1) = '\0'; + /* line */ + thislen = snprintf(msgbuf, MAXMSGBUF, "L%d", line); + thislen = Min(thislen, MAXMSGBUF); + memcpy(data + len, msgbuf, thislen + 1); + len += thislen + 1; - sendlen = len; - len = htonl(len + 4); - pool_write(frontend, &len, sizeof(len)); - pool_write_and_flush(frontend, data, sendlen); - } - else - ereport(ERROR, - (errmsg("send_error_message: unknown protocol major %d", protoMajor))); + /* stop null */ + len++; + *(data + len - 1) = '\0'; + + sendlen = len; + len = htonl(len + 4); + pool_write(frontend, &len, sizeof(len)); + pool_write_and_flush(frontend, data, sendlen); socket_unset_nonblock(frontend->fd); } @@ -1493,7 +1434,7 @@ pool_send_readyforquery(POOL_CONNECTION *frontend) */ POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, - char *query, int protoMajor, int pid, char *key, int keylen, int no_ready_for_query) + char *query, int pid, char *key, int keylen, int no_ready_for_query) { int len; char kind; @@ -1504,7 +1445,7 @@ do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, (errmsg("do_command: Query:\"%s\"", query))); /* send the query to the backend */ - send_simplequery_message(backend, strlen(query) + 1, query, protoMajor); + send_simplequery_message(backend, strlen(query) + 1, query); /* * Wait for response from backend while polling frontend connection is ok. @@ -1512,7 +1453,6 @@ do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, */ wait_for_query_response_with_trans_cleanup(frontend, backend, - protoMajor, pid, key, keylen); @@ -1524,7 +1464,7 @@ do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, * transaction. Otherwise the transaction state might vary among backends * (idle in transaction vs. abort). */ - deadlock_detected = detect_deadlock_error(backend, protoMajor); + deadlock_detected = detect_deadlock_error(backend); /* * Continue to read packets until we get ReadForQuery (Z). Until that we @@ -1546,65 +1486,43 @@ do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, break; /* get out the loop without reading message * length */ - if (protoMajor == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); - - len = ntohl(len) - 4; - - if (kind != 'N' && kind != 'E' && kind != 'S' && kind != 'C' && kind != 'A') - { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("kind is not N, E, S, C or A(%02x)", kind))); - - } - string = pool_read2(backend, len); - if (string == NULL) - { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("unable to read message from backend"))); - } + pool_read(backend, &len, sizeof(len)); + len = ntohl(len) - 4; - /* - * It is possible that we receive a notification response ('A') - * from one of backends prior to "ready for query" response if - * LISTEN and NOTIFY are issued in a same connection. So we need - * to save notification response to stack buffer so that we could - * retrieve it later on. - */ - if (kind == 'A') - { - int nlen = htonl(len + 4); + if (kind != 'N' && kind != 'E' && kind != 'S' && kind != 'C' && kind != 'A') + { + ereport(ERROR, + (errmsg("do command failed"), + errdetail("kind is not N, E, S, C or A(%02x)", kind))); - pool_push(backend, &kind, sizeof(kind)); - pool_push(backend, &nlen, sizeof(nlen)); - pool_push(backend, string, len); - } } - else + string = pool_read2(backend, len); + if (string == NULL) { - string = pool_read_string(backend, &len, 0); - if (string == NULL) - { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("unable to read reset message from backend"))); - } - if (kind == 'C') - { - if (!strncmp(string, "BEGIN", 5)) - backend->tstate = 'T'; - if (!strncmp(string, "COMMIT", 6) || - !strncmp(string, "ROLLBACK", 8)) - backend->tstate = 'I'; - } + ereport(ERROR, + (errmsg("do command failed"), + errdetail("unable to read message from backend"))); + } + + /* + * It is possible that we receive a notification response ('A') + * from one of backends prior to "ready for query" response if + * LISTEN and NOTIFY are issued in a same connection. So we need + * to save notification response to stack buffer so that we could + * retrieve it later on. + */ + if (kind == 'A') + { + int nlen = htonl(len + 4); + + pool_push(backend, &kind, sizeof(kind)); + pool_push(backend, &nlen, sizeof(nlen)); + pool_push(backend, string, len); } if (kind == 'E') { - if (is_panic_or_fatal_error(string, protoMajor)) + if (is_panic_or_fatal_error(string)) { ereport(ERROR, (errmsg("do command failed"), @@ -1613,87 +1531,21 @@ do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, } } -/* - * until 2008/11/12 we believed that we never had packets other than - * 'Z' after receiving 'C'. However a counter example was presented by - * a poor customer. So we replaced the whole thing with codes - * above. In a side effect we were be able to get ride of nasty - * "goto". Congratulations. - */ -#ifdef NOT_USED - - /* - * Expecting CompleteCommand - */ -retry_read_packet: - pool_read(backend, &kind, sizeof(kind)); - - if (kind == 'E') - { - ereport(LOG, - (errmsg("do command failed"), - errdetail("backend does not successfully complete command %s status %c", query, kind))); - } - - /* - * read command tag of CommandComplete response - */ - if (protoMajor == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); - len = ntohl(len) - 4; - string = pool_read2(backend, len); - if (string == NULL) - ereport(ERROR, - (errmsg("do command failed"), - errdetail("read from backend failed"))); - - ereport(DEBUG2, - (errmsg("do command: command tag: %s", string))); - } - else - { - string = pool_read_string(backend, &len, 0); - if (string == NULL) - ereport(ERROR, - (errmsg("do command failed"), - errdetail("read from backend failed"))); - } - - if (kind == 'N') /* warning? */ - goto retry_read_packet; - - /* - * Expecting ReadyForQuery - */ - pool_read(backend, &kind, sizeof(kind)); - - if (kind != 'Z') - { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("backend returns %c while expecting ReadyForQuery", kind))); - } -#endif - if (no_ready_for_query) return POOL_CONTINUE; - if (protoMajor == PROTO_MAJOR_V3) - { - /* read packet length for ready for query */ - pool_read(backend, &len, sizeof(len)); + /* read packet length for ready for query */ + pool_read(backend, &len, sizeof(len)); - /* read transaction state */ - pool_read(backend, &kind, sizeof(kind)); + /* read transaction state */ + pool_read(backend, &kind, sizeof(kind)); - /* set transaction state */ + /* set transaction state */ - backend->tstate = kind; + backend->tstate = kind; - ereport(DEBUG2, - (errmsg("do_command: transaction state: %c", kind))); - } + ereport(DEBUG2, + (errmsg("do_command: transaction state: %c", kind))); return deadlock_detected ? POOL_DEADLOCK : POOL_CONTINUE; } @@ -1707,14 +1559,14 @@ retry_read_packet: * If SELECT is error, we must abort transaction on other nodes. */ void -do_error_command(POOL_CONNECTION *backend, int major) +do_error_command(POOL_CONNECTION *backend) { char *error_query = POOL_ERROR_QUERY; int len; char kind; char *string; - send_simplequery_message(backend, strlen(error_query) + 1, error_query, major); + send_simplequery_message(backend, strlen(error_query) + 1, error_query); /* * Continue to read packets until we get Error response (E). Until that we @@ -1733,24 +1585,13 @@ do_error_command(POOL_CONNECTION *backend, int major) ereport(DEBUG2, (errmsg("do_error_command: kind: %c", kind))); - if (major == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); - len = ntohl(len) - 4; - string = pool_read2(backend, len); - if (string == NULL) - ereport(ERROR, - (errmsg("do error command failed"), - errdetail("read from backend failed"))); - } - else - { - string = pool_read_string(backend, &len, 0); - if (string == NULL) - ereport(ERROR, - (errmsg("do error command failed"), - errdetail("read from backend failed"))); - } + pool_read(backend, &len, sizeof(len)); + len = ntohl(len) - 4; + string = pool_read2(backend, len); + if (string == NULL) + ereport(ERROR, + (errmsg("do error command failed"), + errdetail("read from backend failed"))); } while (kind != 'E'); } @@ -1764,7 +1605,7 @@ do_error_command(POOL_CONNECTION *backend, int major) * than main node to ket them go into abort status. */ void -do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major) +do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id) { char kind; char *string; @@ -1798,57 +1639,33 @@ do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major) p += sizeof(kind); } - if (major == PROTO_MAJOR_V3) - { - pool_read(CONNECTION(backend, node_id), &len, sizeof(len)); - - if (kind != 'E') - { - readlen += sizeof(len); - memcpy(p, &len, sizeof(len)); - p += sizeof(len); - } - - len = ntohl(len) - 4; - string = pool_read2(CONNECTION(backend, node_id), len); - if (string == NULL) - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("read from backend failed"))); - if (kind != 'E') - { - readlen += len; - if (readlen >= sizeof(buf)) - { - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("not enough space in buffer"))); + pool_read(CONNECTION(backend, node_id), &len, sizeof(len)); - } - memcpy(p, string, len); - p += len; - } + if (kind != 'E') + { + readlen += sizeof(len); + memcpy(p, &len, sizeof(len)); + p += sizeof(len); } - else + + len = ntohl(len) - 4; + string = pool_read2(CONNECTION(backend, node_id), len); + if (string == NULL) + ereport(ERROR, + (errmsg("do error execute command failed"), + errdetail("read from backend failed"))); + if (kind != 'E') { - string = pool_read_string(CONNECTION(backend, node_id), &len, 0); - if (string == NULL) + readlen += len; + if (readlen >= sizeof(buf)) + { ereport(ERROR, (errmsg("do error execute command failed"), - errdetail("read from backend failed"))); + errdetail("not enough space in buffer"))); - if (kind != 'E') - { - readlen += len; - if (readlen >= sizeof(buf)) - { - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("not enough space in buffer"))); - } - memcpy(p, string, len); - p += len; } + memcpy(p, string, len); + p += len; } } while (kind != 'E'); @@ -1916,7 +1733,7 @@ free_select_result(POOL_SELECT_RESULT *result) * to void. and now ereport is thrown in case of error occurred within the function */ void -do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int major) +do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result) { #define DO_QUERY_ALLOC_NUM 1024 /* memory allocation unit for * POOL_SELECT_RESULT */ @@ -1952,9 +1769,6 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int RowDesc *rowdesc; AttrInfo *attrinfo; - int nbytes; - static char nullmap[8192]; - unsigned char mask = 0; bool doing_extended; int num_close_complete; int state; @@ -2127,7 +1941,7 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int } else { - send_simplequery_message(backend, strlen(query) + 1, query, major); + send_simplequery_message(backend, strlen(query) + 1, query); } /* @@ -2152,7 +1966,7 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int { char *message = NULL; - if (pool_extract_error_message(false, backend, major, true, &message) == 1) + if (pool_extract_error_message(false, backend, true, &message) == 1) { int etype; @@ -2192,35 +2006,18 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int } } - if (major == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); - - len = ntohl(len) - 4; + pool_read(backend, &len, sizeof(len)); - if (len > 0) - { - packet = pool_read2(backend, len); - if (packet == NULL) - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading rest of message"))); + len = ntohl(len) - 4; - } - } - else + if (len > 0) { - mask = 0; + packet = pool_read2(backend, len); + if (packet == NULL) + ereport(ERROR, + (errmsg("do query failed"), + errdetail("error while reading rest of message"))); - if (kind == 'C' || kind == 'E' || kind == 'N' || kind == 'P') - { - if (pool_read_string(backend, &len, 0) == NULL) - { - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading string of message type %c", kind))); - } - } } switch (kind) @@ -2304,23 +2101,16 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int ereport(DEBUG5, (errmsg("do_query: received ROW DESCRIPTION ('%c')", kind))); - if (major == PROTO_MAJOR_V3) + if (packet) { - if (packet) - { - p = packet; - memcpy(&shortval, p, sizeof(short)); - p += sizeof(num_fields); - } - else - { - ereport(ERROR, - (errmsg("do query failed, no data received for ROW DESCRIPTION ('%c') packet", kind))); - } + p = packet; + memcpy(&shortval, p, sizeof(short)); + p += sizeof(num_fields); } else { - pool_read(backend, &shortval, sizeof(short)); + ereport(ERROR, + (errmsg("do query failed, no data received for ROW DESCRIPTION ('%c') packet", kind))); } num_fields = ntohs(shortval); /* number of fields */ ereport(DEBUG5, @@ -2335,43 +2125,27 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int /* extract attribute info */ for (i = 0; i < num_fields; i++) { - if (major == PROTO_MAJOR_V3) - { - len = strlen(p) + 1; - attrinfo->attrname = palloc(len); - memcpy(attrinfo->attrname, p, len); - p += len; - memcpy(&intval, p, sizeof(int)); - attrinfo->oid = htonl(intval); - p += sizeof(int); - memcpy(&shortval, p, sizeof(short)); - attrinfo->attrnumber = htons(shortval); - p += sizeof(short); - memcpy(&intval, p, sizeof(int)); - attrinfo->typeoid = htonl(intval); - p += sizeof(int); - memcpy(&shortval, p, sizeof(short)); - attrinfo->size = htons(shortval); - p += sizeof(short); - memcpy(&intval, p, sizeof(int)); - attrinfo->mod = htonl(intval); - p += sizeof(int); - p += sizeof(short); /* skip format code since we - * use "text" anyway */ - } - else - { - p = pool_read_string(backend, &len, 0); - attrinfo->attrname = palloc(len); - memcpy(attrinfo->attrname, p, len); - pool_read(backend, &intval, sizeof(int)); - attrinfo->typeoid = ntohl(intval); - pool_read(backend, &shortval, sizeof(short)); - attrinfo->size = ntohs(shortval); - pool_read(backend, &intval, sizeof(int)); - attrinfo->mod = ntohl(intval); - } - + len = strlen(p) + 1; + attrinfo->attrname = palloc(len); + memcpy(attrinfo->attrname, p, len); + p += len; + memcpy(&intval, p, sizeof(int)); + attrinfo->oid = htonl(intval); + p += sizeof(int); + memcpy(&shortval, p, sizeof(short)); + attrinfo->attrnumber = htons(shortval); + p += sizeof(short); + memcpy(&intval, p, sizeof(int)); + attrinfo->typeoid = htonl(intval); + p += sizeof(int); + memcpy(&shortval, p, sizeof(short)); + attrinfo->size = htons(shortval); + p += sizeof(short); + memcpy(&intval, p, sizeof(int)); + attrinfo->mod = htonl(intval); + p += sizeof(int); + p += sizeof(short); /* skip format code since we + * use "text" anyway */ attrinfo++; } } @@ -2382,90 +2156,37 @@ do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int ereport(DEBUG5, (errmsg("do_query: received DATA ROW ('%c')", kind))); - if (major == PROTO_MAJOR_V3) + p = packet; + if (p) { - p = packet; - if (p) - { - memcpy(&shortval, p, sizeof(short)); - num_fields = ntohs(shortval); - p += sizeof(short); - } - else - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading data"))); - + memcpy(&shortval, p, sizeof(short)); + num_fields = ntohs(shortval); + p += sizeof(short); } + else + ereport(ERROR, + (errmsg("do query failed"), + errdetail("error while reading data"))); if (num_fields > 0) { - if (major == PROTO_MAJOR_V2) - { - nbytes = (num_fields + 7) / 8; - - if (nbytes <= 0) - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading null bitmap"))); - - - pool_read(backend, nullmap, nbytes); - } - res->numrows++; for (i = 0; i < num_fields; i++) { - if (major == PROTO_MAJOR_V3) - { - memcpy(&intval, p, sizeof(int)); - len = ntohl(intval); - p += sizeof(int); - - res->nullflags[num_data] = len; + memcpy(&intval, p, sizeof(int)); + len = ntohl(intval); + p += sizeof(int); - if (len >= 0) /* NOT NULL? */ - { - res->data[num_data] = palloc(len + 1); - memcpy(res->data[num_data], p, len); - *(res->data[num_data] + len) = '\0'; + res->nullflags[num_data] = len; - p += len; - } - } - else + if (len >= 0) /* NOT NULL? */ { - if (mask == 0) - mask = 0x80; - - /* NOT NULL? */ - if (mask & nullmap[i / 8]) - { - /* field size */ - pool_read(backend, &len, sizeof(int)); - len = ntohl(len) - 4; + res->data[num_data] = palloc(len + 1); + memcpy(res->data[num_data], p, len); + *(res->data[num_data] + len) = '\0'; - res->nullflags[num_data] = len; - - if (len >= 0) - { - p = pool_read2(backend, len); - res->data[num_data] = palloc(len + 1); - memcpy(res->data[num_data], p, len); - *(res->data[num_data] + len) = '\0'; - if (res->data[num_data] == NULL) - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading field data"))); - } - } - else - { - res->nullflags[num_data] = -1; - } - - mask >>= 1; + p += len; } num_data++; @@ -2649,10 +2370,6 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer POOL_SELECT_RESULT *result; POOL_STATUS status = POOL_CONTINUE; - /* insert_lock can be used in V3 only */ - if (MAJOR(backend) != PROTO_MAJOR_V3) - return POOL_CONTINUE; - /* get table name */ table = get_insert_command_table_name(node); @@ -2778,24 +2495,24 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer { if (pool_get_session_context(true) && pool_is_doing_extended_query_message()) { - do_query(MAIN(backend), qbuf, &result, MAJOR(backend)); + do_query(MAIN(backend), qbuf, &result); } else { - status = do_command(frontend, MAIN(backend), qbuf, MAJOR(backend), MAIN_CONNECTION(backend)->pid, + status = do_command(frontend, MAIN(backend), qbuf, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); } } else if (lock_kind == 2) { - do_query(MAIN(backend), qbuf, &result, MAJOR(backend)); + do_query(MAIN(backend), qbuf, &result); } else { POOL_SELECT_RESULT *result; /* issue row lock command */ - do_query(MAIN(backend), qbuf, &result, MAJOR(backend)); + do_query(MAIN(backend), qbuf, &result); if (status == POOL_CONTINUE) { /* does oid exist in insert_lock table? */ @@ -2811,7 +2528,7 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer per_node_statement_log(backend, MAIN_NODE_ID, qbuf); /* issue row lock command */ - do_query(MAIN(backend), qbuf, &result, MAJOR(backend)); + do_query(MAIN(backend), qbuf, &result); if (!(result && result->data[0] && !strcmp(result->data[0], "1"))) ereport(FATAL, @@ -2834,13 +2551,13 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer if (pool_get_session_context(true) && pool_is_doing_extended_query_message()) { - do_query(MAIN(backend), qbuf, &result, MAJOR(backend)); + do_query(MAIN(backend), qbuf, &result); if (result) free_select_result(result); } else { - status = do_command(frontend, MAIN(backend), qbuf, MAJOR(backend), MAIN_CONNECTION(backend)->pid, + status = do_command(frontend, MAIN(backend), qbuf, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); } } @@ -2858,7 +2575,7 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer if (VALID_BACKEND(i) && !IS_MAIN_NODE_ID(i)) { if (deadlock_detected) - status = do_command(frontend, CONNECTION(backend, i), POOL_ERROR_QUERY, PROTO_MAJOR_V3, + status = do_command(frontend, CONNECTION(backend, i), POOL_ERROR_QUERY, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); else @@ -2868,13 +2585,13 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer per_node_statement_log(backend, i, qbuf); if (pool_get_session_context(true) && pool_is_doing_extended_query_message()) { - do_query(CONNECTION(backend, i), qbuf, &result, MAJOR(backend)); + do_query(CONNECTION(backend, i), qbuf, &result); if (result) free_select_result(result); } else { - status = do_command(frontend, CONNECTION(backend, i), qbuf, PROTO_MAJOR_V3, + status = do_command(frontend, CONNECTION(backend, i), qbuf, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); } @@ -2882,7 +2599,7 @@ insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *quer else if (lock_kind == 2 || lock_kind == 3) { per_node_statement_log(backend, i, qbuf); - do_query(CONNECTION(backend, i), qbuf, &result, MAJOR(backend)); + do_query(CONNECTION(backend, i), qbuf, &result); if (result) free_select_result(result); } @@ -2952,7 +2669,7 @@ add_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char * 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)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0) != POOL_CONTINUE) ereport(ERROR, (errmsg("unable to add lock target"), @@ -3024,7 +2741,7 @@ has_lock_target(POOL_CONNECTION *frontend, } per_node_statement_log(backend, MAIN_NODE_ID, qbuf); - do_query(MAIN(backend), qbuf, &result, MAJOR(backend)); + do_query(MAIN(backend), qbuf, &result); if (result && result->data[0] && !strcmp(result->data[0], "1")) { free_select_result(result); @@ -3063,7 +2780,7 @@ 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, + status = do_command(frontend, MAIN(backend), qbuf, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); return status; @@ -3573,34 +3290,23 @@ read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, { if (kind_list[i] == 'E') { - int major = MAJOR(CONNECTION(backend, i)); - - if (major == PROTO_MAJOR_V3) - { - pool_read(CONNECTION(backend, i), &len, sizeof(len)); - if (ntohl(len) < sizeof(len)) - ereport(ERROR, - (errmsg("read_kind_from_backend: ErrorResponse length %u is below the %zu-byte minimum", - ntohl(len), sizeof(len)))); - unread_len = sizeof(len); - unread_p = palloc(ntohl(len)); - memcpy(unread_p, &len, sizeof(len)); - len = ntohl(len); - len -= 4; - unread_p = repalloc(unread_p, sizeof(len) + len); - p = pool_read2(CONNECTION(backend, i), len); - memcpy(unread_p + sizeof(len), p, len); - unread_len += len; - error_stat_count_up(i, extract_error_kind(unread_p + sizeof(len), PROTO_MAJOR_V3)); - pool_unread(CONNECTION(backend, i), unread_p, unread_len); - pfree(unread_p); - } - else if (major == PROTO_MAJOR_V2) - { - unread_p = pool_read_string(CONNECTION(backend, i), &unread_len, 0); - error_stat_count_up(i, extract_error_kind(unread_p, PROTO_MAJOR_V2)); - pool_unread(CONNECTION(backend, i), unread_p, unread_len); - } + pool_read(CONNECTION(backend, i), &len, sizeof(len)); + if (ntohl(len) < sizeof(len)) + ereport(ERROR, + (errmsg("read_kind_from_backend: ErrorResponse length %u is below the %zu-byte minimum", + ntohl(len), sizeof(len)))); + unread_len = sizeof(len); + unread_p = palloc(ntohl(len)); + memcpy(unread_p, &len, sizeof(len)); + len = ntohl(len); + len -= 4; + unread_p = repalloc(unread_p, sizeof(len) + len); + p = pool_read2(CONNECTION(backend, i), len); + memcpy(unread_p + sizeof(len), p, len); + unread_len += len; + error_stat_count_up(i, extract_error_kind(unread_p + sizeof(len))); + pool_unread(CONNECTION(backend, i), unread_p, unread_len); + pfree(unread_p); } } } @@ -3817,7 +3523,7 @@ read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, appendStringInfo(&msg, "%d[%c: ", i, kind_list[i]); - if (pool_extract_error_message(false, CONNECTION(backend, i), MAJOR(backend), true, &m) == 1) + if (pool_extract_error_message(false, CONNECTION(backend, i), true, &m) == 1) { appendStringInfoString(&msg, m); appendStringInfoString(&msg, "]"); @@ -4199,7 +3905,7 @@ start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *back { per_node_statement_log(backend, i, "BEGIN"); - if (do_command(frontend, CONNECTION(backend, i), "BEGIN", MAJOR(backend), + if (do_command(frontend, CONNECTION(backend, i), "BEGIN", MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0) != POOL_CONTINUE) ereport(ERROR, @@ -4251,7 +3957,7 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen if (VALID_BACKEND_RAW(i) && !IS_MAIN_NODE_ID(i) && INTERNAL_TRANSACTION_STARTED(backend, i)) { - if (MAJOR(backend) == PROTO_MAJOR_V3 && VALID_BACKEND(i)) + if (VALID_BACKEND(i)) { /* * Skip rest of Ready for Query packet for backends @@ -4266,7 +3972,7 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen per_node_statement_log(backend, i, "COMMIT"); PG_TRY(); { - if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), + if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 1) != POOL_CONTINUE) { @@ -4290,7 +3996,7 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen */ TSTATE(backend, i) = 'I'; - if (MAJOR(backend) == PROTO_MAJOR_V3 && !VALID_BACKEND(i)) + if (!VALID_BACKEND(i)) { /* * Skip rest of Ready for Query packet for the backend @@ -4305,7 +4011,7 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen /* Commit on main */ if (INTERNAL_TRANSACTION_STARTED(backend, MAIN_NODE_ID)) { - if (MAJOR(backend) == PROTO_MAJOR_V3 && VALID_BACKEND(MAIN_NODE_ID)) + if (VALID_BACKEND(MAIN_NODE_ID)) { /* * Skip rest of Ready for Query packet for backends satisfying @@ -4319,7 +4025,7 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen per_node_statement_log(backend, MAIN_NODE_ID, "COMMIT"); PG_TRY(); { - if (do_command(frontend, MAIN(backend), "COMMIT", MAJOR(backend), + if (do_command(frontend, MAIN(backend), "COMMIT", MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 1) != POOL_CONTINUE) { @@ -4342,7 +4048,7 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen */ TSTATE(backend, MAIN_NODE_ID) = 'I'; - if (MAJOR(backend) == PROTO_MAJOR_V3 && !VALID_BACKEND(MAIN_NODE_ID)) + if (!VALID_BACKEND(MAIN_NODE_ID)) { /* * Skip rest of Ready for Query packet for the backend that @@ -4369,11 +4075,11 @@ end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen * Returns true if error message contains PANIC or FATAL. */ static bool -is_panic_or_fatal_error(char *message, int major) +is_panic_or_fatal_error(char *message) { char *str; - str = extract_error_kind(message, major); + str = extract_error_kind(message); if (strncasecmp("PANIC", str, 5) == 0 || strncasecmp("FATAL", str, 5) == 0) return true; @@ -4387,46 +4093,38 @@ is_panic_or_fatal_error(char *message, int major) * Other wise returns "unknown". */ char * -extract_error_kind(char *message, int major) +extract_error_kind(char *message) { char *ret = "unknown"; - if (major == PROTO_MAJOR_V3) + for (;;) { - for (;;) - { - char id; + char id; - id = *message++; - if (id == '\0') - return ret; + id = *message++; + if (id == '\0') + return ret; - /* V is never localized. Only available 9.6 or later. */ - if (id == 'V') - return message; + /* V is never localized. Only available 9.6 or later. */ + if (id == 'V') + return message; - if (id == 'S') - return message; - else - { - while (*message++) - ; - continue; - } - } - } - else - { - if (strncmp(message, "PANIC", 5) == 0 || strncmp(message, "FATAL", 5) == 0) + if (id == 'S') return message; + else + { + while (*message++) + ; + continue; + } } return ret; } static int -detect_postmaster_down_error(POOL_CONNECTION *backend, int major) +detect_postmaster_down_error(POOL_CONNECTION *backend) { - int r = extract_message(backend, ADMIN_SHUTDOWN_ERROR_CODE, major, 'E', false); + int r = extract_message(backend, ADMIN_SHUTDOWN_ERROR_CODE, 'E', false); if (r < 0) { @@ -4448,7 +4146,7 @@ detect_postmaster_down_error(POOL_CONNECTION *backend, int major) return r; } - r = extract_message(backend, CRASH_SHUTDOWN_ERROR_CODE, major, 'N', false); + r = extract_message(backend, CRASH_SHUTDOWN_ERROR_CODE, 'N', false); if (r < 0) { ereport(LOG, @@ -4464,9 +4162,9 @@ detect_postmaster_down_error(POOL_CONNECTION *backend, int major) } int -detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major) +detect_active_sql_transaction_error(POOL_CONNECTION *backend) { - int r = extract_message(backend, ACTIVE_SQL_TRANSACTION_ERROR_CODE, major, 'E', true); + int r = extract_message(backend, ACTIVE_SQL_TRANSACTION_ERROR_CODE, 'E', true); if (r == SPECIFIED_ERROR) { @@ -4478,9 +4176,9 @@ detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major) } int -detect_deadlock_error(POOL_CONNECTION *backend, int major) +detect_deadlock_error(POOL_CONNECTION *backend) { - int r = extract_message(backend, DEADLOCK_ERROR_CODE, major, 'E', true); + int r = extract_message(backend, DEADLOCK_ERROR_CODE, 'E', true); if (r == SPECIFIED_ERROR) ereport(DEBUG1, @@ -4490,9 +4188,9 @@ detect_deadlock_error(POOL_CONNECTION *backend, int major) } int -detect_serialization_error(POOL_CONNECTION *backend, int major, bool unread) +detect_serialization_error(POOL_CONNECTION *backend, bool unread) { - int r = extract_message(backend, SERIALIZATION_FAIL_ERROR_CODE, major, 'E', unread); + int r = extract_message(backend, SERIALIZATION_FAIL_ERROR_CODE, 'E', unread); if (r == SPECIFIED_ERROR) ereport(DEBUG1, @@ -4502,9 +4200,9 @@ detect_serialization_error(POOL_CONNECTION *backend, int major, bool unread) } int -detect_query_cancel_error(POOL_CONNECTION *backend, int major) +detect_query_cancel_error(POOL_CONNECTION *backend) { - int r = extract_message(backend, QUERY_CANCEL_ERROR_CODE, major, 'E', true); + int r = extract_message(backend, QUERY_CANCEL_ERROR_CODE, 'E', true); if (r == SPECIFIED_ERROR) ereport(DEBUG1, @@ -4515,9 +4213,9 @@ detect_query_cancel_error(POOL_CONNECTION *backend, int major) int -detect_idle_in_transaction_session_timeout_error(POOL_CONNECTION *backend, int major) +detect_idle_in_transaction_session_timeout_error(POOL_CONNECTION *backend) { - int r = extract_message(backend, IDLE_IN_TRANSACTION_SESSION_TIMEOUT_ERROR_CODE, major, 'E', true); + int r = extract_message(backend, IDLE_IN_TRANSACTION_SESSION_TIMEOUT_ERROR_CODE, 'E', true); if (r == SPECIFIED_ERROR) ereport(DEBUG1, @@ -4527,9 +4225,9 @@ detect_idle_in_transaction_session_timeout_error(POOL_CONNECTION *backend, int m } int -detect_idle_session_timeout_error(POOL_CONNECTION *backend, int major) +detect_idle_session_timeout_error(POOL_CONNECTION *backend) { - int r = extract_message(backend, IDLE_SESSION_TIMEOUT_ERROR_CODE, major, 'E', true); + int r = extract_message(backend, IDLE_SESSION_TIMEOUT_ERROR_CODE, 'E', true); if (r == SPECIFIED_ERROR) ereport(DEBUG1, @@ -4544,7 +4242,7 @@ detect_idle_session_timeout_error(POOL_CONNECTION *backend, int major) * throw an ereport for all other errors. */ static int -extract_message(POOL_CONNECTION *backend, char *error_code, int major, char class, bool unread) +extract_message(POOL_CONNECTION *backend, char *error_code, char class, bool unread) { int is_error = 0; char kind; @@ -4562,37 +4260,30 @@ extract_message(POOL_CONNECTION *backend, char *error_code, int major, char clas /* Specified class? */ if (kind == class) { - /* read actual message */ - if (major == PROTO_MAJOR_V3) - { - char *e; + char *e; - if (pool_read(backend, &nlen, sizeof(nlen)) < 0) - return -1; + /* read actual message */ + if (pool_read(backend, &nlen, sizeof(nlen)) < 0) + return -1; - len = ntohl(nlen) - 4; - str = palloc(len); - pool_read(backend, str, len); + len = ntohl(nlen) - 4; + str = palloc(len); + pool_read(backend, str, len); - /* - * Check error code which is formatted 'Cxxxxxx' (xxxxxx is the - * error code). - */ - e = str; - while (*e) - { - if (*e == 'C') - { /* specified error? */ - is_error = (strcmp(e + 1, error_code) == 0) ? SPECIFIED_ERROR : 0; - break; - } - else - e = e + strlen(e) + 1; - } - } - else + /* + * Check error code which is formatted 'Cxxxxxx' (xxxxxx is the + * error code). + */ + e = str; + while (*e) { - str = pool_read_string(backend, &len, 0); + if (*e == 'C') + { /* specified error? */ + is_error = (strcmp(e + 1, error_code) == 0) ? SPECIFIED_ERROR : 0; + break; + } + else + e = e + strlen(e) + 1; } } @@ -4608,7 +4299,7 @@ extract_message(POOL_CONNECTION *backend, char *error_code, int major, char clas pool_unread(backend, &kind, sizeof(kind)); } - if (major == PROTO_MAJOR_V3 && str) + if (str) pfree(str); return is_error; @@ -4621,79 +4312,62 @@ extract_message(POOL_CONNECTION *backend, char *error_code, int major, char clas */ static bool -pool_process_notice_message_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int backend_idx, char kind) +pool_process_notice_message_from_one_backend(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + int backend_idx, char kind) { - int major = MAJOR(backend); POOL_CONNECTION *backend_conn = CONNECTION(backend, backend_idx); + char *e; + int len, + datalen; + char *buff; + char *errorSev = NULL; + char *errorMsg = NULL; if (kind != 'N') return false; /* read actual message */ - if (major == PROTO_MAJOR_V3) - { - char *e; - int len, - datalen; - char *buff; - char *errorSev = NULL; - char *errorMsg = NULL; + pool_read(backend_conn, &datalen, sizeof(datalen)); + len = ntohl(datalen) - 4; - pool_read(backend_conn, &datalen, sizeof(datalen)); - len = ntohl(datalen) - 4; - - if (len <= 0) - return false; - - buff = palloc(len); - - pool_read(backend_conn, buff, len); + if (len <= 0) + return false; - e = buff; + buff = palloc(len); - while (*e) - { - char tok = *e; + pool_read(backend_conn, buff, len); - e++; - if (*e == 0) - break; - if (tok == 'M') - errorMsg = e; - else if (tok == 'S') - errorSev = e; - else - e += strlen(e) + 1; + e = buff; - if (errorSev && errorMsg) /* we have all what we need */ - break; - } + while (*e) + { + char tok = *e; - /* produce a pgpool log entry */ - ereport(LOG, - (errmsg("backend [%d]: %s: %s", backend_idx, errorSev, errorMsg))); - /* forward it to the frontend */ - pool_write(frontend, &kind, 1); - pool_write(frontend, &datalen, sizeof(datalen)); - pool_write_and_flush(frontend, buff, len); + e++; + if (*e == 0) + break; + if (tok == 'M') + errorMsg = e; + else if (tok == 'S') + errorSev = e; + else + e += strlen(e) + 1; - pfree(buff); + if (errorSev && errorMsg) /* we have all what we need */ + break; } - else /* Old Protocol */ - { - int len = 0; - char *str = pool_read_string(backend_conn, &len, 0); - if (str == NULL || len <= 0) - return false; + /* produce a pgpool log entry */ + ereport(LOG, + (errmsg("backend [%d]: %s: %s", backend_idx, errorSev, errorMsg))); + /* forward it to the frontend */ + pool_write(frontend, &kind, 1); + pool_write(frontend, &datalen, sizeof(datalen)); + pool_write_and_flush(frontend, buff, len); + + pfree(buff); - /* produce a pgpool log entry */ - ereport(LOG, - (errmsg("backend [%d]: %s", backend_idx, str))); - /* forward it to the frontend */ - pool_write(frontend, &kind, 1); - pool_write_and_flush(frontend, str, len); - } return true; } @@ -4713,7 +4387,7 @@ pool_process_notice_message_from_one_backend(POOL_CONNECTION *frontend, POOL_CON * -1: error */ int -pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, bool unread, char **message) +pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, bool unread, char **message) { char kind; int ret = 1; @@ -4723,6 +4397,7 @@ pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, StringInfo str_message_buf; /* message buffer */ MemoryContext oldContext = CurrentMemoryContext; char *str; + char *e; str_buf = makeStringInfo(); str_message_buf = makeStringInfo(); @@ -4752,46 +4427,34 @@ pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, } /* read actual message */ - if (major == PROTO_MAJOR_V3) - { - char *e; - - pool_read(backend, &len, sizeof(len)); - readlen += sizeof(len); - appendBinaryStringInfo(str_buf, (const char *) &len, sizeof(len)); + pool_read(backend, &len, sizeof(len)); + readlen += sizeof(len); + appendBinaryStringInfo(str_buf, (const char *) &len, sizeof(len)); - len = ntohl(len) - 4; - str = palloc(len); + len = ntohl(len) - 4; + str = palloc(len); - pool_read(backend, str, len); - readlen += len; - appendBinaryStringInfo(str_buf, str, len); + pool_read(backend, str, len); + readlen += len; + appendBinaryStringInfo(str_buf, str, len); - /* - * Checks error code which is formatted 'Mxxxxxx' (xxxxxx is error - * message). - */ - e = str; - while (*e) + /* + * Checks error code which is formatted 'Mxxxxxx' (xxxxxx is error + * message). + */ + e = str; + while (*e) + { + if (*e == 'M') { - if (*e == 'M') - { - e++; - appendStringInfoString(str_message_buf, e); - break; - } - else - e = e + strlen(e) + 1; + e++; + appendStringInfoString(str_message_buf, e); + break; } - pfree(str); - } - else - { - str = pool_read_string(backend, &len, 0); - readlen += len; - appendBinaryStringInfo(str_message_buf, str, len); - appendBinaryStringInfo(str_buf, str, len); + else + e = e + strlen(e) + 1; } + pfree(str); if (unread) { @@ -4862,25 +4525,14 @@ pool_discard_packet_contents(POOL_CONNECTION_POOL *cp) backend = CONNECTION(cp, i); - if (MAJOR(cp) == PROTO_MAJOR_V3) - { - pool_read(backend, &len, sizeof(len)); - len = ntohl(len) - 4; - string = pool_read2(backend, len); - if (string == NULL) - ereport(ERROR, - (errmsg("pool discard packet contents failed"), - errdetail("error while reading rest of message"))); + pool_read(backend, &len, sizeof(len)); + len = ntohl(len) - 4; + string = pool_read2(backend, len); + if (string == NULL) + ereport(ERROR, + (errmsg("pool discard packet contents failed"), + errdetail("error while reading rest of message"))); - } - else - { - string = pool_read_string(backend, &len, 0); - if (string == NULL) - ereport(ERROR, - (errmsg("pool discard packet contents failed"), - errdetail("error while reading rest of message"))); - } } return POOL_CONTINUE; } @@ -5049,7 +4701,7 @@ SELECT_RETRY: /* * connection was terminated due to conflict with recovery */ - r = detect_serialization_error(CONNECTION(backend, i), MAJOR(backend), false); + r = detect_serialization_error(CONNECTION(backend, i), false); if (r == SPECIFIED_ERROR) { ereport(FATAL, @@ -5064,7 +4716,7 @@ SELECT_RETRY: * connection was terminated due to * idle_in_transaction_session_timeout expired */ - r = detect_idle_in_transaction_session_timeout_error(CONNECTION(backend, i), MAJOR(backend)); + r = detect_idle_in_transaction_session_timeout_error(CONNECTION(backend, i)); if (r == SPECIFIED_ERROR) { ereport(FATAL, @@ -5076,7 +4728,7 @@ SELECT_RETRY: * connection was terminated due to idle_session_timeout * expired */ - r = detect_idle_session_timeout_error(CONNECTION(backend, i), MAJOR(backend)); + r = detect_idle_session_timeout_error(CONNECTION(backend, i)); if (r == SPECIFIED_ERROR) { ereport(FATAL, @@ -5087,7 +4739,7 @@ SELECT_RETRY: /* * admin shutdown postmaster or postmaster goes down */ - r = detect_postmaster_down_error(CONNECTION(backend, i), MAJOR(backend)); + r = detect_postmaster_down_error(CONNECTION(backend, i)); if (r == SPECIFIED_ERROR) { ereport(LOG, diff --git a/src/protocol/pool_proto2.c b/src/protocol/pool_proto2.c deleted file mode 100644 index bd09a4494..000000000 --- a/src/protocol/pool_proto2.c +++ /dev/null @@ -1,741 +0,0 @@ -/* -*-pgsql-c-*- */ -/* - * $Header$ - * - * pgpool: a language independent connection pool server for PostgreSQL - * written by Tatsuo Ishii - * - * Copyright (c) 2003-2019 PgPool Global Development Group - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that the above copyright notice appear in all - * copies and that both that copyright notice and this permission - * notice appear in supporting documentation, and that the name of the - * author not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. The author makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - *--------------------------------------------------------------------- - * pool_proto2.c: modules corresponding to protocol 2.0. - * used by pool_process_query() - *--------------------------------------------------------------------- - */ -#include -#include -#include - -#include "pool.h" -#include "pool_config.h" -#include "protocol/pool_proto_modules.h" -#include "utils/pool_stream.h" -#include "utils/elog.h" - -POOL_STATUS -AsciiRow(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short num_fields) -{ - static char nullmap[8192], - nullmap1[8192]; - int nbytes; - int i, - j; - unsigned char mask; - int size, - size1 = 0; - char *buf = NULL, - *sendbuf = NULL; - char msgbuf[1024]; - - pool_write(frontend, "D", 1); - - nbytes = (num_fields + 7) / 8; - - if (nbytes <= 0) - return POOL_CONTINUE; - - /* NULL map */ - pool_read(MAIN(backend), nullmap, nbytes); - memcpy(nullmap1, nullmap, nbytes); - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i) && !IS_MAIN_NODE_ID(i)) - { - pool_read(CONNECTION(backend, i), nullmap, nbytes); - if (memcmp(nullmap, nullmap1, nbytes)) - { - /* - * XXX: NULLMAP maybe different among backends. If we were a - * paranoid, we have to treat this as a fatal error. However - * in the real world we'd better to adapt this situation. Just - * throw a log... - */ - ereport(DEBUG1, - (errmsg("processing ASCII row"), - errdetail("NULLMAP is different between main and backend no %d", i))); - } - } - } - - if (pool_write(frontend, nullmap1, nbytes) < 0) - return POOL_END; - - mask = 0; - - for (i = 0; i < num_fields; i++) - { - if (mask == 0) - mask = 0x80; - - /* NOT NULL? */ - if (mask & nullmap[i / 8]) - { - /* field size */ - if (pool_read(MAIN(backend), &size, sizeof(int)) < 0) - return POOL_END; - - size1 = ntohl(size) - 4; - - /* read and send actual data only when size > 0 */ - if (size1 > 0) - { - sendbuf = pool_read2(MAIN(backend), size1); - if (sendbuf == NULL) - return POOL_END; - } - - /* forward to frontend */ - pool_write(frontend, &size, sizeof(int)); - if (size1 > 0) - pool_write(frontend, sendbuf, size1); - snprintf(msgbuf, Min(sizeof(msgbuf), size1 + 1), "%s", sendbuf); - ereport(DEBUG1, - (errmsg("processing ASCII row"), - errdetail("len: %d data: %s", size1, msgbuf))); - - - for (j = 0; j < NUM_BACKENDS; j++) - { - if (VALID_BACKEND(j) && !IS_MAIN_NODE_ID(j)) - { - /* field size */ - if (pool_read(CONNECTION(backend, j), &size, sizeof(int)) < 0) - return POOL_END; - - buf = NULL; - size = ntohl(size) - 4; - - /* - * XXX: field size maybe different among backends. If we - * were a paranoid, we have to treat this as a fatal - * error. However in the real world we'd better to adapt - * this situation. Just throw a log... - */ - if (size != size1) - ereport(DEBUG1, - (errmsg("processing ASCII row"), - errdetail("size of field no %d does not match between main [size:%d] and backend no %d [size:%d]", - i, ntohl(size), j, ntohl(size1)))); - - /* read and send actual data only when size > 0 */ - if (size > 0) - { - buf = pool_read2(CONNECTION(backend, j), size); - if (buf == NULL) - return POOL_END; - } - } - } - } - - mask >>= 1; - } - - if (pool_flush(frontend)) - return POOL_END; - - return POOL_CONTINUE; -} - -POOL_STATUS -BinaryRow(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short num_fields) -{ - static char nullmap[8192], - nullmap1[8192]; - int nbytes; - int i, - j; - unsigned char mask; - int size, - size1 = 0; - char *buf = NULL; - - pool_write(frontend, "B", 1); - - nbytes = (num_fields + 7) / 8; - - if (nbytes <= 0) - return POOL_CONTINUE; - - /* NULL map */ - pool_read(MAIN(backend), nullmap, nbytes); - if (pool_write(frontend, nullmap, nbytes) < 0) - return POOL_END; - memcpy(nullmap1, nullmap, nbytes); - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i) && !IS_MAIN_NODE_ID(i)) - { - pool_read(CONNECTION(backend, i), nullmap, nbytes); - if (memcmp(nullmap, nullmap1, nbytes)) - { - /* - * XXX: NULLMAP maybe different among backends. If we were a - * paranoid, we have to treat this as a fatal error. However - * in the real world we'd better to adapt this situation. Just - * throw a log... - */ - ereport(DEBUG1, - (errmsg("processing binary row"), - errdetail("NULLMAP is different between main and backend no %d", i))); - } - } - } - - mask = 0; - - for (i = 0; i < num_fields; i++) - { - if (mask == 0) - mask = 0x80; - - /* NOT NULL? */ - if (mask & nullmap[i / 8]) - { - /* field size */ - if (pool_read(MAIN(backend), &size, sizeof(int)) < 0) - return POOL_END; - for (j = 0; j < NUM_BACKENDS; j++) - { - if (VALID_BACKEND(j) && !IS_MAIN_NODE_ID(j)) - { - /* field size */ - if (pool_read(CONNECTION(backend, i), &size, sizeof(int)) < 0) - return POOL_END; - - /* - * XXX: field size maybe different among backends. If we - * were a paranoid, we have to treat this as a fatal - * error. However in the real world we'd better to adapt - * this situation. Just throw a log... - */ - if (size != size1) - ereport(DEBUG1, - (errmsg("processing binary row"), - errdetail("size of field no %d does not match between main [size:%d] and backend no %d [size:%d]", - i, ntohl(size), j, ntohl(size1)))); - } - - buf = NULL; - - /* forward to frontend */ - if (IS_MAIN_NODE_ID(j)) - pool_write(frontend, &size, sizeof(int)); - size = ntohl(size) - 4; - - /* read and send actual data only when size > 0 */ - if (size > 0) - { - buf = pool_read2(CONNECTION(backend, j), size); - if (buf == NULL) - return POOL_END; - - if (IS_MAIN_NODE_ID(j)) - { - pool_write(frontend, buf, size); - } - } - } - - mask >>= 1; - } - } - - if (pool_flush(frontend)) - return POOL_END; - - return POOL_CONTINUE; -} - -POOL_STATUS -CompletedResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - int i; - char *string = NULL; - char *string1 = NULL; - int len, - len1 = 0; - - /* read command tag */ - string = pool_read_string(MAIN(backend), &len, 0); - if (string == NULL) - return POOL_END; - else if (!strncmp(string, "BEGIN", 5)) - TSTATE(backend, MAIN_NODE_ID) = 'T'; - else if (!strncmp(string, "COMMIT", 6) || !strncmp(string, "ROLLBACK", 8)) - TSTATE(backend, MAIN_NODE_ID) = 'I'; - - len1 = len; - string1 = pstrdup(string); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (!VALID_BACKEND(i) || IS_MAIN_NODE_ID(i)) - continue; - - /* read command tag */ - string = pool_read_string(CONNECTION(backend, i), &len, 0); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process completed response"), - errdetail("read from backend node %d failed", i))); - - else if (!strncmp(string, "BEGIN", 5)) - TSTATE(backend, i) = 'T'; - else if (!strncmp(string, "COMMIT", 6) || !strncmp(string, "ROLLBACK", 8)) - TSTATE(backend, i) = 'I'; - - if (len != len1) - { - ereport(DEBUG1, - (errmsg("processing completed response"), - errdetail("message length does not match between main(%d \"%s\",) and %d th server (%d \"%s\",)", - len, string, i, len1, string1))); - - /* we except INSERT, because INSERT response has OID */ - if (strncmp(string1, "INSERT", 6)) - { - pfree(string1); - return POOL_END; - } - } - } - /* forward to the frontend */ - pool_write(frontend, "C", 1); - ereport(DEBUG2, - (errmsg("processing completed response"), - errdetail("string: \"%s\"", string1))); - pool_write(frontend, string1, len1); - - pfree(string1); - return pool_flush(frontend); -} - -POOL_STATUS -CursorResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - char *string = NULL; - char *string1 = NULL; - int len, - len1 = 0; - int i; - - /* read cursor name */ - string = pool_read_string(MAIN(backend), &len, 0); - if (string == NULL) - return POOL_END; - len1 = len; - string1 = pstrdup(string); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i) && !IS_MAIN_NODE_ID(i)) - { - /* read cursor name */ - string = pool_read_string(CONNECTION(backend, i), &len, 0); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process cursor response"), - errdetail("read failed on backend node %d", i))); - if (len != len1) - { - ereport(FATAL, - (return_code(2), - errmsg("unable to process cursor response"), - errdetail("length does not match between main(%d) and %d th backend(%d)", len, i, len1), - errhint("main(%s) %d th backend(%s)", string1, i, string))); - } - } - } - - /* forward to the frontend */ - pool_write(frontend, "P", 1); - pool_write(frontend, string1, len1); - pool_flush(frontend); - pfree(string1); - - return POOL_CONTINUE; -} - -void -EmptyQueryResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - char c; - int i; - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - pool_read(CONNECTION(backend, i), &c, sizeof(c)); - } - } - - pool_write(frontend, "I", 1); - pool_write_and_flush(frontend, "", 1); -} - -POOL_STATUS -ErrorResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - char *string = ""; - int len = 0; - int i; - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - /* read error message */ - string = pool_read_string(CONNECTION(backend, i), &len, 0); - if (string == NULL) - return POOL_END; - } - } - /* forward to the frontend */ - pool_write(frontend, "E", 1); - pool_write_and_flush(frontend, string, len); - - /* - * check session context, because this function is called by pool_do_auth - * too. - */ - if (pool_get_session_context(true)) - raise_intentional_error_if_need(backend); - - /* change transaction state */ - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - if (TSTATE(backend, i) == 'T') - TSTATE(backend, i) = 'E'; - } - } - - return POOL_CONTINUE; -} - -POOL_STATUS -FunctionResultResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - char dummy; - int len; - char *result = NULL; - int i; - - pool_write(frontend, "V", 1); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - pool_read(CONNECTION(backend, i), &dummy, 1); - } - } - pool_write(frontend, &dummy, 1); - - /* non empty result? */ - if (dummy == 'G') - { - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - /* length of result in bytes */ - pool_read(CONNECTION(backend, i), &len, sizeof(len)); - } - } - pool_write(frontend, &len, sizeof(len)); - - len = ntohl(len); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - /* result value itself */ - if ((result = pool_read2(MAIN(backend), len)) == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process function result response"), - errdetail("reading from backend node %d failed", i))); - } - } - if (result) - pool_write(frontend, result, len); - else - ereport(FATAL, - (return_code(2), - errmsg("unable to process function result response"), - errdetail("reading from backend node failed"))); - } - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - /* unused ('0') */ - pool_read(MAIN(backend), &dummy, 1); - } - } - pool_write(frontend, "0", 1); - - return pool_flush(frontend); -} - -void -NoticeResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - char *string = NULL; - int len = 0; - int i; - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - /* read notice message */ - string = pool_read_string(CONNECTION(backend, i), &len, 0); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process Notice response"), - errdetail("reading from backend node %d failed", i))); - } - } - - /* forward to the frontend */ - pool_write(frontend, "N", 1); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process Notice response"), - errdetail("reading from backend node failed"))); - else - pool_write_and_flush(frontend, string, len); -} - -POOL_STATUS -NotificationResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) -{ - int pid, - pid1; - char *condition, - *condition1 = NULL; - int len, - len1 = 0; - int i; - - pool_write(frontend, "A", 1); - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - pool_read(CONNECTION(backend, i), &pid, sizeof(pid)); - condition = pool_read_string(CONNECTION(backend, i), &len, 0); - if (condition == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process Notification response"), - errdetail("reading from backend node %d failed", i))); - - if (IS_MAIN_NODE_ID(i)) - { - pid1 = pid; - len1 = len; - if (condition1) - pfree(condition1); - condition1 = pstrdup(condition); - } - } - } - - pool_write(frontend, &pid1, sizeof(pid1)); - pool_write_and_flush(frontend, condition1, len1); - pfree(condition1); - return POOL_CONTINUE; -} - -int -RowDescription(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short *result) -{ - short num_fields, - num_fields1 = 0; - int oid, - mod; - int oid1, - mod1; - short size, - size1; - char *string; - int len, - len1; - int i; - - pool_read(MAIN(backend), &num_fields, sizeof(short)); - num_fields1 = num_fields; - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i) && !IS_MAIN_NODE_ID(i)) - { - /* # of fields (could be 0) */ - pool_read(CONNECTION(backend, i), &num_fields, sizeof(short)); - if (num_fields != num_fields1) - { - ereport(FATAL, - (return_code(2), - errmsg("unable to process row description"), - errdetail("num_fields does not match between backends main(%d) and %d th backend(%d)", - num_fields, i, num_fields1))); - } - } - } - - /* forward it to the frontend */ - pool_write(frontend, "T", 1); - pool_write(frontend, &num_fields, sizeof(short)); - num_fields = ntohs(num_fields); - for (i = 0; i < num_fields; i++) - { - int j; - - /* field name */ - string = pool_read_string(MAIN(backend), &len, 0); - if (string == NULL) - return POOL_END; - len1 = len; - pool_write(frontend, string, len); - - for (j = 0; j < NUM_BACKENDS; j++) - { - if (VALID_BACKEND(j) && !IS_MAIN_NODE_ID(j)) - { - string = pool_read_string(CONNECTION(backend, j), &len, 0); - if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process row description"), - errdetail("read failed on backend node %d", j))); - - if (len != len1) - { - ereport(FATAL, - (return_code(2), - errmsg("unable to process row description"), - errdetail("field length does not match between backends main(%d) and %d th backend(%d)", - ntohl(len), j, ntohl(len1)))); - } - } - } - - /* type oid */ - pool_read(MAIN(backend), &oid, sizeof(int)); - oid1 = oid; - ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("type oid: %d", ntohl(oid)))); - for (j = 0; j < NUM_BACKENDS; j++) - { - if (VALID_BACKEND(j) && !IS_MAIN_NODE_ID(j)) - { - pool_read(CONNECTION(backend, j), &oid, sizeof(int)); - - /* we do not regard oid mismatch as fatal */ - if (oid != oid1) - { - ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("field oid does not match between backends main(%d) and %d th backend(%d)", - ntohl(oid), j, ntohl(oid1)))); - } - } - } - pool_write(frontend, &oid1, sizeof(int)); - - /* size */ - pool_read(MAIN(backend), &size, sizeof(short)); - size1 = size; - for (j = 0; j < NUM_BACKENDS; j++) - { - if (VALID_BACKEND(j) && !IS_MAIN_NODE_ID(j)) - { - pool_read(CONNECTION(backend, j), &size, sizeof(short)); - if (size1 != size) - { - ereport(FATAL, - (errmsg("data among backends are different"), - errdetail("field size does not match between backends main(%d) and %d th backend(%d", ntohs(size), j, ntohs(size1)))); - - } - } - } - ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("field size: %d", ntohs(size)))); - pool_write(frontend, &size1, sizeof(short)); - - /* modifier */ - pool_read(MAIN(backend), &mod, sizeof(int)); - ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("modifier: %d", ntohs(mod)))); - mod1 = mod; - for (j = 0; j < NUM_BACKENDS; j++) - { - if (VALID_BACKEND(j) && !IS_MAIN_NODE_ID(j)) - { - pool_read(CONNECTION(backend, j), &mod, sizeof(int)); - if (mod != mod1) - { - ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("modifier does not match between backends main(%d) and %d th backend(%d)", - ntohl(mod), j, ntohl(mod1)))); - } - } - } - pool_write(frontend, &mod1, sizeof(int)); - } - - *result = num_fields; - - return pool_flush(frontend); -} diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c index 6d98c0094..07b1ccbe7 100644 --- a/src/protocol/pool_proto_modules.c +++ b/src/protocol/pool_proto_modules.c @@ -747,17 +747,6 @@ SimpleQuery(POOL_CONNECTION *frontend, } } - if (MAJOR(backend) == PROTO_MAJOR_V2 && is_start_transaction_query(node)) - { - int i; - - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - TSTATE(backend, i) = 'T'; - } - } - if (node) { POOL_SENT_MESSAGE *msg = NULL; @@ -1701,7 +1690,7 @@ Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, * detecting deadlock isn't same on all nodes. If a transaction is * aborted on main node, pgpool send a error query to another nodes. */ - deadlock_detected = detect_deadlock_error(MAIN(backend), MAJOR(backend)); + deadlock_detected = detect_deadlock_error(MAIN(backend)); /* * Check if other than deadlock error detected. If so, emit log. This @@ -1803,7 +1792,7 @@ Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, /* send error message to frontend */ errmessage = psprintf("prepared statement \"%s\" does not exist", pstmt_name); - pool_send_error_message(frontend, MAJOR(cp), "XX000", errmessage, + pool_send_error_message(frontend, "XX000", errmessage, "", "", __FILE__, __LINE__); pfree(errmessage); @@ -2323,9 +2312,9 @@ ReadyForQuery(POOL_CONNECTION *frontend, * If the numbers of update tuples are differ and * failover_if_affected_tuples_mismatch is false, we abort transactions by * using do_error_command. If failover_if_affected_tuples_mismatch is - * true, trigger failover. This only works with PROTO_MAJOR_V3. + * true, trigger failover. */ - if (session_context->mismatch_ntuples && MAJOR(backend) == PROTO_MAJOR_V3) + if (session_context->mismatch_ntuples) { int i; char kind; @@ -2397,7 +2386,7 @@ ReadyForQuery(POOL_CONNECTION *frontend, if (VALID_BACKEND(i)) { /* abort transaction on all nodes. */ - do_error_command(CONNECTION(backend, i), PROTO_MAJOR_V3); + do_error_command(CONNECTION(backend, i)); } } @@ -2468,47 +2457,44 @@ ReadyForQuery(POOL_CONNECTION *frontend, } } - if (MAJOR(backend) == PROTO_MAJOR_V3) + if ((len = pool_read_message_length(backend)) < 0) + return POOL_END; + + /* + * Set transaction state for each node + */ + state = TSTATE(backend, + MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID); + + for (i = 0; i < NUM_BACKENDS; i++) { - if ((len = pool_read_message_length(backend)) < 0) + if (!VALID_BACKEND(i)) + continue; + + if (pool_read(CONNECTION(backend, i), &kind, sizeof(kind))) return POOL_END; + TSTATE(backend, i) = kind; + ereport(DEBUG5, + (errmsg("processing ReadyForQuery"), + errdetail("transaction state of node %d '%c'(%02x)", i, kind, kind))); + /* - * Set transaction state for each node + * The transaction state to be returned to frontend is main + * node's. */ - state = TSTATE(backend, - MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID); - - for (i = 0; i < NUM_BACKENDS; i++) + if (i == (MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID)) { - if (!VALID_BACKEND(i)) - continue; - - if (pool_read(CONNECTION(backend, i), &kind, sizeof(kind))) - return POOL_END; - - TSTATE(backend, i) = kind; - ereport(DEBUG5, - (errmsg("processing ReadyForQuery"), - errdetail("transaction state of node %d '%c'(%02x)", i, kind, kind))); - - /* - * The transaction state to be returned to frontend is main - * node's. - */ - if (i == (MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID)) - { - state = kind; - } - - /* - * However, if the state is 'E', then frontend should had been - * already reported an ERROR. So, to match with that, let be the - * state to be returned to frontend. - */ - if (kind == 'E') - got_estate = true; + state = kind; } + + /* + * However, if the state is 'E', then frontend should had been + * already reported an ERROR. So, to match with that, let be the + * state to be returned to frontend. + */ + if (kind == 'E') + got_estate = true; } /* @@ -2536,14 +2522,11 @@ ReadyForQuery(POOL_CONNECTION *frontend, { pool_write(frontend, "Z", 1); - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - len = htonl(len); - pool_write(frontend, &len, sizeof(len)); - if (got_estate) - state = 'E'; - pool_write(frontend, &state, 1); - } + len = htonl(len); + pool_write(frontend, &len, sizeof(len)); + if (got_estate) + state = 'E'; + pool_write(frontend, &state, 1); pool_flush(frontend); /* @@ -2597,11 +2580,6 @@ ReadyForQuery(POOL_CONNECTION *frontend, } else { - if (MAJOR(backend) != PROTO_MAJOR_V3) - { - state = 'I'; /* XXX I don't think query cache works - * with PROTO2 protocol */ - } pool_handle_query_cache(backend, query, node, state, false); } } @@ -2676,7 +2654,7 @@ close_standby_transactions(POOL_CONNECTION *frontend, (MAIN_REPLICA ? PRIMARY_NODE_ID : REAL_MAIN_NODE_ID) != i) { per_node_statement_log(backend, i, "COMMIT"); - if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), + if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0) != POOL_CONTINUE) ereport(ERROR, @@ -3040,26 +3018,17 @@ ProcessFrontendResponse(POOL_CONNECTION *frontend, (errmsg("processing frontend response"), errdetail("received kind '%c'(%02x) from frontend", fkind, fkind))); + if (pool_read(frontend, &len, sizeof(len)) < 0) + ereport(ERROR, + (errmsg("unable to process frontend response"), + errdetail("failed to read message length from frontend. frontend abnormally exited"))); - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - if (pool_read(frontend, &len, sizeof(len)) < 0) - ereport(ERROR, - (errmsg("unable to process frontend response"), - errdetail("failed to read message length from frontend. frontend abnormally exited"))); - - len = ntohl(len) - 4; - if (len > 0) - bufp = pool_read2(frontend, len); - else if (len < 0) - ereport(ERROR, - (errmsg("frontend message length is less than 4 (kind: %c)", fkind))); - } - else - { - if (fkind != 'F') - bufp = pool_read_string(frontend, &len, 0); - } + len = ntohl(len) - 4; + if (len > 0) + bufp = pool_read2(frontend, len); + else if (len < 0) + ereport(ERROR, + (errmsg("frontend message length is less than 4 (kind: %c)", fkind))); if (len > 0 && bufp == NULL) ereport(ERROR, @@ -3239,11 +3208,7 @@ ProcessFrontendResponse(POOL_CONNECTION *frontend, pool_where_to_send(query_context, query_context->original_query, query_context->parse_tree); - if (MAJOR(backend) == PROTO_MAJOR_V3) - status = FunctionCall3(frontend, backend, len, contents); - else - status = FunctionCall(frontend, backend); - + status = FunctionCall3(frontend, backend, len, contents); break; case 'c': /* CopyDone */ @@ -3253,33 +3218,29 @@ ProcessFrontendResponse(POOL_CONNECTION *frontend, if (fkind == 'H' && pool_config->log_client_messages) ereport(LOG, (errmsg("Flush message from frontend."))); - if (MAJOR(backend) == PROTO_MAJOR_V3) + if (fkind == 'H') { - if (fkind == 'H') - { - /* - * If data remains in the frontend write buffer, flush it - * now. - */ - pool_flush(frontend); - elog(DEBUG5, - "pending data flushed to frontend due to a flush message"); - pool_set_doing_extended_query_message(); - pool_pending_message_set_flush_request(); - } - status = SimpleForwardToBackend(fkind, frontend, backend, len, contents); - /* - * After flush message received, extended query mode should be - * continued. + * If data remains in the frontend write buffer, flush it + * now. */ - if (fkind != 'H' && pool_is_doing_extended_query_message()) - { - pool_unset_doing_extended_query_message(); - } + pool_flush(frontend); + elog(DEBUG5, + "pending data flushed to frontend due to a flush message"); + pool_set_doing_extended_query_message(); + pool_pending_message_set_flush_request(); + } + status = SimpleForwardToBackend(fkind, frontend, backend, len, contents); - break; + /* + * After flush message received, extended query mode should be + * continued. + */ + if (fkind != 'H' && pool_is_doing_extended_query_message()) + { + pool_unset_doing_extended_query_message(); } + break; default: ereport(FATAL, @@ -3349,260 +3310,190 @@ ProcessBackendResponse(POOL_CONNECTION *frontend, errdetail("received kind '%c'(%02x) from backend", kind, kind))); - if (MAJOR(backend) == PROTO_MAJOR_V3) + switch (kind) { - switch (kind) - { - case 'G': /* CopyInResponse */ - status = CopyInResponse(frontend, backend); - break; + case 'G': /* CopyInResponse */ + status = CopyInResponse(frontend, backend); + break; - case 'S': /* ParameterStatus */ - status = ParameterStatus(frontend, backend); - break; + case 'S': /* ParameterStatus */ + status = ParameterStatus(frontend, backend); + break; - case 'Z': /* ReadyForQuery */ - ereport(DEBUG5, - (errmsg("processing backend response"), - errdetail("Ready For Query received"))); - pool_unset_suspend_reading_from_frontend(); - pool_unset_suspend_reading_from_frontend_copy_in(); - status = ReadyForQuery(frontend, backend, true, true); + case 'Z': /* ReadyForQuery */ + ereport(DEBUG5, + (errmsg("processing backend response"), + errdetail("Ready For Query received"))); + pool_unset_suspend_reading_from_frontend(); + pool_unset_suspend_reading_from_frontend_copy_in(); + status = ReadyForQuery(frontend, backend, true, true); #ifdef DEBUG - extern bool stop_now; + extern bool stop_now; - if (stop_now) - exit(0); + if (stop_now) + exit(0); #endif - break; - - case '1': /* ParseComplete */ - if (SL_MODE) - { - POOL_PENDING_MESSAGE *pmsg; - - pmsg = pool_pending_message_get_previous_message(); - if (pmsg && pmsg->not_forward_to_frontend) - { - /* - * parse_before_bind() was called. Do not forward the - * parse complete message to frontend. - */ - ereport(DEBUG5, - (errmsg("processing backend response"), - errdetail("do not forward parse complete message to frontend"))); - pool_discard_packet_contents(backend); - pool_unset_query_in_progress(); - pool_set_command_success(); - status = POOL_CONTINUE; - break; - } - } - status = ParseComplete(frontend, backend); - pool_set_command_success(); - pool_unset_query_in_progress(); - break; + break; - case '2': /* BindComplete */ - status = BindComplete(frontend, backend); - pool_set_command_success(); - pool_unset_query_in_progress(); - break; + case '1': /* ParseComplete */ + if (SL_MODE) + { + POOL_PENDING_MESSAGE *pmsg; - case '3': /* CloseComplete */ - if (SL_MODE) + pmsg = pool_pending_message_get_previous_message(); + if (pmsg && pmsg->not_forward_to_frontend) { - POOL_PENDING_MESSAGE *pmsg; - - pmsg = pool_pending_message_get_previous_message(); - if (pmsg && pmsg->not_forward_to_frontend) - { - /* - * parse_before_bind() was called. Do not forward the - * close complete message to frontend. - */ - ereport(DEBUG5, - (errmsg("processing backend response"), - errdetail("do not forward close complete message to frontend"))); - pool_discard_packet_contents(backend); - - /* - * Remove pending message here because - * read_kind_from_backend() did not do it. - */ - pmsg = pool_pending_message_pull_out(); - pool_pending_message_free_pending_message(pmsg); - - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - pool_set_command_success(); - status = POOL_CONTINUE; - break; - } + /* + * parse_before_bind() was called. Do not forward the + * parse complete message to frontend. + */ + ereport(DEBUG5, + (errmsg("processing backend response"), + errdetail("do not forward parse complete message to frontend"))); + pool_discard_packet_contents(backend); + pool_unset_query_in_progress(); + pool_set_command_success(); + status = POOL_CONTINUE; + break; } + } + status = ParseComplete(frontend, backend); + pool_set_command_success(); + pool_unset_query_in_progress(); + break; - status = CloseComplete(frontend, backend); - pool_set_command_success(); - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - break; + case '2': /* BindComplete */ + status = BindComplete(frontend, backend); + pool_set_command_success(); + pool_unset_query_in_progress(); + break; - case 'E': /* ErrorResponse */ - if (pool_is_doing_extended_query_message()) - { - char *message; + case '3': /* CloseComplete */ + if (SL_MODE) + { + POOL_PENDING_MESSAGE *pmsg; + pmsg = pool_pending_message_get_previous_message(); + if (pmsg && pmsg->not_forward_to_frontend) + { /* - * Log the error message which was possibly missed till a - * sync message was sent + * parse_before_bind() was called. Do not forward the + * close complete message to frontend. */ - if (pool_extract_error_message(false, MAIN(backend), PROTO_MAJOR_V3, - true, &message) == 1) - { - ereport(LOG, - (errmsg("Error message from backend: DB node id: %d message: \"%s\"", - MAIN_NODE_ID, message))); - pfree(message); - } - } + ereport(DEBUG5, + (errmsg("processing backend response"), + errdetail("do not forward close complete message to frontend"))); + pool_discard_packet_contents(backend); - /* Forward the error message to frontend */ - status = ErrorResponse3(frontend, backend); - pool_unset_command_success(); - if (TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : - REAL_MAIN_NODE_ID) != 'I') - { - pool_set_failed_transaction(); + /* + * Remove pending message here because + * read_kind_from_backend() did not do it. + */ + pmsg = pool_pending_message_pull_out(); + pool_pending_message_free_pending_message(pmsg); - /* Remove ongoing CREATE/DROP temp tables */ - pool_temp_tables_remove_pending(); - } - if (pool_is_doing_extended_query_message()) - { - pool_set_ignore_till_sync(); - pool_unset_query_in_progress(); - pool_unset_suspend_reading_from_frontend(); - if (SL_MODE) - pool_discard_except_sync_and_ready_for_query(frontend, backend); + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + pool_set_command_success(); + status = POOL_CONTINUE; + break; } - break; - - case 'C': /* CommandComplete */ - status = CommandComplete(frontend, backend, true); - pool_set_command_success(); - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - break; + } - case 't': /* ParameterDescription */ - status = ParameterDescription(frontend, backend); - break; + status = CloseComplete(frontend, backend); + pool_set_command_success(); + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + break; - case 'I': /* EmptyQueryResponse */ - status = CommandComplete(frontend, backend, false); + case 'E': /* ErrorResponse */ + if (pool_is_doing_extended_query_message()) + { + char *message; /* - * Empty query response message should be treated same as - * Command complete message. When we receive the Command - * complete message, we unset the query in progress flag if - * operated in streaming replication mode. So we unset the - * flag as well. See bug 190 for more details. + * Log the error message which was possibly missed till a + * sync message was sent */ - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - break; - - case 'T': /* RowDescription */ - status = SimpleForwardToFrontend(kind, frontend, backend); - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - break; - - case 'n': /* NoData */ - status = SimpleForwardToFrontend(kind, frontend, backend); - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - break; - - case 's': /* PortalSuspended */ - status = SimpleForwardToFrontend(kind, frontend, backend); - if (pool_is_doing_extended_query_message()) - pool_unset_query_in_progress(); - break; - - default: - status = SimpleForwardToFrontend(kind, frontend, backend); - break; - } - - pool_get_session_context(false)->flush_pending = false; - - } - else - { - switch (kind) - { - case 'A': /* NotificationResponse */ - status = NotificationResponse(frontend, backend); - break; - - case 'B': /* BinaryRow */ - status = BinaryRow(frontend, backend, *num_fields); - break; - - case 'C': /* CompletedResponse */ - status = CompletedResponse(frontend, backend); - break; + if (pool_extract_error_message(false, MAIN(backend), + true, &message) == 1) + { + ereport(LOG, + (errmsg("Error message from backend: DB node id: %d message: \"%s\"", + MAIN_NODE_ID, message))); + pfree(message); + } + } - case 'D': /* AsciiRow */ - status = AsciiRow(frontend, backend, *num_fields); - break; + /* Forward the error message to frontend */ + status = ErrorResponse3(frontend, backend); + pool_unset_command_success(); + if (TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : + REAL_MAIN_NODE_ID) != 'I') + { + pool_set_failed_transaction(); - case 'E': /* ErrorResponse */ - status = ErrorResponse(frontend, backend); - if (TSTATE(backend, MAIN_REPLICA ? PRIMARY_NODE_ID : - REAL_MAIN_NODE_ID) != 'I') - pool_set_failed_transaction(); - break; + /* Remove ongoing CREATE/DROP temp tables */ + pool_temp_tables_remove_pending(); + } + if (pool_is_doing_extended_query_message()) + { + pool_set_ignore_till_sync(); + pool_unset_query_in_progress(); + pool_unset_suspend_reading_from_frontend(); + if (SL_MODE) + pool_discard_except_sync_and_ready_for_query(frontend, backend); + } + break; - case 'G': /* CopyInResponse */ - status = CopyInResponse(frontend, backend); - break; + case 'C': /* CommandComplete */ + status = CommandComplete(frontend, backend, true); + pool_set_command_success(); + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + break; - case 'H': /* CopyOutResponse */ - status = CopyOutResponse(frontend, backend); - break; + case 't': /* ParameterDescription */ + status = ParameterDescription(frontend, backend); + break; - case 'I': /* EmptyQueryResponse */ - EmptyQueryResponse(frontend, backend); - break; + case 'I': /* EmptyQueryResponse */ + status = CommandComplete(frontend, backend, false); - case 'N': /* NoticeResponse */ - NoticeResponse(frontend, backend); - break; + /* + * Empty query response message should be treated same as + * Command complete message. When we receive the Command + * complete message, we unset the query in progress flag if + * operated in streaming replication mode. So we unset the + * flag as well. See bug 190 for more details. + */ + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + break; - case 'P': /* CursorResponse */ - status = CursorResponse(frontend, backend); - break; + case 'T': /* RowDescription */ + status = SimpleForwardToFrontend(kind, frontend, backend); + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + break; - case 'T': /* RowDescription */ - status = RowDescription(frontend, backend, num_fields); - break; + case 'n': /* NoData */ + status = SimpleForwardToFrontend(kind, frontend, backend); + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + break; - case 'V': /* FunctionResultResponse and - * FunctionVoidResponse */ - status = FunctionResultResponse(frontend, backend); - break; + case 's': /* PortalSuspended */ + status = SimpleForwardToFrontend(kind, frontend, backend); + if (pool_is_doing_extended_query_message()) + pool_unset_query_in_progress(); + break; - case 'Z': /* ReadyForQuery */ - status = ReadyForQuery(frontend, backend, true, true); - break; + default: + status = SimpleForwardToFrontend(kind, frontend, backend); + break; - default: - ereport(FATAL, - (return_code(1), - errmsg("Unknown message type %c(%02x)", kind, kind))); - } + pool_get_session_context(false)->flush_pending = false; } /* @@ -3628,14 +3519,8 @@ CopyInResponse(POOL_CONNECTION *frontend, POOL_STATUS status; /* forward to the frontend */ - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - SimpleForwardToFrontend('G', frontend, backend); - pool_flush(frontend); - } - else - pool_write_and_flush(frontend, "G", 1); - + SimpleForwardToFrontend('G', frontend, backend); + pool_flush(frontend); status = CopyDataRows(frontend, backend, 1); return status; } @@ -3647,14 +3532,8 @@ CopyOutResponse(POOL_CONNECTION *frontend, POOL_STATUS status; /* forward to the frontend */ - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - SimpleForwardToFrontend('H', frontend, backend); - pool_flush(frontend); - } - else - pool_write_and_flush(frontend, "H", 1); - + SimpleForwardToFrontend('H', frontend, backend); + pool_flush(frontend); status = CopyDataRows(frontend, backend, 0); return status; } @@ -3678,87 +3557,69 @@ CopyDataRows(POOL_CONNECTION *frontend, { if (copyin) { - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - char kind; - char *contents = NULL; - - pool_unset_suspend_reading_from_frontend_copy_in(); + char kind; + char *contents = NULL; - pool_read(frontend, &kind, 1); + pool_unset_suspend_reading_from_frontend_copy_in(); - ereport(DEBUG5, - (errmsg("copy data rows"), - errdetail("read kind from frontend %c(%02x)", kind, kind))); + pool_read(frontend, &kind, 1); - pool_read(frontend, &len, sizeof(len)); - len = ntohl(len) - 4; - if (len > 0) - contents = pool_read2(frontend, len); + ereport(DEBUG5, + (errmsg("copy data rows"), + errdetail("read kind from frontend %c(%02x)", kind, kind))); - SimpleForwardToBackend(kind, frontend, backend, len, contents); + pool_read(frontend, &len, sizeof(len)); + len = ntohl(len) - 4; + if (len > 0) + contents = pool_read2(frontend, len); - /* CopyData? */ - if (kind == 'd') - { - copy_count++; - continue; - } + SimpleForwardToBackend(kind, frontend, backend, len, contents); - /* - * Flush (H) or Sync (S) messages should be ignored while in - * the COPY IN mode. - */ - else if (kind == 'H' || kind == 'S') - continue; - else - { - if (pool_config->log_client_messages && copy_count != 0) - ereport(LOG, - (errmsg("CopyData message from frontend."), - errdetail("count: %d", copy_count))); - if (kind == 'c' && pool_config->log_client_messages) - ereport(LOG, - (errmsg("CopyDone message from frontend."))); - if (kind == 'f' && pool_config->log_client_messages) - ereport(LOG, - (errmsg("CopyFail message from frontend."))); - ereport(DEBUG1, - (errmsg("copy data rows"), - errdetail("invalid copyin kind. expected 'd' got '%c'", kind))); - break; - } + /* CopyData? */ + if (kind == 'd') + { + copy_count++; + continue; } + + /* + * Flush (H) or Sync (S) messages should be ignored while in + * the COPY IN mode. + */ + else if (kind == 'H' || kind == 'S') + continue; else - string = pool_read_string(frontend, &len, 1); + { + if (pool_config->log_client_messages && copy_count != 0) + ereport(LOG, + (errmsg("CopyData message from frontend."), + errdetail("count: %d", copy_count))); + if (kind == 'c' && pool_config->log_client_messages) + ereport(LOG, + (errmsg("CopyDone message from frontend."))); + if (kind == 'f' && pool_config->log_client_messages) + ereport(LOG, + (errmsg("CopyFail message from frontend."))); + ereport(DEBUG1, + (errmsg("copy data rows"), + errdetail("invalid copyin kind. expected 'd' got '%c'", kind))); + break; + } } else { /* CopyOut */ - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - signed char kind; + signed char kind; - kind = pool_read_kind(backend); + kind = pool_read_kind(backend); - SimpleForwardToFrontend(kind, frontend, backend); + SimpleForwardToFrontend(kind, frontend, backend); - /* CopyData? */ - if (kind == 'd') - continue; - else - break; - } + /* CopyData? */ + if (kind == 'd') + continue; else - { - for (i = 0; i < NUM_BACKENDS; i++) - { - if (VALID_BACKEND(i)) - { - string = pool_read_string(CONNECTION(backend, i), &len, 1); - } - } - } + break; } if (string == NULL) @@ -3786,15 +3647,12 @@ CopyDataRows(POOL_CONNECTION *frontend, else pool_write(frontend, string, len); - if (len == PROTO_MAJOR_V3) + /* end of copy? */ + if (string[0] == '\\' && + string[1] == '.' && + string[2] == '\n') { - /* end of copy? */ - if (string[0] == '\\' && - string[1] == '.' && - string[2] == '\n') - { - break; - } + break; } } @@ -3868,11 +3726,11 @@ raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) pool_set_node_to_be_sent(query_context, PRIMARY_NODE_ID); if (pool_is_doing_extended_query_message()) { - do_error_execute_command(backend, PRIMARY_NODE_ID, PROTO_MAJOR_V3); + do_error_execute_command(backend, PRIMARY_NODE_ID); } else { - do_error_command(CONNECTION(backend, PRIMARY_NODE_ID), MAJOR(backend)); + do_error_command(CONNECTION(backend, PRIMARY_NODE_ID)); } ereport(DEBUG1, (errmsg("raising intentional error"), @@ -3908,11 +3766,11 @@ raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) */ if (pool_is_doing_extended_query_message()) { - do_error_execute_command(backend, i, PROTO_MAJOR_V3); + do_error_execute_command(backend, i); } else { - do_error_command(CONNECTION(backend, i), MAJOR(backend)); + do_error_command(CONNECTION(backend, i)); } } } @@ -3936,7 +3794,7 @@ check_errors(POOL_CONNECTION_POOL *backend, int backend_id) * Check dead lock error on the main node and abort transactions on all * nodes if so. */ - if (detect_deadlock_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) + if (detect_deadlock_error(CONNECTION(backend, backend_id)) == SPECIFIED_ERROR) return 1; /*----------------------------------------------------------------------------------- @@ -3962,7 +3820,7 @@ check_errors(POOL_CONNECTION_POOL *backend, int backend_id) * S:S2:UPDATE t1 SET i = i + 1; <-- success in UPDATE and data becomes inconsistent! *----------------------------------------------------------------------------------- */ - if (detect_serialization_error(CONNECTION(backend, backend_id), MAJOR(backend), true) == SPECIFIED_ERROR) + if (detect_serialization_error(CONNECTION(backend, backend_id), true) == SPECIFIED_ERROR) return 2; /*------------------------------------------------------------------------------- @@ -3979,11 +3837,11 @@ check_errors(POOL_CONNECTION_POOL *backend, int backend_id) *------------------------------------------------------------------------------- */ - if (detect_active_sql_transaction_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) + if (detect_active_sql_transaction_error(CONNECTION(backend, backend_id)) == SPECIFIED_ERROR) return 3; /* check query cancel error */ - if (detect_query_cancel_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) + if (detect_query_cancel_error(CONNECTION(backend, backend_id)) == SPECIFIED_ERROR) return 4; return 0; @@ -4247,7 +4105,7 @@ per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, char *query, char return kind; } - if (pool_extract_error_message(true, CONNECTION(backend, node_id), MAJOR(backend), unread, &message) == 1) + if (pool_extract_error_message(true, CONNECTION(backend, node_id), unread, &message) == 1) { ereport(LOG, (errmsg("%s: DB node id: %d backend pid: %d statement: \"%s\" message: \"%s\"", @@ -4498,7 +4356,7 @@ send_prepare(POOL_CONNECTION *frontend, message->name); elog(DEBUG1, "send_prepare: %s to backend: %d", qbuf, node_id); - do_query(CONNECTION(backend, node_id), qbuf, &res, MAJOR(backend)); + do_query(CONNECTION(backend, node_id), qbuf, &res); if (res && res->data[0] && strcmp(res->data[0], "0")) { @@ -4512,7 +4370,7 @@ send_prepare(POOL_CONNECTION *frontend, /* send DEALLOCATE message to primary node */ elog(DEBUG1, "send_prepare: %s to backend: %d", qbuf, node_id); - do_query(CONNECTION(backend, node_id), qbuf, &res, MAJOR(backend)); + do_query(CONNECTION(backend, node_id), qbuf, &res); } free_select_result(res); } @@ -4520,7 +4378,7 @@ send_prepare(POOL_CONNECTION *frontend, /* send PREPARE message to primary node */ elog(DEBUG1, "send_prepare: sending PREPARE to primary node"); do_query(CONNECTION(backend, node_id), message->query_context->original_query, - &res, MAJOR(backend)); + &res); free_select_result(res); /* replace the query context of PREPARE message with new query context */ @@ -5197,7 +5055,7 @@ pool_read_kind(POOL_CONNECTION_POOL *cp) if (kind0 == 'E') { - if (pool_extract_error_message(false, MAIN(cp), MAJOR(cp), true, &message) == 1) + if (pool_extract_error_message(false, MAIN(cp), true, &message) == 1) { ereport(LOG, (errmsg("pool_read_kind: error message from main backend:%s", message))); @@ -5206,7 +5064,7 @@ pool_read_kind(POOL_CONNECTION_POOL *cp) } else if (kind == 'E') { - if (pool_extract_error_message(false, CONNECTION(cp, i), MAJOR(cp), true, &message) == 1) + if (pool_extract_error_message(false, CONNECTION(cp, i), true, &message) == 1) { ereport(LOG, (errmsg("pool_read_kind: error message from %d th backend:%s", i, message))); @@ -5302,7 +5160,7 @@ si_get_snapshot(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node * if (!VALID_BACKEND_RAW(i)) continue; - do_query(CONNECTION(backend, i), si_query, &res, MAJOR(backend)); + do_query(CONNECTION(backend, i), si_query, &res); if (res) { if (res->data[0] && !strcmp(res->data[0], "on")) @@ -5348,7 +5206,6 @@ check_transaction_state_and_abort(char *query, Node *node, POOL_CONNECTION *fron /* send an error message to frontend */ pool_send_error_message( frontend, - MAJOR(backend), "25P02", "current transaction is aborted, commands ignored until end of transaction block", buf.data, diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c index a52ba3353..76242bd57 100644 --- a/src/query_cache/pool_memqcache.c +++ b/src/query_cache/pool_memqcache.c @@ -1633,7 +1633,7 @@ pool_get_database_oid_from_dbname(char *dbname) backend = pool_get_session_context(false)->backend; query = psprintf(DATABASE_TO_OID_QUERY, dbname); - do_query(MAIN(backend), query, &res, MAJOR(backend)); + do_query(MAIN(backend), query, &res); pfree(query); if (res->numrows != 1) diff --git a/src/rewrite/pool_lobj.c b/src/rewrite/pool_lobj.c index 2e4fe6dea..bd3fe7056 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-2025 PgPool Global Development Group + * Copyright (c) 2003-2026 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby @@ -173,7 +173,7 @@ pool_rewrite_lo_creat(char kind, char *packet, int packet_len, /* issue lock table command to lob_lock_table */ 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, + status = do_command(frontend, MAIN(backend), qbuf, MAIN_CONNECTION(backend)->pid, MAIN_CONNECTION(backend)->key, MAIN_CONNECTION(backend)->keylen, 0); if (status == POOL_END) { @@ -195,7 +195,7 @@ pool_rewrite_lo_creat(char kind, char *packet, int packet_len, /* get max lobj id */ per_node_statement_log(backend, MAIN_NODE_ID, GET_MAX_LOBJ_KEY); - do_query(MAIN(backend), GET_MAX_LOBJ_KEY, &result, MAJOR(backend)); + do_query(MAIN(backend), GET_MAX_LOBJ_KEY, &result); if (!result) { diff --git a/src/rewrite/pool_timestamp.c b/src/rewrite/pool_timestamp.c index 050a0210c..df57dc4a1 100644 --- a/src/rewrite/pool_timestamp.c +++ b/src/rewrite/pool_timestamp.c @@ -489,7 +489,7 @@ get_current_timestamp(POOL_CONNECTION_POOL *backend) POOL_SELECT_RESULT *res; static char timestamp[64]; - do_query(MAIN(backend), "SELECT pg_catalog.now()", &res, MAJOR(backend)); + do_query(MAIN(backend), "SELECT pg_catalog.now()", &res); if (res->numrows != 1) { @@ -1270,7 +1270,7 @@ makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression) char *str; snprintf(query, sizeof(query), "SELECT %s", expression); - do_query(MAIN(backend), query, &res, MAJOR(backend)); + do_query(MAIN(backend), query, &res); if (res->numrows != 1) { diff --git a/src/streaming_replication/pool_worker_child.c b/src/streaming_replication/pool_worker_child.c index cdd570396..c9d6302a4 100644 --- a/src/streaming_replication/pool_worker_child.c +++ b/src/streaming_replication/pool_worker_child.c @@ -1217,7 +1217,7 @@ get_query_result(POOL_CONNECTION_POOL_SLOT **slots, int backend_id, char *query, PG_TRY(); { - do_query(slots[backend_id]->con, query, res, PROTO_MAJOR_V3); + do_query(slots[backend_id]->con, query, res); } PG_CATCH(); { diff --git a/src/utils/error/elog.c b/src/utils/error/elog.c index d729d500c..243dbc70a 100644 --- a/src/utils/error/elog.c +++ b/src/utils/error/elog.c @@ -1916,11 +1916,28 @@ send_message_to_frontend(ErrorData *edata) if (protoVersion == PROTO_MAJOR_V2) { - char *message = edata->message ? edata->message : "missing error text"; + /* + * We no longer support v2 FE/BE protocol, except here. This is + * necessary for sending reject message to frontend which requested v2 + * protocol + */ + StringInfoData buf; + + initStringInfo(&buf); + + appendStringInfo(&buf, "%s: ", error_severity(edata->elevel, true)); + + if (edata->message) + appendStringInfoString(&buf, edata->message); + else + appendStringInfoString(&buf, _("missing error text")); + + appendStringInfoChar(&buf, '\n'); pool_send_to_frontend((edata->elevel < ERROR) ? "N" : "E", 1, false); - pool_send_to_frontend(message, strlen(message), false); - pool_send_to_frontend("\n", 1, true); + pool_send_to_frontend(buf.data, buf.len + 1, true); + + pfree(buf.data); } else if (protoVersion == PROTO_MAJOR_V3) diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c index da3064359..d14cff0e8 100644 --- a/src/utils/pool_process_reporting.c +++ b/src/utils/pool_process_reporting.c @@ -41,7 +41,6 @@ static void send_row_description_and_data_rows(POOL_CONNECTION *frontend, POOL_C short num_fields, char **field_names, int *offsettbl, char *data, int row_size, int nrows); static void write_one_field(POOL_CONNECTION *frontend, char *field); -static void write_one_field_v2(POOL_CONNECTION *frontend, char *field); static char *db_node_status(int node); static char *db_node_role(int node); @@ -49,7 +48,6 @@ void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, short num_fields, char **field_names) { - static char *cursorname = "blank"; static int oid = 0; static short fsize = -1; static int mod = 0; @@ -59,36 +57,24 @@ send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len; short colnum; - if (MAJOR(backend) == PROTO_MAJOR_V2) - { - /* cursor response */ - pool_write(frontend, "P", 1); - pool_write(frontend, cursorname, strlen(cursorname) + 1); - } - /* row description */ pool_write(frontend, "T", 1); - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - /* - * information about computed byte in section "RowDescription (B)" - * here: - * http://www.postgresql.org/docs/current/static/protocol-message-formats.html - */ - - len = 6; /* int32 + int16 */ - - for (i = 0; i < num_fields; i++) - { - /* String + '\0' + 3* int32 + 3* int16 */ - len += strlen(field_names[i]) + 1 + 18; - } + /* + * information about computed byte in section "RowDescription (B)" here: + * http://www.postgresql.org/docs/current/static/protocol-message-formats.html + */ + len = 6; /* int32 + int16 */ - len = htonl(len); - pool_write(frontend, &len, sizeof(len)); + for (i = 0; i < num_fields; i++) + { + /* String + '\0' + 3* int32 + 3* int16 */ + len += strlen(field_names[i]) + 1 + 18; } + len = htonl(len); + pool_write(frontend, &len, sizeof(len)); + n = htons(num_fields); pool_write(frontend, &n, sizeof(short)); @@ -96,23 +82,15 @@ send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, { pool_write(frontend, field_names[i], strlen(field_names[i]) + 1); /* field name */ - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - pool_write(frontend, &oid, sizeof(oid)); /* table oid */ - colnum = htons(i); - pool_write(frontend, &colnum, sizeof(colnum)); /* column number */ - } - + pool_write(frontend, &oid, sizeof(oid)); /* table oid */ + colnum = htons(i); + pool_write(frontend, &colnum, sizeof(colnum)); /* column number */ pool_write(frontend, &oid, sizeof(oid)); /* data type oid */ s = htons(fsize); pool_write(frontend, &s, sizeof(fsize)); /* field size */ pool_write(frontend, &mod, sizeof(mod)); /* modifier */ - - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - s = htons(0); - pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */ - } + s = htons(0); + pool_write(frontend, &s, sizeof(fsize)); /* field format (text) */ } pool_flush(frontend); } @@ -137,21 +115,15 @@ send_complete_and_ready(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend /* complete command response */ pool_write(frontend, "C", 1); - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - len = htonl(4 + msg_len + 1); - pool_write(frontend, &len, sizeof(len)); - } + len = htonl(4 + msg_len + 1); + pool_write(frontend, &len, sizeof(len)); pool_write(frontend, msg, msg_len + 1); /* ready for query */ pool_write(frontend, "Z", 1); - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - len = htonl(5); - pool_write(frontend, &len, sizeof(len)); - pool_write(frontend, "I", 1); - } + len = htonl(5); + pool_write(frontend, &len, sizeof(len)); + pool_write(frontend, "I", 1); pool_flush(frontend); } @@ -1216,61 +1188,32 @@ send_config_var_detail_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *back int size; int hsize; static short num_fields = 3; + short s; - if (MAJOR(backend) == PROTO_MAJOR_V2) - { - - int nbytes = (num_fields + 7) / 8; - static unsigned char nullmap[2] = {0xff, 0xff}; - - /* ascii row */ - pool_write(frontend, "D", 1); - pool_write_and_flush(frontend, nullmap, nbytes); - - size = strlen(name); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) name, size); - - size = strlen(value); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) value, size); - - size = strlen(description); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) description, size); - } - else - { - short s; - - pool_write(frontend, "D", 1); - size = 6; /* int32 + int16; */ - size += 4 + strlen(name); /* int32 + data; */ - size += 4 + strlen(value); /* int32 + data; */ - size += 4 + strlen(description); /* int32 + data; */ - hsize = htonl(size); - pool_write(frontend, &hsize, sizeof(hsize)); - s = htons(num_fields); - pool_write(frontend, &s, sizeof(s)); + pool_write(frontend, "D", 1); + size = 6; /* int32 + int16; */ + size += 4 + strlen(name); /* int32 + data; */ + size += 4 + strlen(value); /* int32 + data; */ + size += 4 + strlen(description); /* int32 + data; */ + hsize = htonl(size); + pool_write(frontend, &hsize, sizeof(hsize)); + s = htons(num_fields); + pool_write(frontend, &s, sizeof(s)); - size = strlen(name); - hsize = htonl(size); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) name, size); + size = strlen(name); + hsize = htonl(size); + pool_write(frontend, &hsize, sizeof(hsize)); + pool_write(frontend, (void *) name, size); - size = strlen(value); - hsize = htonl(size); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) value, size); + size = strlen(value); + hsize = htonl(size); + pool_write(frontend, &hsize, sizeof(hsize)); + pool_write(frontend, (void *) value, size); - size = strlen(description); - hsize = htonl(size); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) description, size); - } + size = strlen(description); + hsize = htonl(size); + pool_write(frontend, &hsize, sizeof(hsize)); + pool_write(frontend, (void *) description, size); } void @@ -1279,111 +1222,60 @@ send_config_var_value_only_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL * int size; int hsize; static short num_fields = 1; + short s; - if (MAJOR(backend) == PROTO_MAJOR_V2) - { - - int nbytes = (num_fields + 7) / 8; - static unsigned char nullmap[2] = {0xff, 0xff}; - - /* ascii row */ - pool_write(frontend, "D", 1); - pool_write_and_flush(frontend, nullmap, nbytes); - - size = strlen(value); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) value, size); - - } - else - { - short s; - - pool_write(frontend, "D", 1); - size = 6; /* int32 + int16; */ - size += 4 + strlen(value); /* int32 + data; */ - hsize = htonl(size); - pool_write(frontend, &hsize, sizeof(hsize)); - s = htons(num_fields); - pool_write(frontend, &s, sizeof(s)); + pool_write(frontend, "D", 1); + size = 6; /* int32 + int16; */ + size += 4 + strlen(value); /* int32 + data; */ + hsize = htonl(size); + pool_write(frontend, &hsize, sizeof(hsize)); + s = htons(num_fields); + pool_write(frontend, &s, sizeof(s)); - size = strlen(value); - hsize = htonl(size); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void *) value, size); - } + size = strlen(value); + hsize = htonl(size); + pool_write(frontend, &hsize, sizeof(hsize)); + pool_write(frontend, (void *) value, size); } void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { static char *field_names[] = {"item", "value", "description"}; - static unsigned char nullmap[2] = {0xff, 0xff}; static short num_fields = 3; short s; - int nbytes = (num_fields + 7) / 8; int len; int nrows; - int size; - int hsize; int i; POOL_REPORT_CONFIG *status = get_config(&nrows); send_row_description(frontend, backend, num_fields, field_names); - if (MAJOR(backend) == PROTO_MAJOR_V2) + /* data row */ + for (i = 0; i < nrows; i++) { - /* ascii row */ - for (i = 0; i < nrows; i++) - { - pool_write(frontend, "D", 1); - pool_write_and_flush(frontend, nullmap, nbytes); - - size = strlen(status[i].name); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, status[i].name, size); - - size = strlen(status[i].value); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, status[i].value, size); - - size = strlen(status[i].desc); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, status[i].desc, size); - } - } - else - { - /* data row */ - for (i = 0; i < nrows; i++) - { - pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - len += 4 + strlen(status[i].name); /* int32 + data; */ - len += 4 + strlen(status[i].value); /* int32 + data; */ - len += 4 + strlen(status[i].desc); /* int32 + data; */ - len = htonl(len); - pool_write(frontend, &len, sizeof(len)); - s = htons(num_fields); - pool_write(frontend, &s, sizeof(s)); - - len = htonl(strlen(status[i].name)); - pool_write(frontend, &len, sizeof(len)); - pool_write(frontend, status[i].name, strlen(status[i].name)); - - len = htonl(strlen(status[i].value)); - pool_write(frontend, &len, sizeof(len)); - pool_write(frontend, status[i].value, strlen(status[i].value)); - - len = htonl(strlen(status[i].desc)); - pool_write(frontend, &len, sizeof(len)); - pool_write(frontend, status[i].desc, strlen(status[i].desc)); - } + pool_write(frontend, "D", 1); + len = 6; /* int32 + int16; */ + len += 4 + strlen(status[i].name); /* int32 + data; */ + len += 4 + strlen(status[i].value); /* int32 + data; */ + len += 4 + strlen(status[i].desc); /* int32 + data; */ + len = htonl(len); + pool_write(frontend, &len, sizeof(len)); + s = htons(num_fields); + pool_write(frontend, &s, sizeof(s)); + + len = htonl(strlen(status[i].name)); + pool_write(frontend, &len, sizeof(len)); + pool_write(frontend, status[i].name, strlen(status[i].name)); + + len = htonl(strlen(status[i].value)); + pool_write(frontend, &len, sizeof(len)); + pool_write(frontend, status[i].value, strlen(status[i].value)); + + len = htonl(strlen(status[i].desc)); + pool_write(frontend, &len, sizeof(len)); + pool_write(frontend, status[i].desc, strlen(status[i].desc)); } send_complete_and_ready(frontend, backend, "SELECT", nrows); @@ -1926,10 +1818,7 @@ cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) int i; short s; int len; - int size; int hsize; - static unsigned char nullmap[2] = {0xff, 0xff}; - int nbytes = (num_fields + 7) / 8; volatile POOL_SHMEM_STATS *mystats; pool_sigset_t oldmask; double ratio; @@ -2002,36 +1891,20 @@ cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) send_row_description(frontend, backend, num_fields, field_names); /* Send each field */ - if (MAJOR(backend) == PROTO_MAJOR_V2) - { - pool_write(frontend, "D", 1); - pool_write(frontend, nullmap, nbytes); + /* Kind */ + pool_write(frontend, "D", 1); + /* Packet length */ + len = htonl(len + sizeof(int32)); + pool_write(frontend, &len, sizeof(len)); + /* Number of fields */ + s = htons(num_fields); + pool_write(frontend, &s, sizeof(s)); - for (i = 0; i < num_fields; i++) - { - size = strp[i].len + 1; - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, strp[i].string, size); - } - } - else + for (i = 0; i < num_fields; i++) { - /* Kind */ - pool_write(frontend, "D", 1); - /* Packet length */ - len = htonl(len + sizeof(int32)); - pool_write(frontend, &len, sizeof(len)); - /* Number of fields */ - s = htons(num_fields); - pool_write(frontend, &s, sizeof(s)); - - for (i = 0; i < num_fields; i++) - { - hsize = htonl(strp[i].len); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, strp[i].string, strp[i].len); - } + hsize = htonl(strp[i].len); + pool_write(frontend, &hsize, sizeof(hsize)); + pool_write(frontend, strp[i].string, strp[i].len); } send_complete_and_ready(frontend, backend, "SELECT", 1); @@ -2302,52 +2175,27 @@ send_row_description_and_data_rows(POOL_CONNECTION *frontend, POOL_CONNECTION_PO j; short s; int len; - unsigned char *nullmap; - int nbytes; - - nbytes = (num_fields + 7) / 8; send_row_description(frontend, backend, num_fields, field_names); - if (MAJOR(backend) == PROTO_MAJOR_V2) + /* data row */ + for (i = 0; i < nrows; i++) { - nullmap = palloc(nbytes); - memset(nullmap, 0xff, nbytes); + pool_write(frontend, "D", 1); + len = 6; /* int32 + int16; */ - /* ascii row */ - for (i = 0; i < nrows; i++) + for (j = 0; j < num_fields; j++) { - pool_write(frontend, "D", 1); - pool_write_and_flush(frontend, nullmap, nbytes); - - for (j = 0; j < num_fields; j++) - { - write_one_field_v2(frontend, data + i * row_size + offsettbl[j]); - } + len += 4 + strlen(data + i * row_size + offsettbl[j]); } - pfree(nullmap); - } - else - { - /* data row */ - for (i = 0; i < nrows; i++) - { - pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - - for (j = 0; j < num_fields; j++) - { - len += 4 + strlen(data + i * row_size + offsettbl[j]); - } - len = htonl(len); - pool_write(frontend, &len, sizeof(len)); - s = htons(num_fields); - pool_write(frontend, &s, sizeof(s)); + len = htonl(len); + pool_write(frontend, &len, sizeof(len)); + s = htons(num_fields); + pool_write(frontend, &s, sizeof(s)); - for (j = 0; j < num_fields; j++) - { - write_one_field(frontend, data + i * row_size + offsettbl[j]); - } + for (j = 0; j < num_fields; j++) + { + write_one_field(frontend, data + i * row_size + offsettbl[j]); } } @@ -2367,19 +2215,6 @@ write_one_field(POOL_CONNECTION *frontend, char *field) pool_write(frontend, field, size); } -/* Write one field to frontend (v2) */ -static void -write_one_field_v2(POOL_CONNECTION *frontend, char *field) -{ - int size, - hsize; - - size = strlen(field); - hsize = htonl(size + 4); - pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, field, size); -} - /* * Get DB node status. Return values are "up", "down" or "unknown" (in case * when health check is not enabled). diff --git a/src/utils/pool_relcache.c b/src/utils/pool_relcache.c index 170e9a617..3c3c058d7 100644 --- a/src/utils/pool_relcache.c +++ b/src/utils/pool_relcache.c @@ -259,7 +259,7 @@ pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, cha (errmsg("not hit local relation cache and query cache"), errdetail("query:%s", query))); - do_query(CONNECTION(backend, node_id), query, &res, MAJOR(backend)); + do_query(CONNECTION(backend, node_id), query, &res); per_node_statement_log(backend, node_id, query); /* Register cache */ -- 2.43.0