pgpool2.git / summary / log / commit / refs
commit 78dd359e045baec0ed87997dc392508057ae8c4a
Author: Tatsuo Ishii <ishii at sraoss.co.jp>
Date: Mon Sep 06 05:03:21 2010 +0000
Use custom function pgpool_regclass() instead of regclass to convert
table name to oid. Problem with regclass is, it throws an error if
the table does not exist. pgpool_regclass is just a wrapper of
regclass by using PG_TRY()/PG_CATCH().
If user does not install pgpool_regclass(), pgpool-II falls back
to pre 3.0 behavior, i.e. ignores schema qualification.
doc/pgpool-en.html | 26 ++++++++++++++++++++-
doc/pgpool-ja.html | 28 +++++++++++++++++++---
pool_process_query.c | 35 ++++++++++++++++++++++++----
pool_select_walker.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-------
pool_select_walker.h | 1 +
pool_timestamp.c | 26 ++++++++++++++++++++-
6 files changed, 164 insertions(+), 17 deletions(-)
diff --git a/doc/pgpool-en.html b/doc/pgpool-en.html
index f2b74b02a..bc3879c37 100644
--- a/doc/pgpool-en.html
+++ b/doc/pgpool-en.html
@@ -7,7 +7,7 @@
</head>
<!-- hhmts start -->
-Last modified: Tue Aug 24 14:35:48 JST 2010
+Last modified: Mon Sep 6 13:48:47 JST 2010
<!-- hhmts end -->
<body bgcolor="#ffffff">
@@ -179,6 +179,30 @@ make install
will install pgpool-II. (If you use Solaris or FreeBSD, replace make with gmake)
</p>
</dd>
+
+<dt>Installing pgpool_regclass</dt>
+<dd>
+<p>
+If you are using PostgreSQL 8.0 or later, we strongly recommend to
+intall pgpool_regclass, which is used internally by pgpool-II.
+Without this, handling of duplicate table names in different schema
+might cause a trouble(temporary tables do not count on this).
+</p>
+<p>
+<pre>
+# cd pgpool-II-x.x.x/sql/pgpool-regclass
+# make
+# make install
+# psql -f pgpool-regclass.sql template1
+</pre>
+</p>
+<p>
+Executing pgpool-regclass.sql should be performed on every databases you
+want to use through pgpool-II.
+You do not need to do this if the database is created after the
+execution of "psql -f pgpool-regclass.sql template1".
+</p>
+
</dl>
<h1>Configuring pgpool-II<a name="config"></a></h1>
diff --git a/doc/pgpool-ja.html b/doc/pgpool-ja.html
index cdadd83d7..3f9178d04 100644
--- a/doc/pgpool-ja.html
+++ b/doc/pgpool-ja.html
@@ -8,7 +8,7 @@
<body>
<!-- hhmts start -->
-Last modified: Wed Aug 25 09:58:55 JST 2010
+Last modified: Mon Sep 6 13:45:53 JST 2010
<!-- hhmts end -->
<body bgcolor="#ffffff">
@@ -159,9 +159,31 @@ PostgreSQL$B$N%/%i%$%"%s%H%i%$%V%i%j$J$I$,%$%s%9%H!<%k$5$l$F$$$k%H%C%W%G%#(B
make
make install
</pre>
-$B$G%$%s%9%H!<%k$,40N;$7$^$9(B(GNU make$B$,I,MW$J$N$G!"(BSolaris$B$d(BFreeBSD$B$J$I$G$O(B
-make$B$r(Bgmake$B$KFI$_BX$($F$/$@$5$$(B)$B!#(B
+</p>
+
+<dt>pgpool_regclass$B$N%$%s%9%H!<%k(B
+<dd>
+<p>
+PostgreSQL 8.0$B0J9_$r;HMQ$7$F$$$k>l9g$O!"(Bpgpool-II$B$,FbIt$G;HMQ$9$k(BC$B4X?t(Bpgpool_regclass$B$r%$%s%9%H!<%k$7$^$9!#(B
+$B$3$N4X?t$,%$%s%9%H!<%k$5$l$F$$$J$/$F$b(Bpgpool-II$B$OF0:n$7$^$9$,!"0c$&%9%-!<%^$GF1$8%F!<%V%kL>$rDj5A$7$F$$$F!"(BSQL$BJ8$NCf$G%9%-!<%^L>$r>JN,$7$F$$$k>l9g$K!"IT6q9g$,@8$8$k$3$H$,$"$j$^$9(B($B0l;~%F!<%V%k$r=|$/(B)$B!#(B
+$B$7$?$,$C$F!"2DG=$J$i$P(Bpgpool_regclass$B$r%$%s%9%H!<%k$9$k$3$H$r$*4+$a$7$^$9!#(B
+
+<pre>
+# cd pgpool-II-x.x.x/sql/pgpool-regclass
+# make
+# make install
+# psql -f pgpool-regclass.sql template1
+</pre>
+
+pgpool-regclass.sql$B$N<B9T$O!"(Bpgpool-II$B7PM3$GMxMQ$9$k%G!<%?%Y!<%9Kh$KI,MW$K$J$j$^$9!#(B
+$B$?$@$7!"(B"psql -f pgpool-regclass.sql template1"$B$r<B9T8e$K:n@.$5$l$?%G!<%?%Y!<%9$G$O<+F0E*$K(Bpgpool-regclass.sql$B$NFbMF$,H?1G$5$l$F$$$k$N$G!"?7$?$K(Bpgpool-regclass.sql$B$r<B9T$9$kI,MW$O$"$j$^$;$s!#(B
+</p>
+
</dl>
+<p>
+$B0J>e$G%$%s%9%H!<%k$,40N;$7$^$9(B(GNU make$B$,I,MW$J$N$G!"(BSolaris$B$d(BFreeBSD$B$J$I$G$O(B
+make$B$r(Bgmake$B$KFI$_BX$($F$/$@$5$$(B)$B!#(B
+</p>
<h1>pgpool-II$B$N@_Dj(B<a name="config"></a></h1>
<p>
diff --git a/pool_process_query.c b/pool_process_query.c
index 5123d358d..90e25e63a 100644
--- a/pool_process_query.c
+++ b/pool_process_query.c
@@ -50,6 +50,7 @@
#include "pool_stream.h"
#include "pool_session_context.h"
#include "pool_query_context.h"
+#include "pool_select_walker.h"
#ifndef FD_SETSIZE
#define FD_SETSIZE 512
@@ -2634,7 +2635,9 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node)
* Query to know if the target table has SERIAL column or not.
* This query is valid through PostgreSQL 7.3 or higher.
*/
-#define NEXTVALQUERY "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = '%s'::regclass::oid"
+#define NEXTVALQUERY "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.relname = '%s'"
+
+#define NEXTVALQUERY2 "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = pgpool_regclass('%s')"
char *str;
int result;
@@ -2681,7 +2684,18 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node)
*/
if (!relcache)
{
- relcache = pool_create_relcache(32, NEXTVALQUERY,
+ char *query;
+
+ if (pool_has_pgpool_regclass())
+ {
+ query = NEXTVALQUERY2;
+ }
+ else
+ {
+ query = NEXTVALQUERY;
+ }
+
+ relcache = pool_create_relcache(32, query,
int_register_func, int_unregister_func,
false);
if (relcache == NULL)
@@ -2710,7 +2724,9 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend
POOL_STATUS status;
int i, deadlock_detected = 0;
-#define SEQUENCETABLEQUERY "SELECT attname FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = '%s'::regclass::oid AND d.adsrc ~ 'nextval'"
+#define SEQUENCETABLEQUERY "SELECT attname FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s' AND d.adsrc ~ 'nextval'"
+
+#define SEQUENCETABLEQUERY2 "SELECT attname FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum) WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s') AND d.adsrc ~ 'nextval'"
#define MAX_SEQ_NAME 128
@@ -2739,7 +2755,18 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend
*/
if (!relcache)
{
- relcache = pool_create_relcache(32, SEQUENCETABLEQUERY,
+ char *query;
+
+ if (pool_has_pgpool_regclass())
+ {
+ query = SEQUENCETABLEQUERY2;
+ }
+ else
+ {
+ query = SEQUENCETABLEQUERY;
+ }
+
+ relcache = pool_create_relcache(32, query,
string_register_func, string_unregister_func,
false);
if (relcache == NULL)
diff --git a/pool_select_walker.c b/pool_select_walker.c
index f517e23c2..5732336a3 100644
--- a/pool_select_walker.c
+++ b/pool_select_walker.c
@@ -223,7 +223,9 @@ static bool is_system_catalog(char *table_name)
/*
* Query to know if the target table belongs pg_catalog schema.
*/
-#define ISBELONGTOPGCATALOGQUERY "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = '%s'::regclass::oid AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"
+#define ISBELONGTOPGCATALOGQUERY "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"
+
+#define ISBELONGTOPGCATALOGQUERY2 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = pgpool_regclass('%s') AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'"
int hasreliscatalog;
bool result;
@@ -243,7 +245,19 @@ static bool is_system_catalog(char *table_name)
*/
if (!hasreliscatalog_cache)
{
- hasreliscatalog_cache = pool_create_relcache(32, HASPGNAMESPACEQUERY,
+ char *query;
+
+ /* pgpool_regclass has been installed */
+ if (pool_has_pgpool_regclass())
+ {
+ query = ISBELONGTOPGCATALOGQUERY2;
+ }
+ else
+ {
+ query = ISBELONGTOPGCATALOGQUERY;
+ }
+
+ hasreliscatalog_cache = pool_create_relcache(32, query,
int_register_func, int_unregister_func,
false);
if (hasreliscatalog_cache == NULL)
@@ -297,16 +311,20 @@ static bool is_temp_table(char *table_name)
#define HASRELITEMPPQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c, pg_attribute AS a WHERE c.relname = 'pg_class' AND a.attrelid = c.oid AND a.attname = 'relistemp'"
/*
- * Query to know if the target table is a temporary one.
- * This query is valid through PostgreSQL 7.3 to 8.3.
+ * Query to know if the target table is a temporary one. This query
+ * is valid through PostgreSQL 7.3 to 8.3. We do not use regclass (or
+ * its variant) here, because temporary tables never have schema
+ * qualified name.
*/
-#define ISTEMPQUERY83 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = '%s'::regclass::oid AND c.relnamespace = n.oid AND n.nspname ~ '^pg_temp_'"
+#define ISTEMPQUERY83 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname ~ '^pg_temp_'"
/*
- * Query to know if the target table is a temporary one.
- * This query is valid PostgreSQL 8.4 or later.
+ * Query to know if the target table is a temporary one. This query
+ * is valid PostgreSQL 8.4 or later. We do not use regclass (or its
+ * variant) here, because temporary tables never have schema qualified
+ * name.
*/
-#define ISTEMPQUERY84 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = '%s'::regclass::oid AND c.relistemp"
+#define ISTEMPQUERY84 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relistemp"
int hasrelistemp;
bool result;
@@ -364,3 +382,34 @@ static bool is_temp_table(char *table_name)
result = pool_search_relcache(relcache, backend, table_name)==0?false:true;
return result;
}
+
+/*
+ * Judge if we have pgpool_regclass or not.
+ */
+bool pool_has_pgpool_regclass(void)
+{
+/*
+ * Query to know if pgpool_regclass exists.
+ */
+#define HASPGPOOL_REGCLASSQUERY "SELECT count(*) FROM pg_catalog.pg_proc AS p WHERE p.proname = '%s'"
+ bool result;
+ static POOL_RELCACHE *relcache;
+ POOL_CONNECTION_POOL *backend;
+
+ backend = pool_get_session_context()->backend;
+
+ if (!relcache)
+ {
+ relcache = pool_create_relcache(32, HASPGPOOL_REGCLASSQUERY,
+ int_register_func, int_unregister_func,
+ false);
+ if (relcache == NULL)
+ {
+ pool_error("has_pgpool_regclass: pool_create_relcache error");
+ return false;
+ }
+ }
+
+ result = pool_search_relcache(relcache, backend, "pgpool_regclass")==0?0:1;
+ return result;
+}
diff --git a/pool_select_walker.h b/pool_select_walker.h
index 110a6102b..66acf65fc 100644
--- a/pool_select_walker.h
+++ b/pool_select_walker.h
@@ -32,6 +32,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_pgpool_regclass(void);
extern bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context);
#endif /* POOL_SELECT_WALKER_H */
diff --git a/pool_timestamp.c b/pool_timestamp.c
index 0294b903d..228879af2 100644
--- a/pool_timestamp.c
+++ b/pool_timestamp.c
@@ -26,6 +26,7 @@
#include "pool.h"
#include "pool_timestamp.h"
#include "pool_relcache.h"
+#include "pool_select_walker.h"
#include "pool_config.h"
#include "parser/parsenodes.h"
#include "parser/gramparse.h"
@@ -118,9 +119,32 @@ relcache_lookup(TSRewriteContext *ctx)
" , false)" \
" FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
" LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
- " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = '%s'::regclass::oid" \
+ " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.relname = '%s'" \
" ORDER BY a.attnum"
+#define ATTRDEFQUERY2 "SELECT attname, coalesce((d.adsrc = 'now()' OR d.adsrc LIKE '%%''now''::text%%')" \
+ " AND (a.atttypid = 'timestamp'::regtype::oid OR" \
+ " a.atttypid = 'timestamp with time zone'::regtype::oid OR" \
+ " a.atttypid = 'date'::regtype::oid OR" \
+ " a.atttypid = 'time'::regtype::oid OR" \
+ " a.atttypid = 'time with time zone'::regtype::oid)" \
+ " , false)" \
+ " FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a " \
+ " LEFT JOIN pg_catalog.pg_attrdef d ON (a.attrelid = d.adrelid AND a.attnum = d.adnum)" \
+ " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = pgpool_regclass('%s')" \
+ " ORDER BY a.attnum"
+
+ char *query;
+
+ if (pool_has_pgpool_regclass())
+ {
+ query = ATTRDEFQUERY2;
+ }
+ else
+ {
+ query = ATTRDEFQUERY;
+ }
+
if (!ts_relcache)
{
ts_relcache = pool_create_relcache(MAX_RELCACHE, ATTRDEFQUERY, ts_register_func, ts_unregister_func, false);
[parent: ee7b628f9f6a]