pgpool2.git / summary / log / commit / refs

commit    b587544733638cbab8e983cdb892179fa9576d40
Author:   Toshihiro Kitagawa <kitagawa at sraoss.co.jp>
Date:     Wed Jul 27 03:32:13 2011 +0000

    Fix bug with the handling of empty query.
    
    JBoss sends empty queries for checking connections. We decided to replace
    the empty query with dummy SELECT command not to affect load balance.
    Empty query has been replaced with dummy DELETE command till now.
    Note: The dummy command is not sent to backends.
    See the following thread for more details:
    [Pgpool-general] Confused about JDBC and load balancing


pool_process_query.c | 4 ++- pool_proto_modules.c | 72 ++++++++++++++++++++++++++++++++++++---------------- pool_proto_modules.h | 3 ++- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/pool_process_query.c b/pool_process_query.c index 2eb8d0e78..540bf138e 100644 --- a/pool_process_query.c +++ b/pool_process_query.c @@ -1483,8 +1483,10 @@ int is_select_query(Node *node, char *sql) if (select_stmt->intoClause || select_stmt->lockingClause) return 0; + /* '\0' and ';' signify empty query */ return (*sql == 's' || *sql == 'S' || *sql == '(' || - *sql == 'w' || *sql == 'W' || *sql == 't' || *sql == 'T'); + *sql == 'w' || *sql == 'W' || *sql == 't' || *sql == 'T' || + *sql == '\0' || *sql == ';'); } else if (IsA(node, CopyStmt)) { diff --git a/pool_proto_modules.c b/pool_proto_modules.c index 5c3f31b8a..d52bc617a 100644 --- a/pool_proto_modules.c +++ b/pool_proto_modules.c @@ -153,17 +153,31 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (parse_tree_list == NIL) { - /* - * Unable to parse the query. Probably syntax error or the - * query is too new and our parser cannot understand. Treat as - * if it were an DELETE command. Note that the DELETE command - * does not execute, instead the original query will be sent - * to backends, which may or may not cause an actual syntax errors. - * The command will be sent to all backends in replication mode - * or master/primary in master/slave mode. - */ - pool_log("SimpleQuery: Unable to parse the query: %s", contents); - parse_tree_list = raw_parser(POOL_DUMMY_QUERY); + /* is the query empty? */ + if (*contents == '\0' || *contents == ';') + { + /* + * JBoss sends empty queries for checking connections. + * We replace the empty query with SELECT command not + * to affect load balance. + * [Pgpool-general] Confused about JDBC and load balancing + */ + parse_tree_list = raw_parser(POOL_DUMMY_READ_QUERY); + } + else + { + /* + * Unable to parse the query. Probably syntax error or the + * query is too new and our parser cannot understand. Treat as + * if it were an DELETE command. Note that the DELETE command + * does not execute, instead the original query will be sent + * to backends, which may or may not cause an actual syntax errors. + * The command will be sent to all backends in replication mode + * or master/primary in master/slave mode. + */ + pool_log("SimpleQuery: Unable to parse the query: %s", contents); + parse_tree_list = raw_parser(POOL_DUMMY_WRITE_QUERY); + } } if (parse_tree_list != NIL) @@ -628,17 +642,31 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (parse_tree_list == NIL) { - /* - * Unable to parse the query. Probably syntax error or the - * query is too new and our parser cannot understand. Treat as - * if it were an DELETE command. Note that the DELETE command - * does not execute, instead the original query will be sent - * to backends, which may or may not cause an actual syntax errors. - * The command will be sent to all backends in replication mode - * or master/primary in master/slave mode. - */ - pool_log("Parse: Unable to parse the query: %s", stmt); - parse_tree_list = raw_parser(POOL_DUMMY_QUERY); + /* is the query empty? */ + if (*stmt == '\0' || *stmt == ';') + { + /* + * JBoss sends empty queries for checking connections. + * We replace the empty query with SELECT command not + * to affect load balance. + * [Pgpool-general] Confused about JDBC and load balancing + */ + parse_tree_list = raw_parser(POOL_DUMMY_READ_QUERY); + } + else + { + /* + * Unable to parse the query. Probably syntax error or the + * query is too new and our parser cannot understand. Treat as + * if it were an DELETE command. Note that the DELETE command + * does not execute, instead the original query will be sent + * to backends, which may or may not cause an actual syntax errors. + * The command will be sent to all backends in replication mode + * or master/primary in master/slave mode. + */ + pool_log("Parse: Unable to parse the query: %s", stmt); + parse_tree_list = raw_parser(POOL_DUMMY_WRITE_QUERY); + } } if (parse_tree_list != NIL) diff --git a/pool_proto_modules.h b/pool_proto_modules.h index e2d99fe77..cabd60df6 100644 --- a/pool_proto_modules.h +++ b/pool_proto_modules.h @@ -36,7 +36,8 @@ #include "pool_process_reporting.h" #define SPECIFIED_ERROR 1 -#define POOL_DUMMY_QUERY "DELETE FROM foo WHERE col = 'pgpool: unable to parse the query'" +#define POOL_DUMMY_WRITE_QUERY "DELETE FROM foo WHERE col = 'pgpool: unable to parse the query'" +#define POOL_DUMMY_READ_QUERY "SELECT 'pgpool: unable to parse the query'" #define POOL_ERROR_QUERY "send invalid query from pgpool to abort transaction" extern char *copy_table; /* copy table name */ [parent: 930f3fad7340]