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]