Skip to content

Commit 67cbe46

Browse files
committed
Simplify PID extraction
Using bind message to obtain parameter information, rather than determining whether the query is parameterized from the query itself. Multiple parameters are not possible in this case, as PostgreSQL itself rejects multi-parameter pg_cancel_backend() and pg_terminate_backend() and only accepts a single parameter for these functions.
1 parent 5066ddd commit 67cbe46

File tree

1 file changed

+41
-73
lines changed

1 file changed

+41
-73
lines changed

lib/PgSQL_Session.cpp

Lines changed: 41 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5191,91 +5191,59 @@ bool PgSQL_Session::handle_command_query_kill(PtrSize_t* pkt) {
51915191
// Note: This simple check might have false positives if $1 appears in comments or string literals
51925192
// but those cases would fail later when checking bind_msg or parameter validation
51935193
const char* digest_text = CurrentQuery.QueryParserArgs.digest_text;
5194-
bool is_parameterized = strstr(digest_text, "$1") != nullptr;
5194+
5195+
// Use protocol facts (Bind)
5196+
const PgSQL_Bind_Message* bind_msg = CurrentQuery.extended_query_info.bind_msg;
5197+
const bool is_parameterized = bind_msg && bind_msg->data().num_param_values > 0;
51955198
if (is_parameterized) {
5196-
// Check if there are multiple parameters (e.g., $1, $2)
5197-
// Look for $2, $3, etc. to reject multiple parameters
5198-
const char* p = digest_text;
5199-
int max_param = 0;
5200-
while ((p = strstr(p, "$")) != nullptr) {
5201-
p++; // Skip '$'
5202-
if (isdigit(*p)) {
5203-
char* end;
5204-
long param_num = strtol(p, &end, 10);
5205-
if (p != end) { // check if any digits were parsed
5206-
if (param_num > max_param) {
5207-
max_param = static_cast<int>(param_num);
5208-
}
5209-
p = end;
5210-
continue;
5211-
}
5212-
}
5213-
p++;
5214-
}
5215-
if (max_param > 1) {
5216-
// Multiple parameters not supported
5199+
// Check that we have exactly one parameter
5200+
if (bind_msg->data().num_param_values != 1) {
52175201
send_parameter_error_response("function requires exactly one parameter");
52185202
l_free(pkt->size, pkt->ptr);
52195203
return true;
52205204
}
5221-
5222-
// Handle parameterized query
5223-
if (CurrentQuery.extended_query_info.bind_msg) {
5224-
const PgSQL_Bind_Message* bind_msg = CurrentQuery.extended_query_info.bind_msg;
5225-
auto param_reader = bind_msg->get_param_value_reader();
5226-
PgSQL_Param_Value param;
5227-
5228-
// Check that we have exactly one parameter
5229-
if (bind_msg->data().num_param_values != 1) {
5230-
send_parameter_error_response("function requires exactly one parameter");
5231-
l_free(pkt->size, pkt->ptr);
5232-
return true;
5205+
auto param_reader = bind_msg->get_param_value_reader();
5206+
PgSQL_Param_Value param;
5207+
if (param_reader.next(&param)) {
5208+
// Get parameter format (default to text format 0)
5209+
uint16_t param_format = 0;
5210+
if (bind_msg->data().num_param_formats == 1) {
5211+
// Single format applies to all parameters
5212+
auto format_reader = bind_msg->get_param_format_reader();
5213+
format_reader.next(&param_format);
52335214
}
5234-
5235-
if (param_reader.next(&param)) {
5236-
// Get parameter format (default to text format 0)
5237-
uint16_t param_format = 0;
5238-
if (bind_msg->data().num_param_formats == 1) {
5239-
// Single format applies to all parameters
5240-
auto format_reader = bind_msg->get_param_format_reader();
5241-
format_reader.next(&param_format);
5242-
}
52435215

5244-
// Extract PID from parameter
5245-
int32_t pid = extract_pid_from_param(param, param_format);
5246-
if (pid > 0) {
5247-
// Determine if this is terminate or cancel
5248-
int tki = -1;
5249-
if (CurrentQuery.PgQueryCmd == PGSQL_QUERY_TERMINATE_BACKEND) {
5250-
tki = 0; // Connection terminate
5251-
} else if (CurrentQuery.PgQueryCmd == PGSQL_QUERY_CANCEL_BACKEND) {
5252-
tki = 1; // Query cancel
5253-
}
5216+
// Extract PID from parameter
5217+
int32_t pid = extract_pid_from_param(param, param_format);
5218+
if (pid > 0) {
5219+
// Determine if this is terminate or cancel
5220+
int tki = -1;
5221+
if (CurrentQuery.PgQueryCmd == PGSQL_QUERY_TERMINATE_BACKEND) {
5222+
tki = 0; // Connection terminate
5223+
} else if (CurrentQuery.PgQueryCmd == PGSQL_QUERY_CANCEL_BACKEND) {
5224+
tki = 1; // Query cancel
5225+
}
52545226

5255-
if (tki >= 0) {
5256-
return handle_kill_success(pid, tki, digest_text, mc, pkt);
5257-
}
5258-
} else {
5259-
// Invalid parameter - send appropriate error response
5260-
if (pid == -2) {
5261-
// NULL parameter
5262-
send_parameter_error_response("NULL is not allowed", PGSQL_ERROR_CODES::ERRCODE_NULL_VALUE_NOT_ALLOWED);
5263-
} else if (pid == -1) {
5264-
// Invalid format (not a valid integer)
5265-
send_parameter_error_response("invalid input syntax for integer", PGSQL_ERROR_CODES::ERRCODE_INVALID_PARAMETER_VALUE);
5266-
} else if (pid == 0) {
5267-
// PID <= 0 (non-positive)
5268-
send_parameter_error_response("PID must be a positive integer", PGSQL_ERROR_CODES::ERRCODE_INVALID_PARAMETER_VALUE);
5269-
}
5270-
l_free(pkt->size, pkt->ptr);
5271-
return true;
5227+
if (tki >= 0) {
5228+
return handle_kill_success(pid, tki, digest_text, mc, pkt);
52725229
}
52735230
} else {
5274-
// No parameter available - this shouldn't happen
5275-
return false;
5231+
// Invalid parameter - send appropriate error response
5232+
if (pid == -2) {
5233+
// NULL parameter
5234+
send_parameter_error_response("NULL is not allowed", PGSQL_ERROR_CODES::ERRCODE_NULL_VALUE_NOT_ALLOWED);
5235+
} else if (pid == -1) {
5236+
// Invalid format (not a valid integer)
5237+
send_parameter_error_response("invalid input syntax for integer", PGSQL_ERROR_CODES::ERRCODE_INVALID_PARAMETER_VALUE);
5238+
} else if (pid == 0) {
5239+
// PID <= 0 (non-positive)
5240+
send_parameter_error_response("PID must be a positive integer", PGSQL_ERROR_CODES::ERRCODE_INVALID_PARAMETER_VALUE);
5241+
}
5242+
l_free(pkt->size, pkt->ptr);
5243+
return true;
52765244
}
52775245
} else {
5278-
// No bind message available (shouldn't happen for Execute phase)
5246+
// No parameter available - this shouldn't happen
52795247
return false;
52805248
}
52815249
} else {

0 commit comments

Comments
 (0)