Use pg_get_expr() instead of pg_attrdef.adsrc to support for PostgreSQL 12.
authorBo Peng <pengbo@sraoss.co.jp>
Wed, 24 Jul 2019 12:19:26 +0000 (21:19 +0900)
committerBo Peng <pengbo@sraoss.co.jp>
Wed, 24 Jul 2019 12:31:13 +0000 (21:31 +0900)
Since PostgreSQL 12 removed pg_attrdef.adsrc, use pg_get_expr() instead of pg_attrdef.adsrc if the backend version is 7.3 or later.

Thanks to Takuma Hoshiai for creating the patch.

src/include/protocol/protocol_defs.h
src/protocol/pool_process_query.c
src/rewrite/pool_timestamp.c

index 14da4c424f928653d47a9723506e5c8e08f9b6ca..cb9016cf26c1eb3e95cac29744a51ae6dc43c300 100644 (file)
 #ifndef pgpool_protocol_defs_h
 #define pgpool_protocol_defs_h
 
-#define SEQUENCETABLEQUERY "SELECT d.adsrc 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 SEQUENCETABLEQUERY (Pgversion(backend)->major >= 73 ? \
+       "SELECT pg_get_expr(d.adbin, d.adrelid) 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.pg_get_expr(d.adbin, d.adrelid) ~ 'nextval'" : \
+       "SELECT d.adsrc 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 d.adsrc 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 SEQUENCETABLEQUERY2 (Pgversion(backend)->major >= 73 ? \
+       "SELECT pg_get_expr(d.adbin, d.adrelid) 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 pg_get_expr(d.adbin, d.adrelid) ~ 'nextval'" : \
+       "SELECT d.adsrc 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 SEQUENCETABLEQUERY3 "SELECT d.adsrc 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 = pg_catalog.to_regclass('%s') AND d.adsrc ~ 'nextval'"
+#define SEQUENCETABLEQUERY3 (Pgversion(backend)->major >= 73 ? \
+       "SELECT pg_get_expr(d.adbin, d.adrelid) 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 = pg_catalog.to_regclass('%s') AND pg_get_expr(d.adbin, d.adrelid) ~ 'nextval'" : \
+       "SELECT d.adsrc 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 = pg_catalog.to_regclass('%s') AND d.adsrc ~ 'nextval'")
 
 /* query to lock a row by only the specified table name without regard to the schema */
 #define ROWLOCKQUERY "SELECT 1 FROM pgpool_catalog.insert_lock WHERE reloid = (SELECT oid FROM pg_catalog.pg_class WHERE relname = '%s' ORDER BY oid LIMIT 1) FOR UPDATE"
index 0cc4816054855c6b002b9e8651c70cb910b47b86..ef773b2ea479075bcce0afff4fa6b7f7190d0026 100644 (file)
@@ -2831,11 +2831,17 @@ 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.relname = '%s'"
+#define NEXTVALQUERY (Pgversion(backend)->major >= 73 ? \
+       "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND pg_get_expr(d.adbin, d.adrelid) ~ 'nextval' AND c.relname = '%s'" : \
+       "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')"
+#define NEXTVALQUERY2 (Pgversion(backend)->major >= 73 ? \
+       "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND pg_get_expr(d.adbin, d.adrelid) ~ 'nextval' AND c.oid = pgpool_regclass('%s')" : \
+       "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')")
 
-#define NEXTVALQUERY3 "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 = pg_catalog.to_regclass('%s')"
+#define NEXTVALQUERY3 (Pgversion(backend)->major >= 73 ? \
+       "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND pg_get_expr(d.adbin, d.adrelid) ~ 'nextval' AND c.oid = pg_catalog.to_regclass('%s')" : \
+       "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 = pg_catalog.to_regclass('%s')")
 
        char *table;
        int result;
index 7d8fee99842f398ee064d903e30f0252a9f805b3..6bd41f45416c95cfa09d5f5e652b9c72e1250fe9 100644 (file)
@@ -125,7 +125,21 @@ ts_unregister_func(void *data)
 static TSRel*
 relcache_lookup(TSRewriteContext *ctx)
 {
-#define ATTRDEFQUERY "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \
+#define ATTRDEFQUERY (Pgversion(ctx->backend)->major >= 73 ? \
+       "SELECT attname, pg_get_expr(d.adbin, d.adrelid), coalesce((pg_get_expr(d.adbin, d.adrelid) LIKE '%%now()%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%''now''::text%%' OR" \
+       " pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_TIMESTAMP%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_TIME%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_DATE%%' OR" \
+       " pg_get_expr(d.adbin, d.adrelid) LIKE '%%LOCALTIME%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%LOCALTIMESTAMP%%')" \
+       " 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.relname = '%s'" \
+       " ORDER BY a.attnum" : \
+       "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \
        " d.adsrc LIKE '%%CURRENT_TIMESTAMP%%' OR d.adsrc LIKE '%%CURRENT_TIME%%' OR d.adsrc LIKE '%%CURRENT_DATE%%' OR" \
        " d.adsrc LIKE '%%LOCALTIME%%' OR d.adsrc LIKE '%%LOCALTIMESTAMP%%')" \
        " AND (a.atttypid = 'timestamp'::regtype::oid OR" \
@@ -137,9 +151,23 @@ relcache_lookup(TSRewriteContext *ctx)
        " 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'" \
-       " ORDER BY a.attnum"
+       " ORDER BY a.attnum")
 
-#define ATTRDEFQUERY2 "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \
+#define ATTRDEFQUERY2 (Pgversion(ctx->backend)->major >= 73 ? \
+       "SELECT attname, pg_get_expr(d.adbin, d.adrelid), coalesce((pg_get_expr(d.adbin, d.adrelid) LIKE '%%now()%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%''now''::text%%' OR" \
+       " pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_TIMESTAMP%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_TIME%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_DATE%%' OR" \
+       " pg_get_expr(d.adbin, d.adrelid) LIKE '%%LOCALTIME%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%LOCALTIMESTAMP%%')" \
+       " 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" : \
+       "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \
        " d.adsrc LIKE '%%CURRENT_TIMESTAMP%%' OR d.adsrc LIKE '%%CURRENT_TIME%%' OR d.adsrc LIKE '%%CURRENT_DATE%%' OR" \
        " d.adsrc LIKE '%%LOCALTIME%%' OR d.adsrc LIKE '%%LOCALTIMESTAMP%%')" \
        " AND (a.atttypid = 'timestamp'::regtype::oid OR" \
@@ -151,9 +179,23 @@ relcache_lookup(TSRewriteContext *ctx)
        " 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"
+       " ORDER BY a.attnum")
 
-#define ATTRDEFQUERY3 "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \
+#define ATTRDEFQUERY3 (Pgversion(ctx->backend)->major >= 73 ? \
+       "SELECT attname, pg_get_expr(d.adbin, d.adrelid), coalesce((pg_get_expr(d.adbin, d.adrelid) LIKE '%%now()%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%''now''::text%%' OR" \
+       " pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_TIMESTAMP%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_TIME%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%CURRENT_DATE%%' OR" \
+       " pg_get_expr(d.adbin, d.adrelid) LIKE '%%LOCALTIME%%' OR pg_get_expr(d.adbin, d.adrelid) LIKE '%%LOCALTIMESTAMP%%')" \
+       " 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 = to_regclass('%s')" \
+       " ORDER BY a.attnum" : \
+       "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \
        " d.adsrc LIKE '%%CURRENT_TIMESTAMP%%' OR d.adsrc LIKE '%%CURRENT_TIME%%' OR d.adsrc LIKE '%%CURRENT_DATE%%' OR" \
        " d.adsrc LIKE '%%LOCALTIME%%' OR d.adsrc LIKE '%%LOCALTIMESTAMP%%')" \
        " AND (a.atttypid = 'timestamp'::regtype::oid OR" \
@@ -165,7 +207,7 @@ relcache_lookup(TSRewriteContext *ctx)
        " 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 = to_regclass('%s')" \
-       " ORDER BY a.attnum"
+       " ORDER BY a.attnum")
 
        char *query;
        char *table_name;