OSDN Git Service

PG14 support
authorTatsuro Yamada <yamatattsu@gmail.com>
Fri, 5 Nov 2021 07:00:01 +0000 (16:00 +0900)
committerKyotaro Horiguchi <horikyota.ntt@gmail.com>
Thu, 25 Nov 2021 10:31:07 +0000 (19:31 +0900)
- Successfully builds on PG14, and also passes PG13 regression tests.
- The new node types added in PG14 are not yet supported.

Co-Author: Julien Rouhaud <julien.rouhaud@free.fr>

Makefile
SPECS/pg_store_plans14.spec [moved from SPECS/pg_store_plans13.spec with 77% similarity]
expected/store_2.out [new file with mode: 0644]
pg_store_plans--1.6.sql [moved from pg_store_plans--1.5.sql with 97% similarity]
pg_store_plans.c
pg_store_plans.control
pgsp_explain.c

index de5ccef..f80e12b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # pg_stat_plan/Makefile
 
 MODULES = pg_store_plans
-STOREPLANSVER = 1.5
+STOREPLANSVER = 1.6
 
 MODULE_big = pg_store_plans
 OBJS = pg_store_plans.o pgsp_json.o pgsp_json_text.o pgsp_explain.o
@@ -10,7 +10,7 @@ EXTENSION = pg_store_plans
 
 PG_VERSION := $(shell pg_config --version | sed "s/^PostgreSQL //" | sed "s/\.[0-9]*$$//")
 
-DATA = pg_store_plans--1.5.sql
+DATA = pg_store_plans--1.6.sql
 
 REGRESS = convert store
 REGRESS_OPTS = --temp-config=regress.conf
@@ -25,8 +25,8 @@ include $(top_builddir)/src/Makefile.global
 include $(top_srcdir)/contrib/contrib-global.mk
 endif
 
-STARBALL13 = pg_store_plans13-$(STOREPLANSVER).tar.gz
-STARBALLS = $(STARBALL13)
+STARBALL14 = pg_store_plans14-$(STOREPLANSVER).tar.gz
+STARBALLS = $(STARBALL14)
 
 TARSOURCES = Makefile *.c  *.h \
        pg_store_plans--*.sql \
@@ -38,7 +38,7 @@ LDFLAGS+=-Wl,--build-id
 ## These entries need running server
 DBNAME = postgres
 
-rpms: rpm13
+rpms: rpm14
 
 $(STARBALLS): $(TARSOURCES)
        if [ -h $(subst .tar.gz,,$@) ]; then rm $(subst .tar.gz,,$@); fi
@@ -50,8 +50,8 @@ $(STARBALLS): $(TARSOURCES)
        tar -chzf $@ $(addprefix $(subst .tar.gz,,$@)/, $^)
        rm $(subst .tar.gz,,$@)
 
-rpm13: $(STARBALL13)
-       MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_store_plans13.spec
+rpm14: $(STARBALL14)
+       MAKE_ROOT=`pwd` rpmbuild -bb SPECS/pg_store_plans14.spec
 
 testfiles: convert.out convert.sql
 
similarity index 77%
rename from SPECS/pg_store_plans13.spec
rename to SPECS/pg_store_plans14.spec
index 4fe6512..2b1abbf 100644 (file)
@@ -1,7 +1,7 @@
 # SPEC file for pg_store_plans
 # Copyright(c) 2021, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
 
-%define _pgdir   /usr/pgsql-13
+%define _pgdir   /usr/pgsql-14
 %define _bindir  %{_pgdir}/bin
 %define _libdir  %{_pgdir}/lib
 %define _datadir %{_pgdir}/share
@@ -14,9 +14,9 @@
 %endif
 
 ## Set general information for pg_store_plans.
-Summary:    Record executed plans on PostgreSQL 13
-Name:       pg_store_plans13
-Version:    1.5
+Summary:    Record executed plans on PostgreSQL 14
+Name:       pg_store_plans14
+Version:    1.6
 Release:    1%{?dist}
 License:    BSD
 Group:      Applications/Databases
@@ -26,8 +26,8 @@ BuildRoot:  %{_tmppath}/%{name}-%{version}-%{release}-%(%{__id_u} -n)
 Vendor:     NIPPON TELEGRAPH AND TELEPHONE CORPORATION
 
 ## We use postgresql-devel package
-BuildRequires:  postgresql13-devel
-Requires:  postgresql13-libs
+BuildRequires:  postgresql14-devel
+Requires:  postgresql14-libs
 
 ## Description for "pg_store_plans"
 %description
@@ -35,19 +35,19 @@ Requires:  postgresql13-libs
 pg_store_plans provides capability to record statistics for every plan
 executed on PostgreSQL.
 
-Note that this package is available for only PostgreSQL 13.
+Note that this package is available for only PostgreSQL 14.
 
 %package llvmjit
-Requires: postgresql13-server, postgresql13-llvmjit
-Requires: pg_store_plans13 = 1.5
-Summary:  Just-in-time compilation support for pg_store_plans13
+Requires: postgresql14-server, postgresql14-llvmjit
+Requires: pg_store_plans14 = 1.6
+Summary:  Just-in-time compilation support for pg_store_plans14
 
 %description llvmjit
-Just-in-time compilation support for pg_store_plans13
+Just-in-time compilation support for pg_store_plans14
 
 ## pre work for build pg_store_plans
 %prep
-PATH=/usr/pgsql-13/bin:$PATH
+PATH=/usr/pgsql-14/bin:$PATH
 if [ "${MAKE_ROOT}" != "" ]; then
   pushd ${MAKE_ROOT}
   make clean %{name}-%{version}.tar.gz
@@ -58,14 +58,14 @@ if [ ! -d %{_rpmdir} ]; then mkdir -p %{_rpmdir}; fi
 
 ## Set variables for build environment
 %build
-PATH=/usr/pgsql-13/bin:$PATH
+PATH=/usr/pgsql-14/bin:$PATH
 pg_config
 make USE_PGXS=1 %{?_smp_mflags}
 
 ## Set variables for install
 %install
 rm -rf %{buildroot}
-PATH=/usr/pgsql-13/bin:$PATH
+PATH=/usr/pgsql-14/bin:$PATH
 make install DESTDIR=%{buildroot}
 
 %clean
@@ -75,7 +75,7 @@ rm -rf %{buildroot}
 %defattr(0755,root,root)
 %{_libdir}/pg_store_plans.so
 %defattr(0644,root,root)
-%{_datadir}/extension/pg_store_plans--1.5.sql
+%{_datadir}/extension/pg_store_plans--1.6.sql
 %{_datadir}/extension/pg_store_plans.control
 
 %files llvmjit
@@ -85,6 +85,8 @@ rm -rf %{buildroot}
 
 # History of pg_store_plans.
 %changelog
+* Wed Nov xx 2021 Tatsuro Yamada, Julien Rouhaud, Kyotaro Horiguchi
+- Version 1.6. Supports PostgreSQL 14
 * Wed Jan 27 2021 Kyotaro Horiguchi
 - Version 1.5. Supports PostgreSQL 13
 * Thu Jan 30 2020 Kyotaro Horiguchi
diff --git a/expected/store_2.out b/expected/store_2.out
new file mode 100644 (file)
index 0000000..8a347b5
--- /dev/null
@@ -0,0 +1,123 @@
+SET client_min_messages = 'error';
+CREATE EXTENSION IF NOT EXISTS pg_store_plans;
+CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
+SELECT pg_stat_statements_reset();
+ pg_stat_statements_reset 
+--------------------------
+(1 row)
+
+SELECT pg_store_plans_reset();
+ pg_store_plans_reset 
+----------------------
+(1 row)
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a int);
+CREATE INDEX ON t1 (a);
+INSERT INTO t1 (SELECT a FROM generate_series(0, 9999) a);
+RESET enable_seqscan;
+RESET enable_bitmapscan;
+SELECT count(*) FROM (SELECT * FROM t1) AS x;
+ count 
+-------
+ 10000
+(1 row)
+
+SET enable_seqscan TO false;
+SELECT count(*) FROM (SELECT * FROM t1) AS x;
+ count 
+-------
+ 10000
+(1 row)
+
+SELECT count(*) FROM (SELECT * FROM t1) AS x;
+ count 
+-------
+ 10000
+(1 row)
+
+SET enable_bitmapscan TO false;
+SELECT count(*) FROM (SELECT * FROM t1) AS x;
+ count 
+-------
+ 10000
+(1 row)
+
+SELECT count(*) FROM (SELECT * FROM t1) AS x;
+ count 
+-------
+ 10000
+(1 row)
+
+SELECT count(*) FROM (SELECT * FROM t1) AS x;
+ count 
+-------
+ 10000
+(1 row)
+
+RESET enable_seqscan;
+RESET enable_bitmapscan;
+CREATE OR REPLACE FUNCTION test_explain() RETURNS text AS
+$x$
+DECLARE
+    r record;
+    s text;
+    p text;
+    totalrows int;
+    totalcalls int;
+    first bool;
+BEGIN
+    s := '';
+    first = true;
+    SELECT calls, rows INTO totalcalls, totalrows
+    FROM pg_stat_statements
+    WHERE query = 'SELECT count(*) FROM (SELECT * FROM t1) AS x';
+
+    FOR r IN SELECT s.query as q, p.plan as p, p.calls as c, p.rows r
+             FROM pg_stat_statements s
+             JOIN pg_store_plans p ON (s.queryid = p.queryid_stat_statements)
+             WHERE s.query = 'SELECT count(*) FROM (SELECT * FROM t1) AS x'
+             ORDER BY p.calls
+    LOOP
+         IF first then
+        s = r.q || E'\n  totalcalls=' || totalcalls ||
+            ' , totalrows=' || totalrows || E'\n';
+        first := false;
+      END IF;
+      p := regexp_replace(r.p, '=[0-9.]+([^0-9.])', '=xxx\1', 'g');
+      s := s || p || E'\n  calls=' || r.c || ', rows=' || r.r || E'\n';
+    END LOOP;
+
+    RETURN s;
+END
+$x$
+LANGUAGE plpgsql;
+SELECT test_explain();
+                                test_explain                                 
+-----------------------------------------------------------------------------
+ SELECT count(*) FROM (SELECT * FROM t1) AS x                               +
+   totalcalls=6 , totalrows=6                                               +
+ Aggregate  (cost=xxx rows=xxx width=xxx)                                   +
+   Async Capable: false                                                     +
+   ->  Seq Scan on t1  (cost=xxx rows=xxx width=xxx)                        +
+         Async Capable: false                                               +
+   calls=1, rows=1                                                          +
+ Aggregate  (cost=xxx rows=xxx width=xxx)                                   +
+   Async Capable: false                                                     +
+   ->  Bitmap Heap Scan on t1  (cost=xxx rows=xxx width=xxx)                +
+         Async Capable: false                                               +
+         ->  Bitmap Index Scan using t1_a_idx  (cost=xxx rows=xxx width=xxx)+
+               Async Capable: false                                         +
+   calls=2, rows=2                                                          +
+ Aggregate  (cost=xxx rows=xxx width=xxx)                                   +
+   Async Capable: false                                                     +
+   ->  Index Only Scan using t1_a_idx on t1  (cost=xxx rows=xxx width=xxx)  +
+         Async Capable: false                                               +
+   calls=3, rows=3                                                          +
+(1 row)
+
+DROP FUNCTION test_explain();
+DROP TABLE t1;
similarity index 97%
rename from pg_store_plans--1.5.sql
rename to pg_store_plans--1.6.sql
index d03367c..771e232 100644 (file)
@@ -1,4 +1,4 @@
-/* pg_store_plans/pg_store_plans--1.4.sql */
+/* pg_store_plans/pg_store_plans--1.6.sql */
 
 -- complain if script is sourced in psql, rather than via CREATE EXTENSION
 \echo Use "CREATE EXTENSION pg_store_plans" to load this file. \quit
index 9271ebd..4938663 100644 (file)
@@ -255,6 +255,10 @@ PG_FUNCTION_INFO_V1(pg_store_plans_xmlplan);
 #define COMPTAG_TYPE QueryCompletion
 #endif
 
+#if PG_VERSION_NUM < 140000
+#define ROLE_PG_READ_ALL_STATS         DEFAULT_ROLE_READ_ALL_STATS
+#endif
+
 static void pgsp_shmem_startup(void);
 static void pgsp_shmem_shutdown(int code, Datum arg);
 static void pgsp_ExecutorStart(QueryDesc *queryDesc, int eflags);
@@ -264,6 +268,9 @@ static void pgsp_ExecutorRun(QueryDesc *queryDesc,
 static void pgsp_ExecutorFinish(QueryDesc *queryDesc);
 static void pgsp_ExecutorEnd(QueryDesc *queryDesc);
 static void pgsp_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
+#if PG_VERSION_NUM >= 140000
+                                       bool readOnlyTree,
+#endif
                                        ProcessUtilityContext context, ParamListInfo params,
                                        QueryEnvironment *queryEnv,
                                        DestReceiver *dest, COMPTAG_TYPE *completionTag);
@@ -710,7 +717,11 @@ pgsp_ExecutorStart(QueryDesc *queryDesc, int eflags)
                MemoryContext oldcxt;
 
                oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
-               queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL);
+               queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL
+#if PG_VERSION_NUM >= 140000
+                                                                                 , false
+#endif
+                                                                                );
                MemoryContextSwitchTo(oldcxt);
        }
        
@@ -826,16 +837,25 @@ pgsp_ExecutorEnd(QueryDesc *queryDesc)
  */
 static void
 pgsp_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
+#if PG_VERSION_NUM >= 140000
+                                       bool readOnlyTree,
+#endif
                                        ProcessUtilityContext context, ParamListInfo params,
                                        QueryEnvironment *queryEnv,
                                        DestReceiver *dest, COMPTAG_TYPE *completionTag)
 {
        if (prev_ProcessUtility)
                prev_ProcessUtility(pstmt, queryString,
+#if PG_VERSION_NUM >= 140000
+                                                       readOnlyTree,
+#endif
                                                        context, params, queryEnv,
                                                        dest, completionTag);
        else
                standard_ProcessUtility(pstmt, queryString,
+#if PG_VERSION_NUM >= 140000
+                                                               readOnlyTree,
+#endif
                                                                context, params, queryEnv,
                                                                dest, completionTag);
 }
@@ -1040,7 +1060,7 @@ pg_store_plans(PG_FUNCTION_ARGS)
        MemoryContext per_query_ctx;
        MemoryContext oldcontext;
        Oid                     userid = GetUserId();
-       bool            is_allowed_role = is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS);
+       bool            is_allowed_role = is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS);
        HASH_SEQ_STATUS hash_seq;
        StatEntry  *entry;
 
index 0563eb1..30d5ba7 100644 (file)
@@ -1,5 +1,5 @@
 # pg_store_plans extension
 comment = 'track plan statistics of all SQL statements executed'
-default_version = '1.5'
+default_version = '1.6'
 module_pathname = '$libdir/pg_store_plans'
 relocatable = true
index e2f8135..76346b4 100644 (file)
@@ -66,18 +66,46 @@ pgspExplainTriggers(ExplainState *es, QueryDesc *queryDesc)
        {
                ResultRelInfo *rInfo;
                bool            show_relname;
-               int                     numrels = queryDesc->estate->es_num_result_relations;
+#if PG_VERSION_NUM < 140000
+               int         numrels = queryDesc->estate->es_num_result_relations;
+               int         nr;
+#else
+               List       *resultrels;
+               List       *routerels;
+#endif
                List       *targrels = queryDesc->estate->es_trig_target_relations;
-               int                     nr;
                ListCell   *l;
+
+#if PG_VERSION_NUM >= 140000
+               resultrels = queryDesc->estate->es_opened_result_relations;
+               routerels = queryDesc->estate->es_tuple_routing_result_relations;
+               targrels = queryDesc->estate->es_trig_target_relations;
+#endif
                
                pgspExplainOpenGroup("Triggers", "Triggers", false, es);
-               
+
+#if PG_VERSION_NUM < 140000
                show_relname = (numrels > 1 || targrels != NIL);
                rInfo = queryDesc->estate->es_result_relations;
                for (nr = 0; nr < numrels; rInfo++, nr++)
+#else
+               show_relname = (list_length(resultrels) > 1 ||
+                                               routerels != NIL || targrels != NIL);
+               foreach(l, resultrels)
+               {
+                       rInfo = (ResultRelInfo *) lfirst(l);
+#endif
                        report_triggers(rInfo, show_relname, es);
-               
+#if PG_VERSION_NUM >= 140000
+               }
+
+               foreach(l, routerels)
+               {
+                       rInfo = (ResultRelInfo *) lfirst(l);
+                       report_triggers(rInfo, show_relname, es);
+               }
+#endif
+
                foreach(l, targrels)
                {
                        rInfo = (ResultRelInfo *) lfirst(l);