Fix auto-deallocation. If a client used PDO or DBD-pg interface,
authorYoshiyuki Asaba <y-asaba at pgfoundry.org>
Sat, 13 Jan 2007 11:13:38 +0000 (11:13 +0000)
committerYoshiyuki Asaba <y-asaba at pgfoundry.org>
Sat, 13 Jan 2007 11:13:38 +0000 (11:13 +0000)
pgpool didn't clean prepared statement.

pool_process_query.c

index d0e8e3a20c37ce3e628f1bbcf7dbb150459f4420..8062b0e4f2941488bdb0876fe0cff1742f6d3840 100644 (file)
@@ -133,6 +133,7 @@ static void reset_prepared_list(PreparedStatementList *p);
 static PreparedStatement *lookup_prepared_statement_by_statement(PreparedStatementList *p, const char *name);
 static PreparedStatement *lookup_prepared_statement_by_portal(PreparedStatementList *p, const char *name);
 static int send_deallocate(POOL_CONNECTION_POOL *backend, PreparedStatementList *p, int n);
+static char *normalize_prepared_stmt_name(const char *name);
 
 static POOL_CONNECTION_POOL_SLOT *slots[MAX_CONNECTION_SLOTS];
 
@@ -665,10 +666,9 @@ static POOL_STATUS Query(POOL_CONNECTION *frontend,
                        return POOL_END;
                }
 
-               pending_prepared_stmt->statement_name = strdup(name);
+               pending_prepared_stmt->statement_name = normalize_prepared_stmt_name(name);
                pending_prepared_stmt->portal_name = NULL;
-               if (pending_prepared_stmt->portal_name == NULL ||
-                       pending_prepared_stmt->statement_name == NULL)
+               if (pending_prepared_stmt->statement_name == NULL)
                {
                        pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
                        return POOL_END;
@@ -2659,14 +2659,12 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CO
        {
                char *stmt;
                
-               name_len = strlen(p) + 3;
-               name = malloc(name_len);
+               name = strdup(p);
                if (name == NULL)
                {
                        pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
                        return POOL_END;
                }
-               sprintf(name, "\"%s\"", p);
 
                pending_prepared_stmt = malloc(sizeof(PreparedStatement));
                if (pending_prepared_stmt == NULL)
@@ -2732,7 +2730,7 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CO
                {
                        if (stmt->portal_name)
                                free(stmt->portal_name);
-                       stmt->portal_name = strdup(portal_name);
+                       stmt->portal_name = strdup(stmt->portal_name);
                }
 
        }
@@ -2754,7 +2752,7 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CO
                        return POOL_END;
                }
 
-               pending_prepared_stmt->statement_name = strdup(name);
+               pending_prepared_stmt->statement_name = normalize_prepared_stmt_name(name);
                if (pending_prepared_stmt->statement_name == NULL)
                {
                        pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
@@ -3431,12 +3429,10 @@ static PreparedStatement *get_prepared_command_portal_and_statement(char *query)
        memcpy(string, query, len);
 
        stmt = malloc(sizeof(PreparedStatement));
-       stmt->statement_name = strdup(portal);
+       stmt->statement_name = normalize_prepared_stmt_name(portal);
        stmt->portal_name = NULL;
        stmt->prepared_string = string;
 
-       pool_debug("get_prepared_command_portal_and_statement: extracted portal name: %s  portal statement: %s", stmt->portal_name, stmt->prepared_string);
-
        return stmt;
 }
 
@@ -3618,14 +3614,14 @@ static int send_deallocate(POOL_CONNECTION_POOL *backend, PreparedStatementList
        if (p->cnt <= n)
                return 1;
        
-       len = strlen(p->stmt_list[n]->statement_name) + 12; /* "DEALLOCATE " + '\0' */
+       len = strlen(p->stmt_list[n]->statement_name) + 14; /* "DEALLOCATE \"" + "\"" + '\0' */
        query = malloc(len);
        if (query == NULL)
        {
                pool_error("send_deallocate: malloc failed: %s", strerror(errno));
                exit(1);
        }
-       sprintf(query, "DEALLOCATE %s", p->stmt_list[n]->statement_name);
+       sprintf(query, "DEALLOCATE \"%s\"", p->stmt_list[n]->statement_name);
        if (Query(NULL, backend, query) != POOL_CONTINUE)
        {
                free(query);
@@ -3635,3 +3631,36 @@ static int send_deallocate(POOL_CONNECTION_POOL *backend, PreparedStatementList
 
        return 0;
 }
+
+static char *normalize_prepared_stmt_name(const char *name)
+{
+       char *result;
+       int i, len;
+
+       len = strlen(name);
+
+       if (name[0] != '"' && name[len-1] != '"')
+       {
+               result = strdup(name);
+               if (result == NULL)
+                       return result;
+               for (i = 0; i < len; i++)
+               {
+                       if (isupper(result[i]))
+                       {
+                               result[i] += 32; /* convert to lower */
+                       }
+               }
+       }
+       else
+       {
+               result = malloc(len - 1);
+               if (result == NULL)
+                       return result;
+
+               result = memcpy(result, name+1, len-2);
+               result[len-1] = '\0';
+       }
+
+       return result;
+}