pgpool2.git / summary / log / commit / refs
commit e1c1e9432adeb3fa44fd2c35885c58b0b8548195
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Thu Aug 18 01:27:45 2011 +0000
Fix send_to_where() so that it correctly recognizes FOR SHARE/UPDATE
clause even if it's in subquery. Before it only recognized
when the clause was in top level of SELECT. For this new function
pool_has_insertinto_or_locking_clause() is added.
Make pattern_compare() to static since it's not used anywhere outside
of pool_select_walker.c
pool_config.h | 1 -
pool_query_context.c | 9 ++-------
pool_select_walker.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
pool_select_walker.h | 1 +
4 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/pool_config.h b/pool_config.h
index 6a43ba36b..280be8e68 100644
--- a/pool_config.h
+++ b/pool_config.h
@@ -204,6 +204,5 @@ extern int set_syslog_facility (char *);
/* methods used for regexp support */
extern int add_regex_pattern(char *type, char *s);
extern int growPatternArray (RegPattern item);
-extern int pattern_compare(char *str, const int type);
#endif /* POOL_CONFIG_H */
diff --git a/pool_query_context.c b/pool_query_context.c
index 7305dc252..e6deb9601 100644
--- a/pool_query_context.c
+++ b/pool_query_context.c
@@ -1010,14 +1010,9 @@ static POOL_DEST send_to_where(Node *node, char *query)
*/
if (IsA(node, SelectStmt))
{
- /* SELECT INTO? */
- if (((SelectStmt *)node)->intoClause)
+ /* SELECT INTO or SELECT FOR SHARE or UPDATE ? */
+ if (pool_has_insertinto_or_locking_clause(node))
return POOL_PRIMARY;
-
- /* SELECT FOR SHARE or UPDATE */
- else if (((SelectStmt *)node)->lockingClause)
- return POOL_PRIMARY;
-
/*
* SELECT nextval(), setval()
* XXX: We do not search in subquery.
diff --git a/pool_select_walker.c b/pool_select_walker.c
index ea846c5fb..3d1b670d7 100644
--- a/pool_select_walker.c
+++ b/pool_select_walker.c
@@ -34,6 +34,7 @@ typedef struct {
bool has_temp_table; /* True if temporary table is used */
bool has_unlogged_table; /* True if unlogged table is used */
bool has_function_call; /* True if write function call is used */
+ bool has_insertinto_or_locking_clause; /* True if it has SELECT INTO or FOR SHARE/UPDATE */
} SelectContext;
static bool function_call_walker(Node *node, void *context);
@@ -43,6 +44,8 @@ static bool temp_table_walker(Node *node, void *context);
static bool unlogged_table_walker(Node *node, void *context);
static bool is_temp_table(char *table_name);
static bool is_unlogged_table(char *table_name);
+static bool insertinto_or_locking_clause_walker(Node *node, void *context);
+static int pattern_compare(char *str, const int type);
/*
* Return true if this SELECT has function calls *and* supposed to
@@ -117,6 +120,26 @@ bool pool_has_unlogged_table(Node *node)
return ctx.has_unlogged_table;
}
+/*
+ * Return true if this SELECT has INSERT INTO or FOR SHARE or FOR UDPATE.
+ */
+bool pool_has_insertinto_or_locking_clause(Node *node)
+{
+ SelectContext ctx;
+
+ if (!IsA(node, SelectStmt))
+ return false;
+
+ ctx.has_insertinto_or_locking_clause = false;
+
+ raw_expression_tree_walker(node, insertinto_or_locking_clause_walker, &ctx);
+
+ pool_debug("pool_has_insertinto_or_locking_clause: returns %d",
+ ctx.has_insertinto_or_locking_clause);
+
+ return ctx.has_insertinto_or_locking_clause;
+}
+
/*
* Search function name in whilelist or blacklist regex array
* Return 1 on success (found in list)
@@ -124,7 +147,7 @@ bool pool_has_unlogged_table(Node *node)
* Return -1 if the given search type doesn't exist.
* Search type supported are: WHITELIST and BLACKLIST
*/
-int pattern_compare(char *str, const int type)
+static int pattern_compare(char *str, const int type)
{
int i = 0;
@@ -590,3 +613,21 @@ bool pool_has_pgpool_regclass(void)
result = pool_search_relcache(relcache, backend, "pgpool_regclass")==0?0:1;
return result;
}
+
+/*
+ * Walker function to find intoClause or lockingClause.
+ */
+static bool insertinto_or_locking_clause_walker(Node *node, void *context)
+{
+ SelectContext *ctx = (SelectContext *) context;
+
+ if (node == NULL)
+ return false;
+
+ if (IsA(node, IntoClause) || IsA(node, LockingClause))
+ {
+ ctx->has_insertinto_or_locking_clause = true;
+ return false;
+ }
+ return raw_expression_tree_walker(node, insertinto_or_locking_clause_walker, ctx);
+}
diff --git a/pool_select_walker.h b/pool_select_walker.h
index 24ff6070a..222e1449e 100644
--- a/pool_select_walker.h
+++ b/pool_select_walker.h
@@ -33,6 +33,7 @@ extern bool pool_has_function_call(Node *node);
extern bool pool_has_system_catalog(Node *node);
extern bool pool_has_temp_table(Node *node);
extern bool pool_has_unlogged_table(Node *node);
+extern bool pool_has_insertinto_or_locking_clause(Node *node);
extern bool pool_has_pgpool_regclass(void);
extern bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context);
[parent: 4d58bfbe2adf]