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:30:55 +0000 (21:30 +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 fe89b7ab6211cbdbaca7d892b00e8674b7cb344f..150916bf49e79862e1e872b836a34b740fffee79 100644 (file)
@@ -2403,11 +2403,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 cd602125d7655108baeead671a96df041373b976..0e9b34ebded20f3cd42f985899c19ed5e47aae03 100644 (file)
@@ -130,7 +130,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" \
@@ -142,9 +156,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" \
@@ -156,9 +184,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" \
@@ -170,7 +212,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;