Fix the case when duplicate statement remains.
authorTatsuo Ishii <[email protected]>
Fri, 24 Mar 2017 08:44:46 +0000 (17:44 +0900)
committerTatsuo Ishii <[email protected]>
Fri, 24 Mar 2017 08:44:46 +0000 (17:44 +0900)
By using parse_before_bind, it is possible a parsed statement remains
on the load balance node even if explicit close is issued because the
close is redirected to the primary node. Fix is, issue close to both
primary and load balance node anytime. This sounds is a little bit
over killing but I think there's no way to remember the statement
remains on a load balance node.

Also clean up some ifdef NOT_USED garbage.

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 70558a52cdc31f916b04b21dc0cbe6abd1ad2b12..cc3fbd1269c7e9a57bb74871e5832619d422d89f 100644 (file)
@@ -1108,17 +1108,6 @@ 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;
-               }
-
-               if (use_sync_map == POOL_SYNC_MAP_IS_VALID && !pool_is_set_sync_map(i))
-               {
-                       continue;
-               }
-#endif
                if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i))
                {
                        continue;
index 116a23be9cc9acebc8fa35fbb36b4448101e1e72..21a95a9427a494f8d0b99d46f03881755a2ddbb8 100644 (file)
@@ -1215,6 +1215,25 @@ void pool_pending_message_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CON
        }
 }
 
+/*
+ * Set where_to_send field in query_context from node_ids field of message
+ * which indicates which backend nodes the message was sent.
+ */
+void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context)
+{
+       int i;
+
+       memset(query_context->where_to_send, 0, sizeof(query_context->where_to_send));
+
+       for (i=0;i<2;i++)
+       {
+               if (message->node_ids[i] != -1)
+               {
+                       query_context->where_to_send[message->node_ids[i]] = 1;
+               }
+       }
+}
+
 /*
  * Set query field of message.
  */
index c610526fba9a8e8cd59f6cc04c268228ead7d393..cd01d0a0e306192028db15dc9a6883ec915d8c12 100644 (file)
@@ -307,6 +307,7 @@ extern void pool_pending_messages_init (void);
 extern void pool_pending_messages_destroy(void);
 extern POOL_PENDING_MESSAGE *pool_pending_message_create(char kind, int len, char *contents);
 extern void pool_pending_message_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context);
+void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context);
 extern void pool_pending_message_query_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context);
 extern void pool_pending_message_add(POOL_PENDING_MESSAGE* message);
 extern POOL_PENDING_MESSAGE *pool_pending_message_head_message(void);
index 9aaf90e9f334e19d093065eef89cc22e071775f6..c70d5e424a4186718d49de1cdbe1404410571871 100644 (file)
@@ -735,21 +735,6 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend,
        char *p1 = NULL;
        int sendlen;
        int i;
-#ifdef NOT_USED
-       POOL_SYNC_MAP_STATE use_sync_map = pool_use_sync_map();
-#endif
-
-#ifdef NOT_USED
-       /* 
-        * The response of Execute command will be EmptyQueryResponse(I),
-        * if Bind error occurs.
-        */
-       else if ((kind == 'C' || kind == 'I') && select_in_transaction)
-       {
-               select_in_transaction = 0;
-               execute_select = 0;
-       }
-#endif
 
        pool_read(MASTER(backend), &len, sizeof(len));
 
@@ -1051,9 +1036,6 @@ static int
                                /* Deallocate failed. We are in unknown state. Ask caller
                                 * to reset backend connection.
                                 */
-#ifdef NOT_USED
-                               reset_prepared_list(&prepared_list);
-#endif
                                pool_remove_sent_message(kind, name);
                                return -1;
                        }
@@ -1065,9 +1047,6 @@ static int
                         * del_prepared_list() again. This is harmless since trying to
                         * remove same prepared object will be ignored.
                         */
-#ifdef NOT_USED
-                       del_prepared_list(&prepared_list, prepared_list.portal_list[0]);
-#endif
                        pool_remove_sent_message(kind, name);
                        return 1;
                }
@@ -1257,48 +1236,6 @@ bool is_select_query(Node *node, char *sql)
        return false;
 }
 
-#ifdef NOT_USED
-/*
- * returns true if SQL is SELECT statement including nextval() or
- * setval() call
- */
-bool is_sequence_query(Node *node)
-{
-       SelectStmt *select_stmt;
-       ListCell *lc;
-
-       if (node == NULL || !IsA(node, SelectStmt))
-               return false;
-
-       select_stmt = (SelectStmt *)node;
-       foreach (lc, select_stmt->targetList)
-       {
-               if (IsA(lfirst(lc), ResTarget))
-               {
-                       ResTarget *t;
-                       FuncCall *fc;
-                       ListCell *c;
-
-                       t = (ResTarget *) lfirst(lc);
-                       if (IsA(t->val, FuncCall))
-                       {
-                               fc = (FuncCall *) t->val;
-                               foreach (c, fc->funcname)
-                               {
-                                       Value *v = lfirst(c);
-                                       if (strncasecmp(v->val.str, "NEXTVAL", 7) == 0)
-                                               return true;
-                                       else if (strncasecmp(v->val.str, "SETVAL", 6) == 0)
-                                               return true;
-                               }
-                       }
-               }
-       }
-
-       return false;
-}
-#endif
-
 /*
  * Returns true if SQL is transaction commit or rollback command (COMMIT,
  * END TRANSACTION, ROLLBACK or ABORT)
@@ -1751,34 +1688,6 @@ void do_error_command(POOL_CONNECTION *backend, int major)
                }
        } while (kind != 'E');
 
-#ifdef NOT_USED
-       /*
-        * Expecting ErrorResponse
-        */
-       pool_read(backend, &kind, sizeof(kind));
-
-       /*
-        * read command tag of CommandComplete response
-        */
-       if (major == PROTO_MAJOR_V3)
-       {
-               pool_read(backend, &len, sizeof(len));
-               len = ntohl(len) - 4;
-               string = pool_read2(backend, len);
-               if (string == NULL)
-            ereport(ERROR,
-                (errmsg("do error command failed"),
-                     errdetail("read from backend failed")));
-       }
-       else
-       {
-               string = pool_read_string(backend, &len, 0);
-               if (string == NULL)
-            ereport(ERROR,
-                (errmsg("do error command failed"),
-                     errdetail("read from backend failed")));
-       }
-#endif
 }
 
 /*
@@ -3288,7 +3197,14 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
                                                (errmsg("read_kind_from_backend: pending message exists. query context: %x",
                                                                msg->query_context)));
                                pool_pending_message_set_previous_message(msg);
+                               pool_pending_message_query_context_dest_set(msg, msg->query_context);
                                session_context->query_context = msg->query_context;
+
+                               ereport(DEBUG1,
+                                               (errmsg("read_kind_from_backend: where_to_send[0]:%d [1]:%d",
+                                                               msg->query_context->where_to_send[0],
+                                                               msg->query_context->where_to_send[1])));
+                               
                                pool_set_query_in_progress();
                        }
                }
@@ -3327,30 +3243,6 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
                degenerate_node[i] = 0;
                kind_list[i] = 0;
 
-#ifdef NOT_USED
-               if (!VALID_BACKEND(i) || use_sync_map == POOL_SYNC_MAP_EMPTY)
-               {
-                       kind_list[i] = 0;
-                       continue;
-               }
-#endif
-
-#ifdef NOT_USED
-               if (STREAM && pool_is_doing_extended_query_message())
-               {
-                       if (msg && IS_SENT_NODE_ID(msg, i))
-                       {
-                               do_this_node_id = true;
-                       }
-               }
-               else
-               {
-                       if (VALID_BACKEND(i))
-                       {
-                               do_this_node_id = true;
-                       }
-               }
-#endif
                if (VALID_BACKEND(i))
                {
                        num_executed_nodes++;
@@ -3383,11 +3275,6 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
                                ereport(DEBUG1,
                                        (errmsg("reading backend data packet kind"),
                                                 errdetail("backend:%d kind:'%c'",i, kind)));
-#ifdef NOT_USED
-                               ereport(DEBUG2,
-                                       (errmsg("reading backend data packet kind"),
-                                                errdetail("backend:%d kind:'%c'",i, kind)));
-#endif
 
                                /*
                                 * Read and discard parameter status and notice messages
@@ -3535,21 +3422,6 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac
 
                        for(;;)
                        {
-#ifdef NOT_USED
-                               if (!pool_ssl_pending(s) && pool_read_buffer_is_empty(s))
-                               {
-                                       pool_set_timeout(-1);
-                                       if (pool_check_fd(s) != 0)
-                                       {
-                                               ereport(DEBUG1,
-                                                               (errmsg("readkind_from_backend: no pending data")));
-                                               pool_set_timeout(-1);
-                                               break;
-                                       }
-                               }
-
-                               pool_set_timeout(-1);
-#endif
                                pool_read(s, &kind, 1);
 
                                ereport(DEBUG1,
index 8dfa33395712ca518b503abe3367db748b12a957..f5aedfe079756ce390a7f9d2e87e3cb28971bd96 100644 (file)
@@ -887,32 +887,10 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
                /* Various take care at the transaction start */
                handle_query_context(backend);
 
-#ifdef NOT_USED
-               /*
-                * Send flush message to backend to make sure that we get any response
-                * from backend.
-                */
-               pool_write(MASTER(session_context->backend), "H", 1);
-               len = htonl(sizeof(len));
-               pool_write_and_flush(MASTER(session_context->backend), &len, sizeof(len));
-
-               if (MASTER(session_context->backend)->db_node_id != session_context->load_balance_node_id)
-               {
-                       POOL_CONNECTION *con;
-
-                       con = session_context->backend->slots[session_context->load_balance_node_id]->con;
-                       pool_write(con, "H", 1);
-                       len = htonl(sizeof(len));
-                       pool_write_and_flush(con, &len, sizeof(len));
-               }
-#endif
                /*
                 * Remeber that we send flush or sync message to backend.
                 */
                pool_unset_pending_response();
-#ifdef NOT_USED
-               pool_unset_query_in_progress();
-#endif
 
                /*
                 * Take care of "writing transaction" flag.
@@ -1261,7 +1239,9 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
 
                /* XXX fix me:even with streaming replication mode, couldn't we have a deadlock */
                pool_set_query_in_progress();
+#ifdef NOT_USED
                pool_clear_sync_map();
+#endif
                pool_extended_send_and_wait(query_context, "P", len, contents, 1, MASTER_NODE_ID, true);
                pool_extended_send_and_wait(query_context, "P", len, contents, -1, MASTER_NODE_ID, true);
                pool_add_sent_message(session_context->uncompleted_message);
@@ -1408,7 +1388,9 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
        else
                nowait = false;
 
+#ifdef NOT_USED
        pool_clear_sync_map();
+#endif
        pool_extended_send_and_wait(query_context, "B", len, contents, 1, MASTER_NODE_ID, nowait);
        pool_extended_send_and_wait(query_context, "B", len, contents, -1, MASTER_NODE_ID, nowait);
 
@@ -1578,7 +1560,12 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
        {
                POOL_PENDING_MESSAGE *pmsg;
 
-               pool_clear_sync_map();
+               if (session_context->load_balance_node_id != PRIMARY_NODE_ID)
+               {
+                       query_context->where_to_send[PRIMARY_NODE_ID] = true;
+                       query_context->where_to_send[session_context->load_balance_node_id] = true;
+               }
+
                pool_extended_send_and_wait(query_context, "C", len, contents, 1, MASTER_NODE_ID, false);
                pool_extended_send_and_wait(query_context, "C", len, contents, -1, MASTER_NODE_ID, false);
 
@@ -1588,9 +1575,11 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,
                pool_pending_message_query_set(pmsg, query_context);
                pool_pending_message_add(pmsg);
 
+#ifdef NOT_USED
                dump_pending_message();
-
+#endif
                pool_unset_query_in_progress();
+
                /*
                 * Remeber that we send flush or sync message to backend.
                 */
@@ -1803,16 +1792,6 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend,
                        if (!VALID_BACKEND(i))
                                continue;
 
-#ifdef NOT_USED
-                       if (!VALID_BACKEND(i) || use_sync_map == POOL_SYNC_MAP_EMPTY)
-                               continue;
-
-                       if (use_sync_map == POOL_SYNC_MAP_IS_VALID && !pool_is_set_sync_map(i))
-                       {
-                               continue;
-                       }
-#endif
-
                        if (pool_read(CONNECTION(backend, i), &kind, sizeof(kind)))
                                return POOL_END;
 
@@ -2228,56 +2207,6 @@ POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend,
 
        raise_intentional_error_if_need(backend);
        
-#ifdef NOT_USED
-       for (i = 0;i < NUM_BACKENDS; i++)
-       {
-               if (VALID_BACKEND(i))
-               {
-                       POOL_CONNECTION *cp = CONNECTION(backend, i);
-
-                       /* We need to send "sync" message to backend in extend mode
-                        * so that it accepts next command.
-                        * Note that this may be overkill since client may send
-                        * it by itself. Moreover we do not need it in non-extend mode.
-                        * At this point we regard it is not harmful since error response
-                        * will not be sent too frequently.
-                        */
-                       pool_write(cp, "S", 1);
-                       res1 = htonl(4);
-                       if (pool_write_and_flush_noerror(cp, &res1, sizeof(res1)) < 0)
-                       {
-                               return POOL_END;
-                       }
-               }
-       }
-
-       while (read_kind_from_backend(frontend, backend, &kind1))
-       {
-               if (kind1 == 'Z') /* ReadyForQuery? */
-                       break;
-
-               ret = SimpleForwardToFrontend(kind1, frontend, backend);
-               if (ret != POOL_CONTINUE)
-                       return ret;
-               pool_flush(frontend);
-       }
-
-       if (ret != POOL_CONTINUE)
-               return ret;
-
-       for (i = 0; i < NUM_BACKENDS; i++)
-       {
-               if (VALID_BACKEND(i))
-               {
-                       status = pool_read(CONNECTION(backend, i), &res1, sizeof(res1));
-                       res1 = ntohl(res1) - sizeof(res1);
-                       p1 = pool_read2(CONNECTION(backend, i), res1);
-                       if (p1 == NULL)
-                               return POOL_END;
-               }
-       }
-#endif
-
        return POOL_CONTINUE;
 }
 
@@ -2489,20 +2418,12 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
                case 'P':       /* Parse */
                        allow_close_transaction = 0;
                        pool_set_doing_extended_query_message();
-#ifdef NOT_USED
-                       if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync())
-                               pool_set_query_in_progress();
-#endif
                        status = Parse(frontend, backend, len, contents);
                        pool_set_pending_response();
                        break;
 
                case 'B':       /* Bind */
                        pool_set_doing_extended_query_message();
-#ifdef NOT_USED
-                       if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync())
-                               pool_set_query_in_progress();
-#endif
                        status = Bind(frontend, backend, len, contents);
                        pool_set_pending_response();
                        break;
@@ -2516,10 +2437,6 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
 
                case 'D':       /* Describe */
                        pool_set_doing_extended_query_message();
-#ifdef NOT_USED
-                       if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync())
-                               pool_set_query_in_progress();
-#endif
                        status = Describe(frontend, backend, len, contents);
                        pool_set_pending_response();
                        break;