Fix the case when parse_before_bind() is called.
authorTatsuo Ishii <[email protected]>
Mon, 27 Feb 2017 07:47:58 +0000 (16:47 +0900)
committerTatsuo Ishii <[email protected]>
Wed, 29 Mar 2017 04:15:55 +0000 (13:15 +0900)
When parse_before_bind() is called, response of the the newly issued
parse message should not be forwarded to frontend. Otherwise, the
frontend will receive duplicate parse complete message.

src/context/pool_session_context.c
src/include/context/pool_session_context.h
src/protocol/pool_proto_modules.c

index 22ca6d0761b4c4f8c6290082b8df0edef719d3aa..7e06f26268bb1a20192aa9a56d76986628997270 100644 (file)
@@ -1173,6 +1173,7 @@ POOL_PENDING_MESSAGE *pool_pending_messages_create(char kind, int len, char *con
        msg->statement[0] = '\0';
        msg->portal[0] = '\0';
        msg->is_rows_returned = false;
+       msg->not_forward_to_frontend = false;
        msg->node_ids[0] = msg->node_ids[1] = -1;
 
        MemoryContextSwitchTo(old_context);
index cc8d924c1a912fca8b64075ae82791b5ffff1667..65f602d10e810843bb12ba96f7ef0705f2d7f062 100644 (file)
@@ -125,6 +125,9 @@ typedef struct {
        char statement[MAX_IDENTIFIER_LEN];     /* prepared statment name if any */
        char portal[MAX_IDENTIFIER_LEN];        /* portal name if any */
        bool is_rows_returned;          /* true if the message could produce row data */
+       bool not_forward_to_frontend;           /* Do not forward response from backend to frontend.
+                                                                                * This is used by parse_before_bind()
+                                                                                */
        int node_ids[2];        /* backend node ids this message was sent to. -1 means no message was sent. */
        POOL_QUERY_CONTEXT *query_context;      /* query context */
 } POOL_PENDING_MESSAGE;
index 122fc0114482c1603efc265ced9d79e30d274bd6..1c125a8ce14311fc64dab474f466ae1442c81574 100644 (file)
@@ -2660,6 +2660,24 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend,
                                break;
 
                        case '1':       /* ParseComplete */
+                               if (STREAM)
+                               {
+                                       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 foward the
+                                                * parse complete message to frontend. */
+                                               ereport(LOG,
+                                                               (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();
                                if (STREAM||REPLICATION||RAW_MODE)
@@ -3244,6 +3262,7 @@ static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend,
 
                        /* Add pending message */
                        pmsg = pool_pending_messages_create('P', len, contents);
+                       pmsg->not_forward_to_frontend = true;
                        pool_pending_messages_dest_set(pmsg, qc);
                        pool_pending_message_add(pmsg);