Fix SimpleQuery() to properly check extended query related commands.
authorTatsuo Ishii <ishii at sraoss.co.jp>
Fri, 3 Apr 2009 13:30:27 +0000 (13:30 +0000)
committerTatsuo Ishii <ishii at sraoss.co.jp>
Fri, 3 Apr 2009 13:30:27 +0000 (13:30 +0000)
Before it ignores them if query is not NULL. This is problematic if
frontend == NULL, which could happen with queries defined in
reset_query_list. The bug had been there since 2.1 BTW.

pool_proto_modules.c

index bc8a17abeb1dc91391dddeae9a9388871ce9ab7c..ab6b597964c736e6a90dd52e12761525b38ea0c3 100644 (file)
@@ -141,6 +141,9 @@ POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend,
        int deadlock_detected = 0;
        int     active_sql_transaction_error = 0;
 
+       POOL_MEMORY_POOL *old_context = NULL;
+       Portal *portal;
+
        force_replication = 0;
        if (query == NULL)      /* need to read query from frontend? */
        {
@@ -343,63 +346,66 @@ POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend,
                        if (MASTER_SLAVE && TSTATE(backend) != 'E')
                                force_replication = 1;
 
-                       if (frontend)
+                       /*
+                        * Before we do followings only when frontend == NULL,
+                        * which was wrong since if, for example, reset_query_list
+                        * contains "DISCARD ALL", then it does not register
+                        * pending function and it causes trying to DEALLOCATE non
+                        * existing prepared statment(2009/4/3 Tatsuo).
+                        */
+                       if (IsA(node, PrepareStmt))
                        {
-                               POOL_MEMORY_POOL *old_context = NULL;
-                               Portal *portal;
-
-                               if (IsA(node, PrepareStmt))
+                               pending_function = add_prepared_list;
+                               portal = create_portal();
+                               if (portal == NULL)
                                {
-                                       pending_function = add_prepared_list;
-                                       portal = create_portal();
-                                       if (portal == NULL)
-                                       {
-                                               pool_error("SimpleQuery: create_portal() failed");
-                                               return POOL_END;
-                                       }
+                                       pool_error("SimpleQuery: create_portal() failed");
+                                       return POOL_END;
+                               }
 
-                                       /* switch memory context */
-                                       old_context = pool_memory;
-                                       pool_memory = portal->prepare_ctxt;
+                               /* switch memory context */
+                               old_context = pool_memory;
+                               pool_memory = portal->prepare_ctxt;
 
-                                       portal->portal_name = NULL;
-                                       portal->stmt = copyObject(node);
-                                       portal->sql_string = NULL;
-                                       pending_prepared_portal = portal;
-                               }
-                               else if (IsA(node, DeallocateStmt))
+                               portal->portal_name = NULL;
+                               portal->stmt = copyObject(node);
+                               portal->sql_string = NULL;
+                               pending_prepared_portal = portal;
+                       }
+                       else if (IsA(node, DeallocateStmt))
+                       {
+                               pending_function = del_prepared_list;
+                               portal = create_portal();
+                               if (portal == NULL)
                                {
-                                       pending_function = del_prepared_list;
-                                       portal = create_portal();
-                                       if (portal == NULL)
-                                       {
-                                               pool_error("SimpleQuery: create_portal() failed");
-                                               return POOL_END;
-                                       }
+                                       pool_error("SimpleQuery: create_portal() failed");
+                                       return POOL_END;
+                               }
 
-                                       /* switch memory context */
-                                       old_context = pool_memory;
-                                       pool_memory = portal->prepare_ctxt;
+                               /* switch memory context */
+                               old_context = pool_memory;
+                               pool_memory = portal->prepare_ctxt;
 
-                                       portal->portal_name = NULL;
-                                       portal->stmt = copyObject(node);
-                                       portal->sql_string = NULL;
-                                       pending_prepared_portal = portal;
-                               }
-                               else if (IsA(node, DiscardStmt))
+                               portal->portal_name = NULL;
+                               portal->stmt = copyObject(node);
+                               portal->sql_string = NULL;
+                               pending_prepared_portal = portal;
+                       }
+                       else if (IsA(node, DiscardStmt))
+                       {
+                               DiscardStmt *stmt = (DiscardStmt *)node;
+                               if (stmt->target == DISCARD_ALL || stmt->target == DISCARD_PLANS)
                                {
-                                       DiscardStmt *stmt = (DiscardStmt *)node;
-                                       if (stmt->target == DISCARD_ALL || stmt->target == DISCARD_PLANS)
-                                       {
-                                               pending_function = delete_all_prepared_list;
-                                               pending_prepared_portal = NULL;
-                                       }
+                                       pending_function = delete_all_prepared_list;
+                                       pending_prepared_portal = NULL;
                                }
-
-                               /* switch old memory context */
-                               if (old_context)
-                                       pool_memory = old_context;
                        }
+
+                       /* switch old memory context */
+                       if (old_context)
+                               pool_memory = old_context;
+
+                       /* end of wrong if (see 2009/4/3 comment above) */
                }
 
                if (frontend && IsA(node, ExecuteStmt))