Deal with query error case.
authorTatsuo Ishii <[email protected]>
Sat, 18 Feb 2017 10:13:35 +0000 (19:13 +0900)
committerTatsuo Ishii <[email protected]>
Wed, 29 Mar 2017 04:15:55 +0000 (13:15 +0900)
src/auth/pool_auth.c
src/context/pool_session_context.c
src/include/context/pool_session_context.h
src/protocol/pool_process_query.c
src/protocol/pool_proto_modules.c

index ca503ae513e808fbc24c5d2d046917b47dbbe08d..434511ba9de3406645acfdc43fad08ca94f1b19d 100644 (file)
@@ -1112,6 +1112,7 @@ int pool_read_message_length(POOL_CONNECTION_POOL *cp)
 
        for (i=0;i<NUM_BACKENDS;i++)
        {
+#ifdef NOT_USED
                if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i) || use_sync_map == POOL_SYNC_MAP_EMPTY)
                {
                        continue;
@@ -1121,6 +1122,11 @@ int pool_read_message_length(POOL_CONNECTION_POOL *cp)
                {
                        continue;
                }
+#endif
+               if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i))
+               {
+                       continue;
+               }
 
                pool_read(CONNECTION(cp, i), &length, sizeof(length));
 
index e5e520bb12125a6e1e0c3c17e54136cb025409b0..90055f4244525ccc78497d45ddcf8e08a9aca2e7 100644 (file)
@@ -151,6 +151,9 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *
        /* Initialize pending message list */
        pool_pending_messages_init();
 
+       /* Initialize previous pending message */
+       pool_pending_message_reset_previous_message();
+
        /* Initialize preferred master node id */
        pool_reset_preferred_master_node_id();
 }
@@ -1363,6 +1366,48 @@ static POOL_PENDING_MESSAGE *copy_pending_message(POOL_PENDING_MESSAGE *message)
        return msg;
 }
 
+/*
+ * Reset previous message.
+ */
+void pool_pending_message_reset_previous_message(void)
+{
+       if (!session_context)
+       {
+               ereport(ERROR,
+                               (errmsg("pool_pending_message_reset_previous_message: session context is not initialized")));
+               return;
+       }
+       session_context->previous_message = NULL;
+}
+
+/*
+ * Set previous message.
+ */
+void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message)
+{
+       if (!session_context)
+       {
+               ereport(ERROR,
+                               (errmsg("pool_pending_message_set_previous_message: session context is not initialized")));
+               return;
+       }
+       session_context->previous_message = message;
+}
+
+/*
+ * Get previous message.
+ */
+POOL_PENDING_MESSAGE *pool_pending_message_get_previous_message(void)
+{
+       if (!session_context)
+       {
+               ereport(ERROR,
+                               (errmsg("pool_pending_message_get_previous_message: session context is not initialized")));
+               return;
+       }
+       return session_context->previous_message;
+}
+
 /*
  * Dump whole pending message list
  */
index ff65222ac4ac0f8aaae8c1ac8692f782ca6d308f..486dc9248a0577a47f566d2db967ba690e8ece8b 100644 (file)
@@ -218,10 +218,15 @@ typedef struct {
        bool is_pending_response;
 
        /*
-        * Parse/Bind/Close message queue.
+        * Parse/Bind/Decribe/Execute/Close message queue.
         */
        List *pending_messages;
 
+       /*
+        * The last pending message. Reset at Ready for query.
+        */
+       POOL_PENDING_MESSAGE *previous_message;
+
        /* Protocol major version number */
        int major;
        /* Protocol minor version number */
@@ -288,6 +293,9 @@ extern POOL_PENDING_MESSAGE *pool_pending_message_pull_out(void);
 extern POOL_PENDING_MESSAGE *pool_pending_message_remove(POOL_MESSAGE_TYPE type);
 extern char pool_get_close_message_spec(POOL_PENDING_MESSAGE *msg);
 extern char *pool_get_close_message_name(POOL_PENDING_MESSAGE *msg);
+extern void pool_pending_message_reset_previous_message(void);
+extern void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message);
+extern POOL_PENDING_MESSAGE *pool_pending_message_get_previous_message(void);
 extern void dump_pending_message(void);
 extern void pool_set_major_version(int major);
 extern int pool_get_major_version(void);
index 4d722e2d6b0fe22f4acf944bc356ce54d45fca1d..854d83c252a754d2960e69289d4800a46df6a1ba 100644 (file)
@@ -3288,7 +3288,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
        POOL_QUERY_CONTEXT *query_context = session_context->query_context;
        POOL_SYNC_MAP_STATE use_sync_map = pool_use_sync_map();
        POOL_PENDING_MESSAGE *msg = NULL;
-       static POOL_PENDING_MESSAGE *previous_msg = NULL;
+       POOL_PENDING_MESSAGE *previous_message;
        bool do_this_node_id;
 
        int num_executed_nodes = 0;
@@ -3299,6 +3299,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
        if (STREAM && pool_get_session_context(true) && pool_is_doing_extended_query_message())
        {
                msg = pool_pending_message_pull_out();
+               previous_message = pool_pending_message_get_previous_message();
                if (!msg)
                {
                        /*
@@ -3306,7 +3307,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
                         * are receiving data rows.  If so, previous_msg must exist and the
                         * query must be SELECT.
                         */
-                       if (previous_msg == NULL)
+                       if (previous_message == NULL)
                        {
                                /* no previous message. let's unset query in progress flag. */
                                ereport(DEBUG1,
@@ -3316,15 +3317,15 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
                        else
                        {
                                /*
-                                * previous message exists. Let's see if it could return
+                                * Previous message exists. Let's see if it could return
                                 * rows. If not, we cannot predict what kind of message will
                                 * arrive, so just unset query in progress.
                                 */
-                               if (previous_msg->is_rows_returned)
+                               if (previous_message->is_rows_returned)
                                {
                                        ereport(DEBUG1,
                                                        (errmsg("read_kind_from_backend: no pending message, previous message exists, rows returning")));
-                                       session_context->query_context = previous_msg->query_context;
+                                       session_context->query_context = previous_message->query_context;
                                        pool_set_query_in_progress();
                                }
                                else
@@ -3336,7 +3337,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
                        ereport(LOG,
                                        (errmsg("read_kind_from_backend: pending message exists. query context: %x",
                                                msg->query_context)));
-                       previous_msg = msg;
+                       pool_pending_message_set_previous_message(msg);
                        session_context->query_context = msg->query_context;
                        pool_set_query_in_progress();
                }
index f66fa414b2c0134ad3e3ed7b0778b997e5e31b6a..5598fe9fe45500896f81e904e40c7d66cac49dc8 100644 (file)
@@ -1655,6 +1655,9 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
         */
        pool_unset_ignore_till_sync();
 
+       /* Reset previous message */
+       pool_pending_message_reset_previous_message();
+
        /* Get session context */
        session_context = pool_get_session_context(false);
        use_sync_map = pool_use_sync_map();
@@ -1729,6 +1732,7 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
                /*
                 * XXX: discard rest of ReadyForQuery packet
                 */
+
                if (pool_read_message_length(backend) < 0)
                        return POOL_END;
 
@@ -1795,6 +1799,10 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
 
                for (i=0;i<NUM_BACKENDS;i++)
                {
+                       if (!VALID_BACKEND(i))
+                               continue;
+
+#ifdef NOT_USED
                        if (!VALID_BACKEND(i) || use_sync_map == POOL_SYNC_MAP_EMPTY)
                                continue;
 
@@ -1802,6 +1810,7 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
                        {
                                continue;
                        }
+#endif
 
                        if (pool_read(CONNECTION(backend, i), &kind, sizeof(kind)))
                                return POOL_END;
@@ -2518,7 +2527,10 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
                        pool_set_doing_extended_query_message();
                        if (pool_is_ignore_till_sync())
                                pool_unset_ignore_till_sync();
-                       if (!pool_is_query_in_progress())
+
+                       if (STREAM)
+                               pool_unset_query_in_progress();
+                       else if (!pool_is_query_in_progress())
                                pool_set_query_in_progress();
                        status = SimpleForwardToBackend(fkind, frontend, backend, len, contents);
                        pool_unset_pending_response();
@@ -2675,6 +2687,11 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend,
                                {
                                        pool_set_ignore_till_sync();
                                        pool_unset_query_in_progress();
+
+                                       /* Remove all pending messages */
+                                       while (pool_pending_message_pull_out())
+                                               ;
+                                       pool_pending_message_reset_previous_message();
                                }
                                break;