Fix bug with insert_lock in following cases:
authorTatsuo Ishii <ishii at sraoss.co.jp>
Sun, 26 Feb 2006 10:36:53 +0000 (10:36 +0000)
committerTatsuo Ishii <ishii at sraoss.co.jp>
Sun, 26 Feb 2006 10:36:53 +0000 (10:36 +0000)
- INSERT statement with multiple lines
- erroneous INSERT statement

pool_process_query.c

index 0f565eaccc35ebe8351971c7d4ac46488e867e1f..331ffdd0f207283a42b37342e688e1a952e81e26 100644 (file)
@@ -513,6 +513,7 @@ static POOL_STATUS Query(POOL_CONNECTION *frontend,
        char *string;
        int len;
        static char *sq = "show pool_status";
+       POOL_STATUS status;
 
        if (query == NULL)      /* need to read query from frontend? */
        {
@@ -583,6 +584,7 @@ static POOL_STATUS Query(POOL_CONNECTION *frontend,
         * judge if we need to lock the table
         * to keep SERIAL data consistency among servers
         * conditions:
+        * - replication is enabled
         * - protocol is V3
         * - statement is INSERT
         * - either "INSERT LOCK" comment exists or insert_lock directive specified
@@ -590,8 +592,9 @@ static POOL_STATUS Query(POOL_CONNECTION *frontend,
        if (REPLICATION && need_insert_lock(backend, string))
        {
                /* start a transaction if needed and lock the table */
-               if (insert_lock(backend, string) != POOL_CONTINUE)
-                       return POOL_END;
+               status = insert_lock(backend, string);
+               if (status != POOL_CONTINUE)
+                       return status;
        }
 
        /* forward the query to the backend */
@@ -2584,16 +2587,12 @@ static POOL_STATUS do_command(POOL_CONNECTION *backend, char *query, int protoMa
                return POOL_END;
        }
 
-#ifdef NOT_USED
        if (kind != 'C')
        {
                pool_error("do_command: backend does not successfully complete command %s status %c", query, kind);
 
-               /* the response must be an ERROR. handle it */
-               
-               return POOL_END;
        }
-#endif
+
        /*
         * read command tag of CommandComplete response
         */
@@ -2686,10 +2685,23 @@ static POOL_STATUS insert_lock(POOL_CONNECTION_POOL *backend, char *query)
 {
        char *table;
        char qbuf[1024];
+       POOL_STATUS status;
        int i;
 
+       /* insert_lock can be used in V3 only */
        if (MAJOR(backend) != PROTO_MAJOR_V3)
-               return 0;
+               return POOL_CONTINUE;
+
+       /* get table name */
+       table = get_insert_command_table_name(query);
+
+       /* could not get table name. probably wrong SQL command */
+       if (table == NULL)
+       {
+               return POOL_CONTINUE;
+       }
+
+       snprintf(qbuf, sizeof(qbuf), "LOCK TABLE %s IN SHARE ROW EXCLUSIVE MODE", table);
 
        /* if we are not in a transaction block,
         * start a new transaction
@@ -2706,20 +2718,15 @@ static POOL_STATUS insert_lock(POOL_CONNECTION_POOL *backend, char *query)
                internal_transaction_started = 1;
        }
 
-       /* issue lock table command */
-       table = get_insert_command_table_name(query);
-       snprintf(qbuf, sizeof(qbuf), "LOCK TABLE %s IN SHARE ROW EXCLUSIVE MODE", table);
+       status = POOL_CONTINUE;
 
+       /* issue lock table command */
        for (i = 0;i < backend->num;i++)
        {
-               if (do_command(backend->slots[i]->con, qbuf, PROTO_MAJOR_V3, 0) != POOL_CONTINUE)
-               {
-                       internal_transaction_started = 0;
-                       return POOL_END;
-               }
+               status = do_command(backend->slots[i]->con, qbuf, PROTO_MAJOR_V3, 0);
        }
 
-       return POOL_CONTINUE;
+       return status;
 }
 
 /*
@@ -2759,9 +2766,16 @@ static char *get_insert_command_table_name(char *query)
        while (*query && isspace(*query))
                query++;
 
-       /* get table */
+       /* get table name */
        qbuf = strdup(query);
-       token = strtok(qbuf, " (");
+       token = strtok(qbuf, "\r\n\t (");
+
+       if (token == NULL)
+       {
+               pool_error("get_insert_command_table_name: could not get table name");
+               return NULL;
+       }
+
        strncpy(table, token, sizeof(table));
        free(qbuf);