pgpool2.git / summary / log / commit / refs
commit e15eedd0c77edfe4e472d1f80f7b22ca8c7dce16
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Fri Jul 23 06:08:33 2010 +0000
Add reset_context flag to session context.
This is to be called while executing reset queries.
Fix SimpleQuery so that if function call is executed under
dummy query context.
pool_process_query.c | 22 +++++++++++++++++++---
pool_proto_modules.c | 45 ++++++++++++++++++++-------------------------
pool_query_context.c | 14 +++++++++++++-
3 files changed, 52 insertions(+), 29 deletions(-)
diff --git a/pool_process_query.c b/pool_process_query.c
index b597d58fd..35819aaa6 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -1781,6 +1781,8 @@ static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt)
char *query;
int qn;
POOL_SESSION_CONTEXT *session_context;
+ int i;
+ bool need_to_abort;
/* Get session context */
session_context = pool_get_session_context();
@@ -1790,6 +1792,9 @@ static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt)
return POOL_END;
}
+ /* Set reset context */
+ session_context->reset_context = true;
+
/*
* Reset all state variables
*/
@@ -1842,9 +1847,20 @@ static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt)
query = pool_config->reset_query_list[qcnt];
- /* if transaction state is idle, we don't need to issue ABORT */
- if (TSTATE(backend, MASTER_NODE_ID) == 'I' && !strcmp("ABORT", query))
- return 0;
+ if (!strcmp("ABORT", query))
+ {
+ /* If transaction state are all idle, we don't need to issue ABORT */
+ need_to_abort = false;
+
+ for (i=0;i<NUM_BACKENDS;i++)
+ {
+ if (TSTATE(backend, i) != 'I')
+ need_to_abort = true;
+ }
+
+ if (!need_to_abort)
+ return 0;
+ }
pool_set_timeout(10);
diff --git a/pool_proto_modules.c b/pool_proto_modules.c
index 32767badd..5132b81f1 100644
--- a/pool_proto_modules.c
+++ b/pool_proto_modules.c
@@ -393,6 +393,8 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
}
}
+ string = query_context->original_query;
+
if (!RAW_MODE)
{
/* check if query is "COMMIT" or "ROLLBACK" */
@@ -429,9 +431,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend,
}
- if (query_context->rewritten_query == NULL)
- string = query_context->original_query;
- else
+ if (query_context->rewritten_query != NULL)
string = query_context->rewritten_query;
/*
@@ -1908,6 +1908,10 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
switch (fkind)
{
+ POOL_QUERY_CONTEXT *query_context;
+ char *query;
+ Node *node;
+ List *parse_tree_list;
case 'X': /* Terminate */
return POOL_END;
@@ -1964,30 +1968,21 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
break;
case 'F': /* FunctionCall */
- if (MASTER_SLAVE)
+ /*
+ * Create dummy query context as if it were an INSERT.
+ */
+ query_context = pool_init_query_context();
+ if (!query_context)
{
- /*
- * Send to primary/master node only.
- * For this we treat function call as if INSERT.
- */
- POOL_QUERY_CONTEXT *query_context;
- char *query = "INSERT INTO foo VALUES(1)";
- Node *node;
- List *parse_tree_list;
-
- /* Create query context */
- query_context = pool_init_query_context();
- if (!query_context)
- {
- pool_error("ProcessFrontendResponse: pool_init_query_context failed");
- return POOL_END;
- }
- parse_tree_list = raw_parser(query);
- node = (Node *) lfirst(list_head(parse_tree_list));
- pool_start_query(query_context, query, node);
- pool_where_to_send(query_context, query_context->original_query,
- query_context->parse_tree);
+ pool_error("ProcessFrontendResponse: pool_init_query_context failed");
+ return POOL_END;
}
+ query = "INSERT INTO foo VALUES(1)";
+ parse_tree_list = raw_parser(query);
+ node = (Node *) lfirst(list_head(parse_tree_list));
+ pool_start_query(query_context, query, node);
+ pool_where_to_send(query_context, query_context->original_query,
+ query_context->parse_tree);
if (MAJOR(backend) == PROTO_MAJOR_V3)
status = FunctionCall3(frontend, backend, len, contents);
diff --git a/pool_query_context.c b/pool_query_context.c
index fe7f052b5..80a3b0614 100644
--- a/pool_query_context.c
+++ b/pool_query_context.c
@@ -563,7 +563,8 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *string,
/*
* If in master/slave mode, we do not send COMMIT/ABORT to
- * slaves/standbys if it's in I(idle) state.
+ * slaves/standbys if it's not in I(idle in transaction)
+ * state.
*/
if (is_commit && MASTER_SLAVE && !IS_MASTER_NODE_ID(i) && TSTATE(backend, i) == 'I')
{
@@ -571,6 +572,17 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *string,
continue;
}
+ /*
+ * If in reset context, we send COMMIT/ABORT to nodes those
+ * are not in I(idle) state. This will ensure that
+ * transactions are closed.
+ */
+ if (is_commit && session_context->reset_context && TSTATE(backend, i) == 'I')
+ {
+ pool_unset_node_to_be_sent(query_context, i);
+ continue;
+ }
+
per_node_statement_log(backend, i, string);
if (*kind == '\0')
[parent: a758388bed4d]