pgpool2.git / summary / log / commit / refs
commit 47a286ca929d4736083d3231a4a55ab18dbe9910
Author: Yoshiyuki Asaba <y-asaba at pgfoundry.org>
Date: Wed Jul 25 12:31:03 2007 +0000
Fix hang up and SEGV if Parse message contains a warning statement.
SELECT '\'';
WARNING: nonstandard use of \' in a string literal
If pgpool receives a warning message that is NoticeMessage('N') under
the extended query protocol, it reads a next message.
pool_process_query.c | 48 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/pool_process_query.c b/pool_process_query.c
index 0c673e457..3adb99681 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -3208,14 +3208,16 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_C
/*
* Check if packet kind == 'C'(Command complete), '1'(Parse
- * complete), '3'(Close complete). If so, then register or unregister
- * pending prepared statement.
+ * complete), '3'(Close complete). If so, then register or
+ * unregister pending prepared statement.
*/
if ((kind == 'C' || kind == '1' || kind == '3') &&
pending_function && pending_prepared_portal)
{
pending_function(&prepared_list, pending_prepared_portal);
- if (IsA(pending_prepared_portal->stmt, DeallocateStmt))
+ if (pending_prepared_portal &&
+ pending_prepared_portal->stmt &&
+ IsA(pending_prepared_portal->stmt, DeallocateStmt))
{
DeallocateStmt *s = (DeallocateStmt *)pending_prepared_portal->stmt;
@@ -3228,8 +3230,15 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_C
else if (kind == 'C' && select_in_transaction)
select_in_transaction = 0;
- pending_function = NULL;
- pending_prepared_portal = NULL;
+ /*
+ * Remove a pending function if a received message is not
+ * NoticeResponse.
+ */
+ if (kind != 'N')
+ {
+ pending_function = NULL;
+ pending_prepared_portal = NULL;
+ }
status = pool_read(MASTER(backend), &len, sizeof(len));
len = ntohl(len);
@@ -3550,6 +3559,7 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CO
portal = malloc(sizeof(Portal));
/* translate Parse message to PrepareStmt */
p_stmt = palloc(sizeof(PrepareStmt));
+ p_stmt->type = T_PrepareStmt;
p_stmt->name = pstrdup(name);
p_stmt->query = copyObject(node);
portal->stmt = (Node *)p_stmt;
@@ -3637,6 +3647,11 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CO
}
}
+ /*
+ * Describe message with a portal name receive two messages.
+ * 1. ParameterDescription
+ * 2. RowDescriptions or NoData
+ */
if (kind == 'D' && *p == 'S')
{
kind1 = pool_read_kind(backend);
@@ -3649,14 +3664,21 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CO
pool_flush(frontend);
}
- kind1 = pool_read_kind(backend);
- if (kind1 < 0)
+ for (;;)
{
- pool_error("SimpleForwardToBackend: pool_read_kind error");
- return POOL_ERROR;
+ kind1 = pool_read_kind(backend);
+ if (kind1 < 0)
+ {
+ pool_error("SimpleForwardToBackend: pool_read_kind error");
+ return POOL_ERROR;
+ }
+ SimpleForwardToFrontend(kind1, frontend, backend);
+ if (pool_flush(frontend) < 0)
+ return POOL_ERROR;
+
+ if (kind1 != 'N')
+ break;
}
- SimpleForwardToFrontend(kind1, frontend, backend);
- return pool_flush(frontend);
}
return POOL_CONTINUE;
@@ -4549,6 +4571,7 @@ static void add_unnamed_portal(PreparedStatementList *p, Portal *portal)
pfree(p_stmt->query);
pfree(p_stmt);
}
+ free(unnamed_statement);
}
unnamed_portal = NULL;
@@ -4587,6 +4610,9 @@ static void reset_prepared_list(PreparedStatementList *p)
{
pool_memory_delete(prepare_memory_context);
prepare_memory_context = NULL;
+ free(unnamed_statement);
+ unnamed_portal = NULL;
+ unnamed_statement = NULL;
}
p->cnt = 0;
}
[parent: fb07de60e5e3]