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]