GithubHelp home page GithubHelp logo

ossc-db / pg_hint_plan Goto Github PK

View Code? Open in Web Editor NEW
673.0 30.0 100.0 2.23 MB

Extension adding support for optimizer hints in PostgreSQL

License: Other

Makefile 0.80% C 66.18% Shell 0.14% PLpgSQL 19.36% Perl 3.14% Lex 10.38%

pg_hint_plan's People

Contributors

anisimov-ds avatar cstarc avatar dependabot[bot] avatar felixge avatar fzhlib avatar hanada avatar horiguti avatar littlewucoding avatar masaofujii avatar metrohasegawa avatar michaelpq avatar mikecaat avatar rattrayalex avatar rjuju avatar sherlockcpp avatar tideri avatar xzilla avatar yamatattsu avatar yang-rong-0814 avatar za-arthur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pg_hint_plan's Issues

make installcheck: 5 of 14 tests failed.

Hi,

Thanks for creating pg_hint_plan.

Some tests are failing. I've attached the regression.diffs below.

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.2 LTS
Release:	20.04
Codename:	focal

$ psql --version
psql (PostgreSQL) 13.2 (Ubuntu 13.2-1.pgdg20.04+1)

$ make installcheck
/usr/lib/postgresql/13/lib/pgxs/src/makefiles/../../src/test/regress/pg_regress --inputdir=./ --bindir='/usr/lib/postgresql/13/bin'    --encoding=UTF8 --dbname=contrib_regression init base_plan pg_hint_plan ut-init ut-A ut-S ut-J ut-L ut-G ut-R ut-fdw ut-W ut-T ut-fini
(using postmaster on Unix socket, default port)
============== dropping database "contrib_regression" ==============
DROP DATABASE
============== creating database "contrib_regression" ==============
CREATE DATABASE
ALTER DATABASE
============== running regression test queries        ==============
test init                         ... FAILED      896 ms
test base_plan                    ... ok           12 ms
test pg_hint_plan                 ... FAILED     7937 ms
test ut-init                      ... FAILED      551 ms
test ut-A                         ... FAILED      328 ms
test ut-S                         ... FAILED      443 ms
test ut-J                         ... ok          288 ms
test ut-L                         ... ok          250 ms
test ut-G                         ... ok          157 ms
test ut-R                         ... ok         1622 ms
test ut-fdw                       ... ok           43 ms
test ut-W                         ... ok          224 ms
test ut-T                         ... ok           35 ms
test ut-fini                      ... ok           13 ms

=======================
5 of 14 tests failed.
=======================

$ cat regression.diffs
diff -U3 /home/joel/postgresql-extensions/pg_hint_plan/expected/init.out /home/joel/postgresql-extensions/pg_hint_plan/results/init.out
--- /home/joel/postgresql-extensions/pg_hint_plan/expected/init.out	2021-04-29 07:57:13.223086918 +0000
+++ /home/joel/postgresql-extensions/pg_hint_plan/results/init.out	2021-04-29 08:14:28.188557252 +0000
@@ -38,6 +38,7 @@
CREATE INDEX p2_val_idx_1 ON p2 USING hash (val);
CREATE INDEX p2_val_id_idx ON p2 (val, id);
CREATE INDEX p2_val_idx2 ON p2 (val COLLATE "ja_JP");
+ERROR:  collation "ja_JP" for encoding "UTF8" does not exist
CREATE INDEX p2_val_idx3 ON p2 (val varchar_ops);
CREATE INDEX p2_val_idx4 ON p2 (val DESC NULLS LAST);
CREATE INDEX p2_val_idx5 ON p2 (val NULLS FIRST);
diff -U3 /home/joel/postgresql-extensions/pg_hint_plan/expected/pg_hint_plan.out /home/joel/postgresql-extensions/pg_hint_plan/results/pg_hint_plan.out
--- /home/joel/postgresql-extensions/pg_hint_plan/expected/pg_hint_plan.out	2021-04-29 07:57:13.227087063 +0000
+++ /home/joel/postgresql-extensions/pg_hint_plan/results/pg_hint_plan.out	2021-04-29 08:14:36.328707456 +0000
@@ -7061,14 +7061,14 @@
/*+IndexScan(p2 p2_val_idx6)*/
EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)';
LOG:  available indexes for IndexScan(p2): p2_val_idx6
-LOG:  available indexes for IndexScan(p2_c1): p2_c1_val_idx7
-LOG:  available indexes for IndexScan(p2_c2): p2_c2_val_idx7
-LOG:  available indexes for IndexScan(p2_c3): p2_c3_val_idx7
-LOG:  available indexes for IndexScan(p2_c4): p2_c4_val_idx7
-LOG:  available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx7
-LOG:  available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx7
-LOG:  available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx7
-LOG:  available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx7
+LOG:  available indexes for IndexScan(p2_c1): p2_c1_val_idx6
+LOG:  available indexes for IndexScan(p2_c2): p2_c2_val_idx6
+LOG:  available indexes for IndexScan(p2_c3): p2_c3_val_idx6
+LOG:  available indexes for IndexScan(p2_c4): p2_c4_val_idx6
+LOG:  available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx6
+LOG:  available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx6
+LOG:  available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx6
+LOG:  available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx6
LOG:  pg_hint_plan:
used hint:
IndexScan(p2 p2_val_idx6)
@@ -7102,14 +7102,14 @@
/*+IndexScan(p2 p2_val_idx p2_val_idx6)*/
EXPLAIN (COSTS false) SELECT val FROM p2 WHERE val >= '50' AND val <= '51' AND p2.ctid = '(1,1)';
LOG:  available indexes for IndexScan(p2): p2_val_idx6 p2_val_idx
-LOG:  available indexes for IndexScan(p2_c1): p2_c1_val_idx7 p2_c1_val_idx
-LOG:  available indexes for IndexScan(p2_c2): p2_c2_val_idx7 p2_c2_val_idx
-LOG:  available indexes for IndexScan(p2_c3): p2_c3_val_idx7 p2_c3_val_idx
-LOG:  available indexes for IndexScan(p2_c4): p2_c4_val_idx7 p2_c4_val_idx
-LOG:  available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx7 p2_c1_c1_val_idx
-LOG:  available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx7 p2_c1_c2_val_idx
-LOG:  available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx7 p2_c3_c1_val_idx
-LOG:  available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx7 p2_c3_c2_val_idx
+LOG:  available indexes for IndexScan(p2_c1): p2_c1_val_idx6 p2_c1_val_idx
+LOG:  available indexes for IndexScan(p2_c2): p2_c2_val_idx6 p2_c2_val_idx
+LOG:  available indexes for IndexScan(p2_c3): p2_c3_val_idx6 p2_c3_val_idx
+LOG:  available indexes for IndexScan(p2_c4): p2_c4_val_idx6 p2_c4_val_idx
+LOG:  available indexes for IndexScan(p2_c1_c1): p2_c1_c1_val_idx6 p2_c1_c1_val_idx
+LOG:  available indexes for IndexScan(p2_c1_c2): p2_c1_c2_val_idx6 p2_c1_c2_val_idx
+LOG:  available indexes for IndexScan(p2_c3_c1): p2_c3_c1_val_idx6 p2_c3_c1_val_idx
+LOG:  available indexes for IndexScan(p2_c3_c2): p2_c3_c2_val_idx6 p2_c3_c2_val_idx
LOG:  pg_hint_plan:
used hint:
IndexScan(p2 p2_val_idx p2_val_idx6)
diff -U3 /home/joel/postgresql-extensions/pg_hint_plan/expected/ut-init.out /home/joel/postgresql-extensions/pg_hint_plan/results/ut-init.out
--- /home/joel/postgresql-extensions/pg_hint_plan/expected/ut-init.out	2021-04-29 07:57:13.247087791 +0000
+++ /home/joel/postgresql-extensions/pg_hint_plan/results/ut-init.out	2021-04-29 08:14:36.888717778 +0000
@@ -10,6 +10,7 @@
  NOLOGIN
  NOREPLICATION
  CONNECTION LIMIT 1;
+ERROR:  role "super_user" already exists
CREATE ROLE normal_user
  NOSUPERUSER
  NOCREATEDB
@@ -27,6 +28,7 @@
CREATE TABLE s2.t1 (LIKE s1.t1 INCLUDING ALL);
CREATE TABLE s1.p1 (LIKE s1.t1 INCLUDING ALL);
CREATE UNIQUE INDEX p1_parent ON s1.p1 USING btree (c4 COLLATE "ja_JP" varchar_ops ASC NULLS LAST, (c1 * 2 < 100)) WHERE c1 < 10;
+ERROR:  collation "ja_JP" for encoding "UTF8" does not exist
CREATE TABLE s1.p2 (LIKE s1.t1 INCLUDING ALL);
CREATE TABLE s1.p1c1 (LIKE s1.p1 INCLUDING ALL, CHECK (c1 <= 100)) INHERITS(s1.p1);
NOTICE:  merging column "c1" with inherited definition
diff -U3 /home/joel/postgresql-extensions/pg_hint_plan/expected/ut-A.out /home/joel/postgresql-extensions/pg_hint_plan/results/ut-A.out
--- /home/joel/postgresql-extensions/pg_hint_plan/expected/ut-A.out	2021-04-29 07:57:13.227087063 +0000
+++ /home/joel/postgresql-extensions/pg_hint_plan/results/ut-A.out	2021-04-29 08:14:37.224723968 +0000
@@ -3134,11 +3134,7 @@
----
-- No. A-11-5-1
SELECT pg_stat_statements_reset();
- pg_stat_statements_reset
---------------------------
-
-(1 row)
-
+ERROR:  pg_stat_statements must be loaded via shared_preload_libraries
SELECT * FROM s1.t1 WHERE t1.c1 = 1;
  c1 | c2 | c3 | c4
----+----+----+----
@@ -3176,12 +3172,7 @@
  JOIN pg_catalog.pg_database d
    ON (s.dbid = d.oid)
  ORDER BY 1;
-                query                 | calls
---------------------------------------+-------
- SELECT * FROM s1.t1 WHERE t1.c1 = $1 |     3
- SELECT pg_stat_statements_reset()    |     1
-(2 rows)
-
+ERROR:  pg_stat_statements must be loaded via shared_preload_libraries
----
---- No. A-12-1 reset of global variable of core at the error
---- No. A-12-2 reset of global variable of original at the error
diff -U3 /home/joel/postgresql-extensions/pg_hint_plan/expected/ut-S.out /home/joel/postgresql-extensions/pg_hint_plan/results/ut-S.out
--- /home/joel/postgresql-extensions/pg_hint_plan/expected/ut-S.out	2021-04-29 07:57:13.247087791 +0000
+++ /home/joel/postgresql-extensions/pg_hint_plan/results/ut-S.out	2021-04-29 08:14:37.676732297 +0000
@@ -5242,8 +5242,8 @@

\o results/ut-S.tmpout
/*+IndexScan(p1 p1_parent)*/ EXPLAIN SELECT c4 FROM s1.p1 WHERE c2 * 2 < 100 AND c1 < 10;
-LOG:  available indexes for IndexScan(p1): p1_parent
-LOG:  available indexes for IndexScan(p1c1): p1c1_c4_expr_idx
+LOG:  available indexes for IndexScan(p1):
+LOG:  available indexes for IndexScan(p1c1):
LOG:  pg_hint_plan:
used hint:
IndexScan(p1 p1_parent)
@@ -5255,11 +5255,11 @@
\! sql/maskout.sh results/ut-S.tmpout
  QUERY PLAN
----------------
- Append  (cost=xxx..xxx rows=4 width=xxx)
-   ->  Index Scan using p1_parent on p1 p1_1  (cost=xxx..xxx rows=1 width=xxx)
-         Filter: ((c2 * 2) < 100)
-   ->  Index Scan using p1c1_c4_expr_idx on p1c1 p1_2  (cost=xxx..xxx rows=3 width=xxx)
-         Filter: ((c2 * 2) < 100)
+ Append  (cost={inf}..{inf} rows=4 width=xxx)
+   ->  Seq Scan on p1 p1_1  (cost={inf}..{inf} rows=1 width=xxx)
+         Filter: ((c1 < 10) AND ((c2 * 2) < 100))
+   ->  Seq Scan on p1c1 p1_2  (cost={inf}..{inf} rows=3 width=xxx)
+         Filter: ((c1 < 10) AND ((c2 * 2) < 100))

-- No. S-3-10-4
\o results/ut-S.tmpout
@@ -6045,7 +6045,7 @@
/*+IndexScanRegexp(p1 p1.*i)*/
EXPLAIN (COSTS false) SELECT * FROM s1.p1 WHERE c1 = 1;
LOG:  available indexes for IndexScanRegexp(p1): p1_i2 p1_i
-LOG:  available indexes for IndexScanRegexp(p1c1): p1c1_i p1c1_c4_expr_idx
+LOG:  available indexes for IndexScanRegexp(p1c1): p1c1_i
LOG:  pg_hint_plan:
used hint:
IndexScanRegexp(p1 p1.*i)

Can not find "pg_hint_plan.bc" file during make install.

Hi,

I have a problem installing pg_hint_plan.
Can not find "pg_hint_plan.bc" file during make install.

The environment is as follows.
Environments
- OS : CentOS Linux release 7.5.1804 (Core)
- PostgreSQL : 11.1 version
- pg_hint_plan : REL11_1_3_2

Below is the work history.

postgres tmp > git clone https://github.com/ossc-db/pg_hint_plan.git
Cloning into 'pg_hint_plan'...
remote: Enumerating objects: 127, done.
remote: Counting objects: 100% (127/127), done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 3763 (delta 81), reused 76 (delta 52), pack-reused 3636
Receiving objects: 100% (3763/3763), 1.31 MiB | 731.00 KiB/s, done.
Resolving deltas: 100% (2762/2762), done.

postgres tmp > cd pg_hint_plan/
postgres pg_hint_plan > ls -l
total 256
-rw-r--r--. 1 postgres postgres 1593 Nov 24 02:10 COPYRIGHT
-rw-r--r--. 1 postgres postgres 1295 Nov 24 02:10 COPYRIGHT.postgresql
-rw-r--r--. 1 postgres postgres 1523 Nov 24 02:10 Makefile
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 SPECS
-rw-r--r--. 1 postgres postgres 39421 Nov 24 02:10 core.c
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 data
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 doc
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 expected
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 input
-rw-r--r--. 1 postgres postgres 12169 Nov 24 02:10 make_join_rel.c
-rw-r--r--. 1 postgres postgres 1504 Nov 24 02:10 normalize_query.h
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 output
-rw-r--r--. 1 postgres postgres 233 Nov 24 02:10 pg_hint_plan--1.3.0--1.3.1.sql
-rw-r--r--. 1 postgres postgres 545 Nov 24 02:10 pg_hint_plan--1.3.2.sql
-rw-r--r--. 1 postgres postgres 120688 Nov 24 02:10 pg_hint_plan.c
-rw-r--r--. 1 postgres postgres 104 Nov 24 02:10 pg_hint_plan.control
-rw-r--r--. 1 postgres postgres 24711 Nov 24 02:10 pg_stat_statements.c
drwxr-xr-x. 2 postgres postgres 4096 Nov 24 02:10 sql

postgres pg_hint_plan > git checkout -b REL11_1_3_2 REL11_1_3_2
Switched to a new branch 'REL11_1_3_2'

postgres pg_hint_plan > make CLANG=true -k install
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard - O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC -I. -I./ -I/usr/pgsql-11/include/server -I/usr/pgsql-11/include/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -c -o pg_hint_plan.o pg_hint_plan.c
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC -L/usr/pgsql-11/lib -Wl,--as-needed -L/usr/lib64/llvm5.0/lib -L/usr/lib64 -Wl,--as-needed -Wl,-rpath,'/usr/pgsql-11/lib',--enable-new-dtags -Wl,--build-id -shared -o pg_hint_plan.so pg_hint_plan.o
true -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -O2 -I. -I./ -I/usr/pgsql-11/include/server -I/usr/pgsql-11/include/internal -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include -flto=thin -emit-llvm -c -o pg_hint_plan.bc pg_hint_plan.c
/usr/bin/mkdir -p '/usr/pgsql-11/share/extension'
/usr/bin/mkdir -p '/usr/pgsql-11/share/extension'
/usr/bin/mkdir -p '/usr/pgsql-11/lib'
/usr/bin/install -c -m 644 .//pg_hint_plan.control '/usr/pgsql-11/share/extension/'
/usr/bin/install -c -m 644 .//pg_hint_plan--1.3.2.sql '/usr/pgsql-11/share/extension/'
/usr/bin/install -c -m 755 pg_hint_plan.so '/usr/pgsql-11/lib/'
/usr/bin/mkdir -p '/usr/pgsql-11/lib/bitcode/pg_hint_plan'
/usr/bin/mkdir -p '/usr/pgsql-11/lib/bitcode'/pg_hint_plan/
/usr/bin/install -c -m 644 pg_hint_plan.bc '/usr/pgsql-11/lib/bitcode'/pg_hint_plan/./
/usr/bin/install: cannot stat 'pg_hint_plan.bc': No such file or directory
make: *** [install] Error 1

Please let me know.

Thank you & best regards,

Could not load library pg_hint_plan (undefined symbol: RINFO_IS_PUSHED_DOWN)

Hi,

On PG10 branch (commit 3cb8d0b), there's a warning at compile time:

core.c:1481:3: warning: implicit declaration of function 'RINFO_IS_PUSHED_DOWN' [-Wimplicit-function-declaration]
   if (only_pushed_down && !RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids))
   ^

It causes an error when pg_hint_plan is loaded:

postgres=# LOAD 'pg_hint_plan';
ERROR:  could not load library "/opt/intelerad/postgres10.3/lib64/pg_hint_plan.so": /opt/intelerad/postgres10.3/lib64/pg_hint_plan.so: undefined symbol: RINFO_IS_PUSHED_DOWN

It looks that the macro RINFO_IS_PUSHED_DOWN is used in core.c file but doesn't exist in pg10 .h files (only exists in pg11).
The bug has been introduced with the commit 375fdd2.

Platform information:
OS Version : CENTOS 7
Posgresql version : 10.3
pg_hint_plan version : PG10 (3cb8d0b)

Failed while running ut-W.sql regression test

Hi.

When I was doing regression tests for pg_hint_planREL96_1_2_4, one case failed.

Platform information:
OS Version : RHEL 6.4
Posgresql version : 9.6.11
pg_hint_plan version : 96_1.2.4
Failure case : ut-W

In Posgresql-9.6.10, this case is passable. I guess this is a styling change caused by the upgrade of Posgresql . If so, in the Posgresql-9.6.11, does the expected log need to be updated?

Here is the testlog I actually tested.
ut-W.zip

Segmentation fault occurred in parallel query

Hi.

Segmentation faults occur in queries where parallel queries are used.
However, no issue will occur under the following conditions.
· disabled pg_hint_plan
(SET pg_hint_plan.enable_hint TO off;)
· disabled Parallel query
(max_parallel_workers_per_gather = 0 / max_parallel_workers = 0)
· Specify parallel execution method
(/ * + SeqScan (a) Parallel (a 1 soft) * /)

Segmentation fault will be reproduced by the following test.
Is this a bug?

=# SELECT version();
PostgreSQL 10.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18), 64-bit

=# \dx
Name | Version | Schema | Description
--------------+---------+------------+------------------------------
pg_hint_plan | 1.3.1 | hint_plan |

(test)
$ pgbench -i -s 10 testdb
$ LANG=C psql testdb
=# LOAD 'pg_hint_plan';
=# /*+ SeqScan(a) */ EXPLAIN (ANALYZE, BUFFERS) SELECT a.aid FROM pgbench_accounts AS a INNER JOIN pgbench_accounts AS b ON a.aid = b.aid ORDER BY a.aid;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.

(log)
LOG: server process (PID 1750) was terminated by signal 11: Segmentation fault
DETAIL: Failed process was running: /*+ SeqScan(a) */ EXPLAIN (ANALYZE, BUFFERS) SELECT a.aid FROM pgbench_accounts AS a INNER JOIN pgbench_accounts AS b ON a.aid = b.aid ORDER BY a.aid;
LOG: terminating any other active server processes
WARNING: terminating connection because of crash of another server process
DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT: In a moment you should be able to reconnect to the database and repeat your command.

(gdb) bt
#0 copyObjectImpl (from=0x3eb0c6f7a0b5ed8d) at copyfuncs.c:4679
#1 0x000000000067e95b in create_scan_plan (root=0x1277a38, best_path=0x1278c78, flags=) at createplan.c:567
#2 0x000000000067cadd in create_plan_recurse (root=0x1277a38, best_path=0x1278c78, flags=0) at createplan.c:378
#3 0x000000000067cb38 in create_mergejoin_plan (root=0x1277a38, best_path=0x12805b8, flags=1) at createplan.c:3787
#4 create_join_plan (root=0x1277a38, best_path=0x12805b8, flags=1) at createplan.c:953
#5 create_plan_recurse (root=0x1277a38, best_path=0x12805b8, flags=1) at createplan.c:383
#6 0x0000000000680685 in create_gather_merge_plan (root=0x1277a38, best_path=0x12804b8) at createplan.c:1504
#7 0x000000000067c816 in create_plan_recurse (root=0x1277a38, best_path=0x12804b8, flags=1) at createplan.c:488
#8 0x000000000067da19 in create_plan (root=0x1277a38, best_path=) at createplan.c:315
#9 0x000000000068a2cb in standard_planner (parse=0x1275a28, cursorOptions=256, boundParams=) at planner.c:341
#10 0x00007f916dc05508 in pg_hint_plan_planner (parse=0x1275a28, cursorOptions=256, boundParams=0x0) at pg_hint_plan.c:3035
#11 0x00000000007245fa in pg_plan_query (querytree=, cursorOptions=, boundParams=) at postgres.c:796
#12 0x00000000005990b7 in ExplainOneQuery (query=0x1275a28, cursorOptions=, into=0x0, es=0x11c96d8,
queryString=0x1225528 "/*+ SeqScan(a) / EXPLAIN (ANALYZE, BUFFERS) SELECT a.aid FROM pgbench_accounts AS a INNER JOIN pgbench_accounts AS b ON a.aid = b.aid ORDER BY a.aid;",
params=0x0, queryEnv=0x0) at explain.c:367
#13 0x000000000059933d in ExplainQuery (pstate=0x11c9538, stmt=0x1226a78,
queryString=0x1225528 "/
+ SeqScan(a) / EXPLAIN (ANALYZE, BUFFERS) SELECT a.aid FROM pgbench_accounts AS a INNER JOIN pgbench_accounts AS b ON a.aid = b.aid ORDER BY a.aid;",
params=0x0, queryEnv=0x0, dest=0x11c9648) at explain.c:256
#14 0x000000000072b12d in standard_ProcessUtility (pstmt=0x1227060,
queryString=0x1225528 "/
+ SeqScan(a) / EXPLAIN (ANALYZE, BUFFERS) SELECT a.aid FROM pgbench_accounts AS a INNER JOIN pgbench_accounts AS b ON a.aid = b.aid ORDER BY a.aid;",
context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0x11c9648, completionTag=0x7fff48ab3ab0 "") at utility.c:680
#15 0x000000000072705b in PortalRunUtility (portal=0x125ccc8, pstmt=0x1227060, isTopLevel=, setHoldSnapshot=, dest=0x11c9648,
completionTag=) at pquery.c:1178
#16 0x000000000072826a in FillPortalStore (portal=0x125ccc8, isTopLevel=1 '\001') at pquery.c:1038
#17 0x0000000000728758 in PortalRun (portal=0x125ccc8, count=9223372036854775807, isTopLevel=1 '\001', run_once=1 '\001', dest=0x1227410, altdest=0x1227410,
completionTag=0x7fff48ab3cd0 "") at pquery.c:768
#18 0x0000000000724c81 in exec_simple_query (
query_string=0x1225528 "/
+ SeqScan(a) */ EXPLAIN (ANALYZE, BUFFERS) SELECT a.aid FROM pgbench_accounts AS a INNER JOIN pgbench_accounts AS b ON a.aid = b.aid ORDER BY a.aid;")
at postgres.c:1099
#19 0x0000000000725c39 in PostgresMain (argc=, argv=, dbname=0x11a3cd8 "testdb", username=) at postgres.c:4088
#20 0x00000000006b9aca in BackendRun (argc=, argv=) at postmaster.c:4405
#21 BackendStartup (argc=, argv=) at postmaster.c:4077
#22 ServerLoop (argc=, argv=) at postmaster.c:1755
#23 PostmasterMain (argc=, argv=) at postmaster.c:1363
#24 0x000000000063a130 in main (argc=1, argv=0x11a1ba0) at main.c:228

Invalid read error

I've get an "Invalid read of size 8" error while running regression tests manually under valgrind. The problem is around walking indexes list in restrict_indexes. I think, in this case it would be correct to use foreach(cell, rel->indexlist) instead of for (cell = list_head(rel->indexlist); cell; cell = next).

The same problem is in transform_join_hints function.

Here is the log:

==00:00:00:00.000 1162045== Memcheck, a memory error detector
==00:00:00:00.000 1162045== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==00:00:00:00.000 1162045== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==00:00:00:00.000 1162045== Command: /home/andrew/pgpro/build/pg13vg/bin/postgres --log_line_prefix=%m\ %p\  --log_statement=all --shared_buffers=64MB -D 1
==00:00:00:00.000 1162045== Parent PID: 1092243
==00:00:00:00.000 1162045== 
==00:00:00:00.955 1162046== 
==00:00:00:00.955 1162046== HEAP SUMMARY:
==00:00:00:00.955 1162046==     in use at exit: 293,482 bytes in 157 blocks
==00:00:00:00.955 1162046==   total heap usage: 944 allocs, 195 frees, 1,351,933 bytes allocated
==00:00:00:00.955 1162046== 
==00:00:00:00.955 1162046== For a detailed leak analysis, rerun with: --leak-check=full
==00:00:00:00.955 1162046== 
==00:00:00:00.955 1162046== For lists of detected and suppressed errors, rerun with: -s
==00:00:00:00.955 1162046== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==00:00:02:50.414 1162215== 
==00:00:02:50.414 1162215== HEAP SUMMARY:
==00:00:02:50.414 1162215==     in use at exit: 1,869,432 bytes in 380 blocks
==00:00:02:50.414 1162215==   total heap usage: 14,157 allocs, 955 frees, 42,353,409 bytes allocated
==00:00:02:50.414 1162215== 
==00:00:02:50.414 1162215== For a detailed leak analysis, rerun with: --leak-check=full
==00:00:02:50.414 1162215== 
==00:00:02:50.414 1162215== For lists of detected and suppressed errors, rerun with: -s
==00:00:02:50.414 1162215== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 7)
==00:00:03:44.965 1162214== VALGRINDERROR-BEGIN
==00:00:03:44.965 1162214== Invalid read of size 8
==00:00:03:44.965 1162214==    at 0xB3AD8C2: restrict_indexes (pg_hint_plan.c:3458)
==00:00:03:44.965 1162214==    by 0xB3AE145: setup_hint_enforcement (pg_hint_plan.c:3948)
==00:00:03:44.965 1162214==    by 0xB3AE69B: pg_hint_plan_set_rel_pathlist (pg_hint_plan.c:4758)
==00:00:03:44.965 1162214==    by 0x3F1A1D: set_rel_pathlist (allpaths.c:540)
==00:00:03:44.965 1162214==    by 0x3F1B57: set_base_rel_pathlists (allpaths.c:352)
==00:00:03:44.965 1162214==    by 0x3F2168: make_one_rel (allpaths.c:222)
==00:00:03:44.965 1162214==    by 0x4136AB: query_planner (planmain.c:269)
==00:00:03:44.965 1162214==    by 0x41965B: grouping_planner (planner.c:2058)
==00:00:03:44.965 1162214==    by 0x41B1F7: subquery_planner (planner.c:1015)
==00:00:03:44.965 1162214==    by 0x41B790: standard_planner (planner.c:405)
==00:00:03:44.965 1162214==    by 0xB3AD08E: pg_hint_plan_planner (pg_hint_plan.c:3176)
==00:00:03:44.965 1162214==    by 0x41BB82: planner (planner.c:273)
==00:00:03:44.965 1162214==  Address 0xa0d57c8 is 7,336 bytes inside a recently re-allocated block of size 8,192 alloc'd
==00:00:03:44.965 1162214==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==00:00:03:44.965 1162214==    by 0x60CC5E: AllocSetAlloc (aset.c:919)
==00:00:03:44.965 1162214==    by 0x613E1C: palloc (mcxt.c:963)
==00:00:03:44.965 1162214==    by 0x631A14: initStringInfo (stringinfo.c:63)
==00:00:03:44.965 1162214==    by 0xB3A81D1: parse_quoted_value (pg_hint_plan.c:1456)
==00:00:03:44.965 1162214==    by 0xB3A8490: parse_parentheses (pg_hint_plan.c:1629)
==00:00:03:44.965 1162214==    by 0xB3AC945: ScanMethodHintParse (pg_hint_plan.c:2102)
==00:00:03:44.965 1162214==    by 0xB3ABC92: parse_hints (pg_hint_plan.c:1681)
==00:00:03:44.965 1162214==    by 0xB3ABE4A: create_hintstate (pg_hint_plan.c:2022)
==00:00:03:44.965 1162214==    by 0xB3ACE0D: pg_hint_plan_planner (pg_hint_plan.c:3112)
==00:00:03:44.965 1162214==    by 0x41BB82: planner (planner.c:273)
==00:00:03:44.965 1162214==    by 0x4D3ED4: pg_plan_query (postgres.c:875)
==00:00:03:44.965 1162214== 
==00:00:03:44.965 1162214== VALGRINDERROR-END

Segmentation fault in PL/pgSQL and ROLLBACK to SAVEPOINT.

Hi,

Segmentation fault occurs when I rollback to savepoint in transaction block.

The simple way to reproduce:

create or replace function err_func() returns text language plpgsql as $$
begin
  insert into invalid_table values (1);
  return 'failed';
end;
$$;

begin;
savepoint a;
select err_func();
rollback to a;
select 1;
rollback;

Stack trace:

(gdb) bt
#0  0x00007f1309106bbc in pg_hint_plan_planner () from /home/egashira/usr/local/pgsql/lib/pg_hint_plan.so
#1  0x00000000006fe0cc in pg_plan_query ()
#2  0x00000000006fe1ae in pg_plan_queries ()
#3  0x00000000006fe62a in exec_simple_query ()
#4  0x00000000006ff7ac in PostgresMain ()
#5  0x0000000000476141 in ServerLoop ()
#6  0x0000000000699ec9 in PostmasterMain ()
#7  0x0000000000476b51 in main ()

My environment is pg_hint_plan 1.3.3 with PostgreSQL 10.7.
I found with PostgreSQL 10.4, too.

I found this bug in executing PostgreSQL's regression test by make installcheck on the database with pg_hint_plan enabled.
Because of #41's issue, I removed "plancache" test from PostgreSQL's testset. Then, this bug was occurred in plpgsql test.
-> https://github.com/postgres/postgres/blob/REL_10_7/src/test/regress/sql/plpgsql.sql#L3854

This bug seems to be introduced by commit c9864a4 .
( This bug did not happen in pg_hint_plan 1.3.2 )

core.c in .gitignore

Hello,
Why core.c file is in the .gitignore? As far as I understand core.c is not generated automatically.

Join order incorrect when using join method and leading hints

I have turned geqo off and increased from_collapse_limit and join_collapse_limit to appropriate values. I am attempting to plan the following:

/*+                                                                                                                                                             
  HashJoin(ct t chn cn ci mc rt)                                                                                                                                
  HashJoin(t chn cn ci mc rt)                                                                                                                                   
  HashJoin(chn cn ci mc rt)                                                                                                                                     
  HashJoin(cn ci mc rt)                                                                                                                                         
  HashJoin(ci mc rt)                                                                                                                                            
  HashJoin(ci mc)                                                                                                                                                                                                                                                                                          
  Leading((ct (t (chn (cn ((ci mc) rt))))))                                                                                                                     
 */ explain SELECT MIN(chn.name) AS character,                                                                                                     
       MIN(t.title) AS movie_with_american_producer                                                                                                             
FROM char_name AS chn,                                                                                                                                          
     cast_info AS ci,                                                                                                                                           
     company_name AS cn,                                                                                                                                        
     company_type AS ct,                                                                                                                                        
     movie_companies AS mc,                                                                                                                                     
     role_type AS rt,                                                                                                                                           
     title AS t                                                                                                                                                 
WHERE ci.note LIKE '%(producer)%'                                                                                                                               
  AND cn.country_code = '[us]'                                                                                                                                  
  AND t.production_year > 1990                                                                                                                                  
  AND t.id = mc.movie_id                                                                                                                                        
  AND t.id = ci.movie_id                                                                                                                                        
  AND ci.movie_id = mc.movie_id                                                                                                                                 
  AND chn.id = ci.person_role_id                                                                                                                                
  AND rt.id = ci.role_id                                                                                                                                        
  AND cn.id = mc.company_id                                                                                                                                     
  AND ct.id = mc.company_type_id;

However, pg_hint_plan claims that all hints are used but the returned QEP does not follow the join order specified above.

2020-10-18 07:37:20.852 UTC [12379] LOG:  pg_hint_plan[qno=0xb]: HintStateDump: {used hints:HashJoin(ci mc)HashJoin(ci mc rt)HashJoin(ci cn mc rt)HashJoin(chn ci cn mc rt)HashJoin(chn ci cn mc rt t)HashJoin(chn ci cn ct mc rt t)Leading((ct (t (chn (cn ((ci mc) rt))))))}, {not used hints:(none)}, {duplicate hints:(none)}, {error hints:(none)}

Resulting execution plan (which very clearly does not follow the join order specified by Leading):

 Aggregate  (cost=10078338320.71..10078338321.21 rows=1 width=64)
   ->  Hash Join  (cost=10077494801.71..10078097989.21 rows=961326 width=33)
         Hash Cond: (ct.id = mc.company_type_id)
         ->  Seq Scan on company_type ct  (cost=0.00..3.00 rows=4 width=4)
         ->  Hash  (cost=10076893972.96..10076893972.96 rows=961326 width=37)
               ->  Gather  (cost=10071476776.84..10076893972.96 rows=961326 width=37)
                     Workers Planned: 4
                     ->  Parallel Hash Join  (cost=10071475776.84..10072086342.96 rows=240332 width=37)
                           Hash Cond: (t.id = mc.movie_id)
                           ->  Parallel Seq Scan on title t  (cost=0.00..431062.38 rows=435273 width=21)
                                 Filter: (production_year > 1990)
                           ->  Parallel Hash  (cost=10070962528.09..10070962528.09 rows=821198 width=28)
                                 ->  Nested Loop  (cost=10005677650.40..10070962528.09 rows=821198 width=28)
                                       ->  Parallel Hash Join  (cost=5677628.90..52478321.67 rows=821198 width=16)
                                             Hash Cond: (cn.id = mc.company_id)
                                             ->  Parallel Seq Scan on company_name cn  (cost=0.00..89390.96 rows=49663 width=4)
                                                   Filter: ((country_code)::text = '[us]'::text)
                                             ->  Parallel Hash  (cost=5272860.78..5272860.78 rows=647629 width=20)
                                                   ->  Hash Join  (cost=965666.13..5272860.78 rows=647629 width=20)
                                                         Hash Cond: (ci.role_id = rt.id)
                                                         ->  Parallel Hash Join  (cost=965651.63..5157824.72 rows=647629 width=24)
                                                               Hash Cond: (ci.movie_id = mc.movie_id)
                                                               ->  Parallel Seq Scan on cast_info ci  (cost=0.00..4028332.83 rows=237535 width=12)
                                                                     Filter: (note ~~ '%(producer)%'::text)
                                                               ->  Parallel Hash  (cost=439617.26..439617.26 rows=841655 width=12)
                                                                     ->  Parallel Seq Scan on movie_companies mc  (cost=0.00..439617.26 rows=841655 width=12
)
                                                         ->  Hash  (cost=7.00..7.00 rows=12 width=4)
                                                               ->  Seq Scan on role_type rt  (cost=0.00..7.00 rows=12 width=4)
                                       ->  Index Scan using char_name_pkey on char_name chn  (cost=21.50..22.51 rows=1 width=20)
                                             Index Cond: (id = ci.person_role_id)
(30 rows)

Official support for PostgreSQL 14?

The current release of pg_hint_plan is 1.3.7 that supports up to PostgreSQL 13. I see a couple of new commits 2 weeks ago that update the version to 1.4 with the support for PostgreSQL 14.

May I ask if there is a target date when version 1.4 will be released officially?

Thank you.

Segfault when use Set, Rows and Parallel hints together

Hi, when trying to execute following SQL statement:

/*+Set(enable_nestloop on)
Rows(t1 t2 +10)
Parallel(t1 8 hard)
*/
EXPLAIN SELECT * FROM t1 JOIN t2 ON (t1.id = t2.id);

I got the segmentation fault in log file.
Without one of this hints (Set, Rows or Parallel) statement completed correctly.

The default value of pg_hint_plan.message_level is not same with document

Hello, when I print the default value of pg_hint_plan.message_level, I found it is not same with the value on document.
The value on document is "INFO", but it prints "LOG".

The information on document:
Parameter name: pg_hint_plan.message_level
discription: Specifies message level of debug print. Valid values are error, warning, notice, info, log, debug.
Default: INFO

Execute log:

postgres=# load 'pg_hint_plan';
LOAD
postgres=# create extension pg_hint_plan;
CREATE EXTENSION
postgres=# select name, setting from pg_settings where name = 'pg_hint_plan.message_level';
            name            | setting
----------------------------+---------
 pg_hint_plan.message_level | log
(1 row)

postgres=#

[BUG]When using the plugin on PostgreSQL 10.6, I found that some operations will cause the database to crash

PostgreSQL: 10.6
pg_hint_plan: 1.3.1
When I use indexscan(a a.index_name), an error occurs in the database:
2021-11-02 17:38:46.079 CST,,,3954,,61810386.f72,3,,2021-11-02 17:23:18 CST,,0,LOG,00000,"received fast shutdown request",,,,,,,,,""
2021-11-02 17:38:46.083 CST,,,3954,,61810386.f72,4,,2021-11-02 17:23:18 CST,,0,LOG,00000,"aborting any active transactions",,,,,,,,,""
2021-11-02 17:38:46.083 CST,"postgres","test",5683,"10.251.134.63:55876",618103bc.1633,4,"idle",2021-11-02 17:24:12 CST,3/0,0,FATAL,57P01,"terminating connection due
to administrator command",,,,,,,,,"DBeaver 21.1.4 - SQLEditor <Script-5.sql>"
2021-11-02 17:38:46.084 CST,"postgres","test",5685,"10.251.134.63:55877",618103bc.1635,3,"idle",2021-11-02 17:24:12 CST,4/0,0,FATAL,57P01,"terminating connection due
to administrator command",,,,,,,,,"DBeaver 21.1.4 - Metadata "
2021-11-02 17:38:46.086 CST,,,3954,,61810386.f72,5,,2021-11-02 17:23:18 CST,,0,LOG,00000,"worker process: logical replication launcher (PID 3982) exited with exit cod
e 1",,,,,,,,,""
2021-11-02 17:38:46.089 CST,,,3977,,61810386.f89,1,,2021-11-02 17:23:18 CST,,0,LOG,00000,"shutting down",,,,,,,,,""
2021-11-02 17:38:46.212 CST,,,3954,,61810386.f72,6,,2021-11-02 17:23:18 CST,,0,LOG,00000,"database system is shut down",,,,,,,,,""

In addition, when I use indexscan(A INDEX_NAME), it is invalid.It seems to be case sensitive.

Segmentation fault occured with multi statements query

Hello,

A segmentation fault occurs if enable_hint_table = on and a "multi-statement" query is used with some constants.

Sample steps to reproduce:

LOAD 'pg_hint_plan';
create extension pg_hint_plan;
set  pg_hint_plan.enable_hint_table = on;
\;\;SELECT 1,2;

> server closed the connection unexpectedly

It happens:

The segmentation fault occurs in the function generate_normalized_query (file pg_stat_statements.c) with the code :
memcpy(norm_query + n_quer_loc, query + quer_loc, len_to_wrt);
because len_to_wrt is negative.

According to the commit in pg_stat_statements extension, it looks like the query parameter should be changed according to the new parameter query_loc, but pg_hint_plan.c always calls this function with the same query string.

the hint for joining order function was invalid on queries with more than 11 tables

Hello,

When I experimented with the join order benchmark using pg_hint_plan, I found that the hint for joining order function was invalid on queries with more than 11 tables.

These queries include (29c 29b 29a 33c 33b 33a 28c 28b 28a 30c 30b 30a 27c 27b 27a 26c 26b 26a 24b 24a ).

For instance, when I used the following hint command for 33a, there was no change in the query plan.

 /*+  Leading(  ((((((kt ((it (((it1 ((lt ml) mi_idx1)) mc1) cn1)) t)) mc) cn) t1) kt1) mi_idx) )  */
 explain ...

/*+  Leading(  ((((((kt ((it (((it1 ((ml lt) mi_idx1)) mc1) cn1)) t)) mc) cn) t1) kt1) mi_idx) )  */
 explain ...

/*+  Leading(  (((((( (( (((it1 ((ml lt) mi_idx1)it) mc1) cn1)kt) t)) mc) cn) t1) kt1) mi_idx) )  */
 explain ...

But for the query of <=11 tables, the result is in line with expectations.

Is this feature limited to the number of tables? Or is there any problem with the method I am using?

My experimental environment is as follows:
PostgreSQL 10.7
Ubuntu 16.04
pg_hint_plan--1.3.3 Download from this link (https://ja.osdn.net/projects/pghintplan/scm/git/pg_hint_plan/tree/PG10/)

I wonder if you can give me some advice. Thank you~!

windows build using MSYS

Hi,
I would like to use this extension on windows 7 64
I'm able to build postgres from tarball using doc :
https://wiki.postgresql.org/wiki/Building_With_MinGW#Build_from_a_tarball

But I get errrors when trying to build pg_hint_plan with

me@mycomputer MSYS ~/postgresql-11devel/contrib/pg_hint_plan
$ make
x86_64-w64-mingw32-gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -I. -I. -I../../src/include -I./src/include/port/win32 -DEXEC_BACKEND "-I../../src/include/port/win32" -c -o pg_hint_plan.o pg_hint_plan.c
windres -i win32ver.rc -o win32ver.o --include-dir=../../src/include --include-dir=.
x86_64-w64-mingw32-gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -shared -static-libgcc -o pg_hint_plan.dll pg_hint_plan.o win32ver.o -L../../src/port -L../../src/common -Wl,--allow-multiple-definition -Wl,--disable-auto-import -Wl,--as-needed -lm -L../../src/backend -lpostgres -lpgcommon -lpgport -lz -lws2_32 -lm -lws2_32 -Wl,--export-all-symbols -Wl,--out-implib=libpg_hint_plan.a
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.geqo_threshold[.refptr.geqo_threshold]+0x0): undefined reference to geqo_threshold' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_geqo[.refptr.enable_geqo]+0x0): undefined reference to enable_geqo'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.max_parallel_workers_per_gather[.refptr.max_parallel_workers_per_gather]+0x0): undefined reference to max_parallel_workers_per_gather' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.min_parallel_index_scan_size[.refptr.min_parallel_index_scan_size]+0x0): undefined reference to min_parallel_index_scan_size'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.min_parallel_table_scan_size[.refptr.min_parallel_table_scan_size]+0x0): undefined reference to min_parallel_table_scan_size' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_hashjoin[.refptr.enable_hashjoin]+0x0): undefined reference to enable_hashjoin'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_mergejoin[.refptr.enable_mergejoin]+0x0): undefined reference to enable_mergejoin' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_nestloop[.refptr.enable_nestloop]+0x0): undefined reference to enable_nestloop'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_indexonlyscan[.refptr.enable_indexonlyscan]+0x0): undefined reference to enable_indexonlyscan' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_tidscan[.refptr.enable_tidscan]+0x0): undefined reference to enable_tidscan'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_bitmapscan[.refptr.enable_bitmapscan]+0x0): undefined reference to enable_bitmapscan' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_indexscan[.refptr.enable_indexscan]+0x0): undefined reference to enable_indexscan'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.enable_seqscan[.refptr.enable_seqscan]+0x0): undefined reference to enable_seqscan' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.disable_cost[.refptr.disable_cost]+0x0): undefined reference to disable_cost'
pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.max_worker_processes[.refptr.max_worker_processes]+0x0): undefined reference to max_worker_processes' pg_hint_plan.o:pg_hint_plan.c:(.rdata$.refptr.application_name[.refptr.application_name]+0x0): undefined reference to application_name'
collect2.exe: error: ld returned 1 exit status
../../src/Makefile.shlib:372 : la recette pour la cible « pg_hint_plan.dll » a échouée
make: *** [pg_hint_plan.dll] Erreur 1

Any Idea ?
Thanks in advance
Regards
PAscal

Hint not working for Prepare Statement

I am trying to use pg_hint_plan to get hint for my dynamic queries prepared using Prepare statements , but hint does not work.

I have attached the test case for ECPG for which pg_hint_plan fails to provide hint.
From the log it seems the sequence in which it parses the query and execute the query gets jumbled up.

I have attached the log and Source code with my logging for same , for debugging purpose I had added logging in functions "pg_hint_plan_post_parse_analyze" and "pg_hint_plan_planner".

It seems that while executing pg_hint_plan_planner the hint gets overwritten with next statement's hint string.

test_douteki_01.pgc.txt

hint_plan.log

pg_hint_plan.c.txt

The Variable "DATA" in the Makefile can't be work with install.pl in PostgresSQL source code

PostgreSQL verison: 12.3
pg_hint_plan version: REL12_1_3_7

I'm going to build the PostgreSQL project from source code,And I put the pg_hint_plan in the contrib folder before building.
Then I got two problem.
The first is in the pg_hint_plan.c line 54:
#include "plpgsql.h
the Head file plpgsql.h can't be import correctly,
I modified it to this below, then it works.
#include "../../src/pl/plpgsql/src/plpgsql.h",

The second problem is when run the install.bat, and it will get and error:

Could not copy contrib/pg_hint_plan/pg_hint_plan--*.sql to E:\Projects\PSQL\pgsql\/share/extension/pg_hint_plan--*.sql at E:\Projects\PSQL\postgresql-12.3\src\tools\msvc/Install.pm line 40. Install::lcopy("contrib/pg_hint_plan/pg_hint_plan--*.sql", "E:\\Projects\\PSQL\\pgsql\\/share/extension/pg_hint_plan--*.sql") called at E:\Projects\PSQL\postgresql-12.3\src\tools\msvc/Install.pm line 498 Install::CopySubdirFiles("contrib", "pg_hint_plan", HASH(0x2951f50), "E:\\Projects\\PSQL\\pgsql\\") called at E:\Projects\PSQL\postgresql-12.3\src\tools\msvc/Install.pm line 444 Install::CopyContribFiles(HASH(0x2951f50), "E:\\Projects\\PSQL\\pgsql\\") called at E:\Projects\PSQL\postgresql-12.3\src\tools\msvc/Install.pm line 115 Install::Install("E:\\Projects\\PSQL\\pgsql\\", undef) called at install.pl line 30
In the Makefile The "DATA" is in this line:
DATA = pg_hint_plan--*.sql
The reason is the install.pm treat it as a filename.
i just fixed it like this:
DATA = pg_hint_plan--1.3.5--1.3.6.sql pg_hint_plan--1.3.6--1.3.7.sql pg_hint_plan--1.3.7.sql

Cardinality feedback

Hello,

Thanks for this very usefull feature in Postgresql !
I'm an old Oracle DBA, and I like it very much ;o)

Question regarding wrong estimates and Oracle Cardinality Feedback
as discussed in https://www.postgresql.org/message-id/flat/1510775864811-0.post%40n3.nabble.com#[email protected]

do you think that it would be possible to write an extension like auto_explain (or other)
that would be able to catch wrong estimates / real data fetched at the end (success, error, cancel) of each query and add a row in hint_plan.hints table with the proper Hint for row number correction ?

This hint in hint_plan.hints would be available for next executions.
Regards
PAscal

Problem in using pg_hint_plan.parse_messages

Hi,

Currently our customer uses PostgreSQL 9.5 and pg_hint_plan 1.1.3 and hits problem in using pg_hint_plan.parse_messages parameter.

In pg_hint_plan.html and pg_hint_plan-ja.html, two parameters pg_hint_plan.parse_messages and pg_hint_plan.message_level are written as follows.

pg_hint_plan 1.1.3 (for Postgres 9.5):
pg_hint_plan.html: only pg_hint_plan.message_level is written.
pg_hint_plan-ja.html: only pg_hint_plan.parse_messages is written.

pg_hint_plan 1.2.3 and 1.3.1 (for Postgres 9.6 and 10):
both two parameters are written.

However, these two parameters are assigned to the same variable (parse_messages_level_options) as follows.

pg_hint_plan.c

     DefineCustomEnumVariable("pg_hint_plan.parse_messages",
                                                      "Message level of parse errors.",
                                                      NULL,
                                                      &pg_hint_plan_message_level,
                                                      INFO,
                                                      parse_messages_level_options,
                                                      PGC_USERSET,
                                                      0,
                                                      NULL,
                                                      NULL,
                                                      NULL);

     DefineCustomEnumVariable("pg_hint_plan.message_level",
                                                      "Message level of debug messages.",
                                                      NULL,
                                                      &pg_hint_plan_message_level,
                                                      INFO,
                                                      parse_messages_level_options,
                                                      PGC_USERSET,
                                                      0,
                                                      NULL,
                                                      NULL,
                                                      NULL);

Since two parameters are assigned to the same variable, pg_hint_plan.parse_messages is overwritten with pg_hint_plan.message_level when starting PostgreSQL. When my customer writes "pg_hint_plan.parse_messages = 'warning'" and does not write pg_hint_plan.message_level and starts PostgreSQL, both two parameters are shown as 'info' (default value of pg_hint_plan.message_level).

Therefore, I propose to remove pg_hint_plan.parse_messages from pg_hint_plan.html and pg_hint_plan-ja.html.

Regards,
Ryohei Takahashi

Error compiling on Solaris

Hi

When I compiled on Solaris, I encountered a compilation error.
Platform information:
OS Version : Solaris10
pg_hint_plan version : 96_1.2.4

The error message is as follows:
···· -Wl,--build-id -G -o pg_hint_plan.so pg_hint_plan.o
ld: error: unrecognized option '--'
ld: error: use the -z help option for usage information
gmake: *** [pg_hint_plan.so] Error 2

After consulting the relevant information, we found that Solaris does not currently seem to support the following options in the Makefile.

LDFLAGS+=-Wl,--build-id

If so, the following code seems to avoid this problem

ifeq ($(shell uname), SunOS)
else
LDFLAGS+=-Wl,--build-id
endif

Incorrect join order when using join method hints

Hi, I am using 1.3.7 version downloaded from releases for PostgreSQL 13.1.
I also set the parameters join_collapse_limit=25; from_collapse_limit=25; geqo_threshold = 25; work_mem = "2000MB";

When I run explain of the following query:

/*+
Leading((rt (it ((n (chn (mc (mi (t (ci an)))))) cn))))
HashJoin(ci an)
NestLoop(t ci an)
NestLoop(mi t ci an)
NestLoop(ci an mi t mc)
NestLoop(ci chn an mi t mc)
NestLoop(ci chn n mi t an mc)
NestLoop(ci chn cn n mi t an mc)
NestLoop(mi an it ci chn n cn t mc)
NestLoop(rt mi it ci chn n an cn t mc)
*/
SELECT   MIN(n.name) AS voicing_actress,
       MIN(t.title) AS jap_engl_voiced_movie
 FROM  aka_name AS an,
     char_name AS chn,
     cast_info AS ci,
     company_name AS cn,
     info_type AS it,
     movie_companies AS mc,
     movie_info AS mi,
     name AS n,
     role_type AS rt,
     title AS t
WHERE ci.note IN ('(voice)',
                  '(voice: Japanese version)',
                  '(voice) (uncredited)',
                  '(voice: English version)')
  AND cn.country_code ='[us]'
  AND it.info = 'release dates'
  AND mi.info IS NOT NULL
  AND (mi.info LIKE 'Japan:%200%'
       OR mi.info LIKE 'USA:%200%')
  AND n.gender ='f'
  AND n.name LIKE '%An%'
  AND rt.role ='actress'
  AND t.production_year > 2000
  AND t.id = mi.movie_id
  AND t.id = mc.movie_id
  AND t.id = ci.movie_id
  AND mc.movie_id = ci.movie_id
  AND mc.movie_id = mi.movie_id
  AND mi.movie_id = ci.movie_id
  AND cn.id = mc.company_id
  AND it.id = mi.info_type_id
  AND n.id = ci.person_id
  AND rt.id = ci.role_id
  AND n.id = an.person_id
  AND ci.person_id = an.person_id
  AND chn.id = ci.person_role_id;

I get the following:

Aggregate  (cost=35459384571.50..35459384571.51 rows=1 width=64)
  ->  Nested Loop  (cost=30000031677.62..35459384571.49 rows=2 width=32)
        Join Filter: (ci.role_id = rt.id)
        ->  Seq Scan on role_type rt  (cost=0.00..1.15 rows=1 width=4)
              Filter: ((role)::text = 'actress'::text)
        ->  Nested Loop  (cost=30000031677.62..35459384570.08 rows=21 width=36)
              Join Filter: (mi.info_type_id = it.id)
              ->  Seq Scan on info_type it  (cost=0.00..2.41 rows=1 width=4)
                    Filter: ((info)::text = 'release dates'::text)
              ->  Nested Loop  (cost=30000031677.62..35459384537.91 rows=2380 width=40)
                    ->  Nested Loop  (cost=30000031677.20..35459376985.73 rows=6487 width=44)
                          Join Filter: (ci.person_id = n.id)
                          ->  Seq Scan on name n  (cost=0.00..118123.77 rows=28675 width=19)
                                Filter: (((name)::text ~~ '%An%'::text) AND ((gender)::text = 'f'::text))
                          ->  Materialize  (cost=30000031677.20..35053766466.68 rows=942737 width=37)
                                ->  Nested Loop  (cost=30000031677.20..35053761752.99 rows=942737 width=37)
                                      ->  Nested Loop  (cost=20000031676.77..25053296164.95 rows=176294 width=45)
                                            ->  Nested Loop  (cost=10000031676.34..15052975508.48 rows=360864 width=49)
                                                  Join Filter: (t.id = mi.movie_id)
                                                  ->  Index Scan using info_type_id_movie_info on movie_info mi  (cost=0.43..7142663.77 rows=308977 width=8)
                                                        Filter: ((info IS NOT NULL) AND (((info)::text ~~ 'Japan:%200%'::text) OR ((info)::text ~~ 'USA:%200%'::text)))
                                                  ->  Materialize  (cost=10000031675.91..10003632177.12 rows=1087935 width=41)
                                                        ->  Nested Loop  (cost=10000031675.91..10003626737.45 rows=1087935 width=41)
                                                              ->  Hash Join  (cost=31675.47..851969.06 rows=1982120 width=20)
                                                                    Hash Cond: (ci.person_id = an.person_id)
                                                                    ->  Seq Scan on cast_info ci  (cost=0.00..796166.82 rows=861114 width=16)
                                                                          Filter: ((note)::text = ANY ('{(voice),"(voice: Japanese version)","(voice) (uncredited)","(voice: English version)"}'::text[]))
                                                                    ->  Hash  (cost=20409.10..20409.10 rows=901310 width=4)
                                                                          ->  Seq Scan on aka_name an  (cost=0.00..20409.10 rows=901310 width=4)
                                                              ->  Index Scan using title_pkey on title t  (cost=0.43..1.40 rows=1 width=21)
                                                                    Index Cond: (id = ci.movie_id)
                                                                    Filter: (production_year > 2000)
                                            ->  Index Only Scan using char_name_pkey on char_name chn  (cost=0.43..0.89 rows=1 width=4)
                                                  Index Cond: (id = ci.person_role_id)
                                      ->  Index Scan using movie_id_movie_companies on movie_companies mc  (cost=0.43..2.59 rows=5 width=8)
                                            Index Cond: (movie_id = t.id)
                    ->  Index Scan using company_name_pkey on company_name cn  (cost=0.42..1.16 rows=1 width=4)
                          Index Cond: (id = mc.company_id)
                          Filter: ((country_code)::text = '[us]'::text)

First chn is joined, and then mc. But it should be in the opposite order.
By the way if I remove join method hints and use only Leading the order became exactly what was specified.
Am I doing everything right? Thank you!

Could not control access plan on REL95_1_1_8 in one use case

Hi,

I found the bug on REL95_1_1_8.
I tried to force MergeJoin, but I could not control access plan in special use case.

Platform information:
OS Version : RHEL 7.4
PostgreSQL version : 9.5.16
pg_hint_plan version : REL95_1_1_8

How to reproduce

Initial setup as follows:

CREATE EXTENSION pg_hint_plan;
CREATE EXTENSION pg_dbms_stats;
CREATE SCHEMA S1;
CREATE TABLE S1.T1(C1 int);
CREATE TABLE S1.T2(C1 int);
CREATE UNIQUE INDEX ix1T1 ON S1.T1(C1);
CREATE UNIQUE INDEX ix1T2 ON S1.T2(C1);
INSERT INTO S1.T1(C1) SELECT generate_series(1,10);
INSERT INTO S1.T2(C1) SELECT generate_series(1,10);
ANALYZE;

After this, execute "psql -f test.sql". test.sql has following SQLs:

EXPLAIN SELECT T1.C1,T2.C1 FROM S1.T1,S1.T2 WHERE T1.C1=T2.C1;
ANALYZE;
SELECT dbms_stats.lock_table_stats('s1.t1');
EXPLAIN SELECT /*+ MergeJoin(t1 t2) */ T1.C1,T2.C1 FROM S1.T1,S1.T2 WHERE T1.C1=T2.C1;
SELECT dbms_stats.unlock_table_stats('s1.t1');

Even if MergeJoin is specified in hint clause, HashJoin is selected.

Note:
As far as I saw, this problem occurs only when I use "psql -f xxx".
This problem does not occur if I execute SQLs interactively on psql terminal.

Investigation

After adding this commit to REL95_1_1_8, this problem is solved.
The commit log shows "9.5 is not affected", but I think this should be back-patch to 9.5 too.

Regards,
Daisuke Higuchi

hint string "MergeJoin" Invalid in some cases

Hello

When I use pg_hint_plan and pg_dbms_stat together, hint String (/* + MergeJoin (t1 t2)*/) did not work in the following situations.

Create tables T1 and T2 and insert data into them:
CREATE TABLE t1
( C1 integer ,
C2 integer ,
C3 integer ,
C4 integer ,
C5 integer ,
C6 integer ,
C7 integer ,
C8 integer ,
C9 integer ,
C10 integer);

CREATE TABLE t2
( C1 integer ,
C2 integer ,
C3 integer ,
C4 integer ,
C5 integer ,
C6 integer ,
C7 integer ,
C8 integer ,
C9 integer ,
C10 integer);

INSERT INTO t1(C1,C2,C3,C4,C5,C6,C7,C8,C9,C10)
SELECT generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20);

INSERT INTO t2(C1,C2,C3,C4,C5,C6,C7,C8,C9,C10)
SELECT generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20),
generate_series(1,20);

Then execute the following SQL:
explain SELECT /*+ MergeJoin(t1 t2) */ T1.C1,T2.C1 FROM T1,T2 WHERE T1.C1=T2.C1;

results:
QUERY PLAN

Hash Join (cost=1.45..2.92 rows=20 width=8)
Hash Cond: (t1.c1 = t2.c1)
-> Seq Scan on t1 (cost=0.00..1.20 rows=20 width=4)
-> Hash (cost=1.20..1.20 rows=20 width=4)
-> Seq Scan on t2 (cost=0.00..1.20 rows=20 width=4)
(5 rows)

I added "MergeJoin" hint string in sql, but it didn't work.This worked in the REL95_1_1_7 .I've been investigating for a long time, but I haven't found out why.

Memory not freed in time when debug_print is set to verbose

Hi
I found some Memory not freed in time when debug_print is set to verbose
in function restrict_indexes()

when debug_level > 0 , buf malloc 1024 bytes

	if (debug_level > 0)
		initStringInfo(&buf);

at the end of restrict_indexes() , buf.data is freed only if debug_level = 1.
I think buf.data is not freed in time when debug_level is 2 or 3.
[ps. After my check, is does not cause memleak]

	if (debug_level == 1)
	{
		initStringInfo(&rel_buf);
                ...
		pfree(buf.data);
		pfree(rel_buf.data);
	}

I think a new if branch can be create to free buf.data, like the following;

	if (debug_level == 1)
	{
		initStringInfo(&rel_buf);
                ...
		pfree(rel_buf.data);
	}

	if (debug_level > 0)
		pfree(buf.data);

found two same condition can be Merge

Dear Developers.

I am currently learning pg_hint_plan, and I found two same condition in function pg_hint_plan_planner()which can be merge.

	if (!current_hint_str)
		get_current_hint_string(NULL, parse);

	/* No hint, go the normal way */
	if (!current_hint_str)
		goto standard_planner_proc;

May be it looks better like the following

	if (!current_hint_str)
	{
		get_current_hint_string(NULL, parse);

                /* No hint, go the normal way */
		if(!current_hint_str)
			goto standard_planner_proc;
	}

Need to check for invalidated plan and if so, set target_query = NULL

target_query = (Query *) linitial (entry->plansource->query_list);

At line 1873, where:
p = entry->plansource->query_string;
target_query = (Query *) linitial (entry->plansource->query_list);

the query could have been invalidated. In this case, the target_query should be set to NULL, as in:

        /* If the plan was just invalidated then the query_list will be NULL                                                                                                                                                                     
         */                                                                                                                                                                                                                                      
        if (NULL == entry->plansource->query_list)                                                                                                                                                                                                            
        {                                                                                                                                                                                                                                        
            target_query = NULL;                                                                                                                                                                                                                 
        }                                                                                                                                                                                                                                        
        else                                                                                                                                                                                                                                     
        {                                                                                                                                                                                                                                        
            target_query = (Query *) linitial (entry->plansource->query_list);                                                                                                                                                                                
        }  

if this is not done, then bb installcheck serial will fail on the plancache test.

best regards,

/Jim Finnerty

Wrong join order and final plan output when a specific hint is given

Hello all,

I am using the TPC-H Benchmark and I am trying to specify a query plan for the query template number 3. More specifically, the query with the hints provided is the following:

/*+SeqScan(customer) 
    SeqScan(orders) 
    SeqScan(lineitem) 
    NestLoop(orders lineitem) 
    NestLoop(orders lineitem customer)
    Leading ((customer (lineitem orders)))*/

EXPLAIN  SELECT l_orderkey, sum(l_extendedprice * (1 - l_discount)) as revenue, o_orderdate, o_shippriority
FROM
  customer,
  orders,
  lineitem
WHERE
  c_mktsegment = 'BUILDING'
  and c_custkey = o_custkey
  and l_orderkey = o_orderkey
  and o_orderdate < date '1995-03-13'
  and l_shipdate > date '1995-03-13'
GROUP BY
  l_orderkey,
  o_orderdate,
  o_shippriority
  order by
  revenue desc,
  o_orderdate;

As seen from the hints block I want to force two Nested Loops with the pair lineitem and orders is executed first. The problem is that the output of the of above hints is:

Sort  (cost=29746039187.49..29746039976.89 rows=315760 width=48)
   Sort Key: (sum((lineitem.l_extendedprice * ('1'::numeric - lineitem.l_discount)))) DESC, orders.o_orderdate
   ->  GroupAggregate  (cost=29745991156.43..29746000629.23 rows=315760 width=48)
         Group Key: lineitem.l_orderkey, orders.o_orderdate, orders.o_shippriority
         ->  Sort  (cost=29745991156.43..29745991945.83 rows=315760 width=28)
               Sort Key: lineitem.l_orderkey, orders.o_orderdate, orders.o_shippriority
               ->  Nested Loop  (cost=20000000000.00..29745954757.67 rows=315760 width=28)
                     Join Filter: (orders.o_orderkey = lineitem.l_orderkey)
                     ->  Seq Scan on lineitem  (cost=0.00..196558.01 rows=3248676 width=20)
                           Filter: (l_shipdate > '1995-03-13'::date)
                     ->  Materialize  (cost=10000000000.00..10328091202.85 rows=145795 width=12)
                           ->  Nested Loop  (cost=10000000000.00..10328089761.88 rows=145795 width=12)
                                 Join Filter: (customer.c_custkey = orders.o_custkey)
                                 ->  Seq Scan on orders  (cost=0.00..46375.00 rows=725346 width=20)
                                       Filter: (o_orderdate < '1995-03-13'::date)
                                 ->  Materialize  (cost=0.00..5733.75 rows=30150 width=4)
                                       ->  Seq Scan on customer  (cost=0.00..5583.00 rows=30150 width=4)
                                             Filter: (c_mktsegment = 'BUILDING'::bpchar)

The above output is wrong based on the given hints. If I specify a different join operator on the orders join pair the produced plan is correct. Generally, the hint NestLoop(orders lineitem) results a wrong plan. Also removing the specific hint the output seems to be correct. Is this a bug or am I using the hints in a wrong way?

Thank you very much in advance.

System crash on Row(<empty string>)

I could get a system crash on PostgreSQL v9.6 + pg_hint_plan 1.2.5 (for PGv9.6)
when I told the hint-clause below.

/*+
 Row()
 */

It is fundamentally a syntax error, so I expect it shall be ignored or aborted by error.
I guess something like list or cstring are not handled correctly in this corner case.

segfaults appear related to pg_hint_plan

Hi

Firstly, as a recovering Oracle DBA thanks for this extension! We get occasional segfaults on a database we can't reproduce (we tried!), but the backtrace on the core file suggests it may be pg_hint_plan:

Core was generated by `postgres: batch_user_account'.
Program terminated with signal 11, Segmentation fault.
#0 0x000000386712868a in __strcmp_sse42 () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install postgresql96-server-9.6.5-1PGDG.rhel6.x86_64
(gdb) bt
#0 0x000000386712868a in __strcmp_sse42 () from /lib64/libc.so.6
#1 0x00007fa3f0c7074c in get_query_string (pstate=, query=, jumblequery=) at pg_hint_plan.c:1882
#2 0x00007fa3f0c70a5d in pg_hint_plan_post_parse_analyze (pstate=0x25324b8, query=0x25325e8) at pg_hint_plan.c:2875
#3 0x00000000005203bc in parse_analyze ()
#4 0x00000000006df933 in pg_analyze_and_rewrite ()
#5 0x00000000007c6f6b in ?? ()
#6 0x00000000007c6ff0 in CachedPlanGetTargetList ()
#7 0x00000000006e173a in PostgresMain ()
#8 0x00000000006812f5 in PostmasterMain ()
#9 0x0000000000609278 in main ().

We are using version 1.2.2 on Postgres 9.6.5 on RHEL 6.9. We get this segfault on one particular prod database with moderate load (200+ different sql statements, total of a few hundred executes per second) after applying DDL to the database. The DDL is usually a 'grant usage on schema APP ... ' statement unrelated to the user segfaulting. Maybe just the cache invalidation triggers something. We aren't actually using any hints in this database, we have the extension installed in case we need it later. We don't even know for certain if this is pg_hint_plan causing the segfault, just looks like it from the backtrace. We have another version 1.2.0 on Postgres 9.6.5 on RHEL 6.9 database with pg_hint_plan and no segfaults so it is an odd problem. Glad for any thoughts.

thanks, Blair

pg_hint_plan build issue with PostgreSQL-10.8

I was trying to build pg_hint_plan with latest PostgreSQL-10.8 on centos-6 and 7 it fails. Please find the error detail below

core.c:1402:1: error: static declaration of 'is_dummy_rel' follows non-static declaration
 is_dummy_rel(RelOptInfo *rel)
 ^
In file included from pg_hint_plan.c:20:0:
PostgreSQL-inst-dir/10.8/include/server/nodes/relation.h:1195:13: note: previous declaration of 'is_dummy_rel' was here
 extern bool is_dummy_rel(RelOptInfo *rel);

parallel and indexscan must be used together for parallel index scan

it seems Parallel() must be given with IndexScan() to let PostgreSQL use parallel index scan.
not sure if it's true though feel it's right by reading the source code
and if actually it is so then it should be on the manual or somewhere obvious.

version: pg10, 1.3.*

ex.
/*+ IndexScan(tb idx_tb) */

  • when the planner chose to use parallel query, just giving IndexScan() hint doesn't make it use index scan
  • if the planner doesn't chose to use parallel, there is no problem. it uses index scan.

/*+ Parallel(tb 2 hard) IndexScan(tb idx_tb) */

  • giving Parallel() hint together make it actually use index scan
  • OR should give Parallel(tb 0 hard) to make sure it accidentally chose parallel and uses seq scan.

Installation of pg_hint_plan failed

Installation of pg_hint_plan failed

Environment

  • Operating System: CentOS 7.5
  • PostgreSQL version:PostgreSQL 11.x
  • pg_hint_plan version: REL11_1_3_6

When I execute the make command in the pg_hint_plan-REL11_1_3_6 directory, the following error appears:

gcc -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -DLINUX_OOM_SCORE_ADJ=0 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -fPIC -I. -I. -I/usr/include/pgsql/server -I/usr/include/pgsql/internal -D_GNU_SOURCE -I/usr/include/libxml2 -c -o pg_hint_plan.o pg_hint_plan.c
pg_hint_plan.c:34:37: fatal error: partitioning/partbounds.h: No such file or directory
#include "partitioning/partbounds.h"
^
compilation terminated.
make: *** [pg_hint_plan.o] Error 1
[root@r1-coremap-kftest-vm-3 pg_hint_plan-REL11_1_3_5]# pwd
/usr/local/pg-hint-plan/pg_hint_plan-REL11_1_3_5

where to place hint in procedure

hi there, I'd like to report interesting find during my work.

I have tested pg_hint_plan 1.3.5 version on PG 11.7

the part that I have tested is using hint inside of the procedure.

few times I have tried and noticed that hint is not working on insert statement unless

I place the hint after "INSERT INTO "

select statements seems working fine if hint is placed before "SELECT"

I'll update this post when I have time to test more later.

Errors in log when pg_hint_plan is loaded as shared_preload_libraries

Hi, to Load pg_hint_plan user has to have superuser privileges so I decided to load libraries during postmaster startup but when I did this there a lot of Error was showed in log.

2019-11-28 08:48:56 CET [378337]: [1-1] db=mydatabase,user=user2,app=pgAdmin 4 - DB:mydatabase,client=192.168.1.1 WARNING:  terminating connection because of crash of another server process
2019-11-28 08:48:56 CET [378337]: [2-1] db=mydatabase,user=user2,app=pgAdmin 4 - DB:mydatabase,client=192.168.1.1 DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2019-11-28 08:48:56 CET [378337]: [3-1] db=mydatabase,user=user2,app=pgAdmin 4 - DB:mydatabase,client=192.168.1.1 HINT:  In a moment you should be able to reconnect to the database and repeat your command.
2019-11-28 08:48:56 CET [284325]: [1-1] db=,user=,app=,client= WARNING:  terminating connection because of crash of another server process
2019-11-28 08:48:56 CET [284325]: [2-1] db=,user=,app=,client= DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
2019-11-28 08:48:56 CET [284325]: [3-1] db=,user=,app=,client= HINT:  In a moment you should be able to reconnect to the database and repeat your command.
2019-11-28 08:48:56 CET [270120]: [17-1] db=,user=,app=,client= LOG:  all server processes terminated; reinitializing
2019-11-28 08:48:58 CET [412756]: [1-1] db=,user=,app=,client= LOG:  database system was interrupted; last known up at 2019-11-28 08:46:13 CET
2019-11-28 08:48:58 CET [412774]: [1-1] db=mydatabase,user=user2,app=[unknown],client=192.168.1.1 FATAL:  the database system is in recovery mode
2019-11-28 08:48:59 CET [412756]: [2-1] db=,user=,app=,client= LOG:  database system was not properly shut down; automatic recovery in progress
2019-11-28 08:48:59 CET [412756]: [3-1] db=,user=,app=,client= LOG:  redo starts at 392A/B253D988

Is it possible to operate inside pg_hint_plan function?

Dear Developers.

I am currently using a version of Postgresql 11.2 in CentoOS 7.4
pg_hint_plan is version 1.3.4.

Create a function as shown below.
######################################################################
CREATE OR REPLACE FUNCTION test_fnc_2()
returns table (bid int, bbalance int, filler bpchar, aid int, a_bid int, abalance int, a_filler bpchar)
language sql as $$
/*+
seqscan (a)
seqscan (b)
*/
select
b.bid , b.bbalance , b.filler , a.aid , a.bid, a.abalance , a.filler
FROM pgbench_branches b
JOIN pgbench_accounts a ON b.bid = a.bid
ORDER BY a.aid;
$$;
#######################################################################
I use auto_explan to see the result of executing the function, pg_hint_plan does not work.

Normal operation is possible when executed with sql instead of a function.

Can I get a description and documentation of the issue?

SIGSEGV while running plancache.sql regression test

Hello,

I was running plancache.sql regression test and I met SIGSEGV.
(PG10 branch with PostgreSQL 10.3)

Program received signal SIGSEGV, Segmentation fault.
get_query_string (pstate=pstate@entry=0x207fca0, query=query@entry=0x207fdb8,
    jumblequery=jumblequery@entry=0x0) at pg_hint_plan.c:1867

The CachedPlanSource in the fetched PreparedStatement was revalidated. Its is_valid was false and query_list was NIL.

You can reproduce it by running following statements.

CREATE TABLE INT8_TBL(q1 int8, q2 int8);


CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl;

-- create and use a cached plan
PREPARE prepstmt AS SELECT * FROM pcachetest;

EXECUTE prepstmt;

-- invalidate the plans and see what happens
DROP TABLE pcachetest;

EXECUTE prepstmt;

-- recreate the temp table (this demonstrates that the raw plan is
-- purely textual and doesn't depend on OIDs, for instance)
CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2;


EXECUTE prepstmt;

unable to update extension

Hi,
In a797bcf , It seems line break leads to syntax error when updating extension.

/* pg_hint_plan/pg_hint_plan--1.3.6--1.3.7.sql */

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION pg_dbms_stats UPDATE TO '1.3.7'" to load this file.
\quit
postgres=# CREATE EXTENSION pg_hint_plan VERSION "1.3.6";
CREATE EXTENSION
postgres=# ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.7";
ERROR:  syntax error at or near "\"
postgres=# \dx pg_hint_plan 
           List of installed extensions
     Name     | Version |  Schema   | Description 
--------------+---------+-----------+-------------
 pg_hint_plan | 1.3.6   | hint_plan | 
(1 row)

By editing complain back to one line made work as normal

/* pg_hint_plan/pg_hint_plan--1.3.6--1.3.7.sql */

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION pg_dbms_stats UPDATE TO '1.3.7'" to load this file. \quit
postgres=# ALTER EXTENSION pg_hint_plan UPDATE TO "1.3.7";
ALTER EXTENSION
postgres=# \dx pg_hint_plan 
           List of installed extensions
     Name     | Version |  Schema   | Description 
--------------+---------+-----------+-------------
 pg_hint_plan | 1.3.7   | hint_plan | 
(1 row)

Null pointer causes service to crash

How to reproduce

1、add the follow parameter to postgresql.conf
session_preload_libraries = 'pg_hint_plan'

2、Execute the following statement
create table int8_tbl(q1 bigint, q2 bigint);
insert into int8_tbl values(123, 456), (4567890123456789, 4567890123456789);
CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl;
PREPARE prepstmt AS SELECT * FROM pcachetest;
EXECUTE prepstmt;
PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1;
EXECUTE prepstmt2(123);
DROP TABLE pcachetest;
EXECUTE prepstmt;
CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2;
EXECUTE prepstmt;

3、after execute the last statement ,the server crash
REGRESSION=# EXECUTE prepstmt;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
!>

4、Crash stack
Program received signal SIGSEGV, Segmentation fault.
0x00007f7b5751e3a2 in get_query_string (pstate=0x27d62a8, query=0x27d63b8, jumblequery=0x0) at pg_hint_plan.c:1886
warning: Source file is more recent than executable.
1886 p = NULL;
(gdb) bt
#0 0x00007f7b5751e3a2 in get_query_string (pstate=0x27d62a8, query=0x27d63b8, jumblequery=0x0) at pg_hint_plan.c:1886
#1 0x00007f7b575208f5 in get_current_hint_string (pstate=0x27d62a8, query=0x27d63b8) at pg_hint_plan.c:2902
#2 0x00007f7b57520baf in pg_hint_plan_post_parse_analyze (pstate=0x27d62a8, query=0x27d63b8) at pg_hint_plan.c:2953
#3 0x000000000058fae0 in parse_analyze (parseTree=0x27d61c8, sourceText=0x27d5770 "EXECUTE prepstmt;", paramTypes=0x0, numParams=0, queryEnv=0x0) at analyze.c:124
#4 0x000000000089239d in pg_analyze_and_rewrite (parsetree=0x27d61c8, query_string=0x27d5770 "EXECUTE prepstmt;", paramTypes=0x0, numParams=0, queryEnv=0x0) at postgres.c:694
#5 0x0000000000893587 in exec_simple_query (query_string=0x27d5770 "EXECUTE prepstmt;") at postgres.c:1120
#6 0x00000000008978eb in PostgresMain (argc=1, argv=0x275e268, dbname=0x275e178 "postgres", username=0x275e158 "postgres") at postgres.c:4271
#7 0x0000000000801efe in BackendRun (port=0x2756150) at postmaster.c:4405
#8 0x0000000000801692 in BackendStartup (port=0x2756150) at postmaster.c:4077
#9 0x00000000007fdea6 in ServerLoop () at postmaster.c:1749
#10 0x00000000007fd694 in PostmasterMain (argc=1, argv=0x272af70) at postmaster.c:1399
#11 0x000000000073196a in main (argc=1, argv=0x272af70) at main.c:232

Issues that change to parallel execution plan when using hints

The default value of the parallel_tuple_cost parameter is 0.1. The value of the parallel_tuple_cost variable of pg_hint_plan is changed from 0.1 to 0 because it is of type int. This is why the execution plan changes in parallel when using pg_hint_plan.

Add hints_inside_query feature

There are ORMs (namely, 1C solutions with more than 100 thousand installations) which don't allow to put a comment at the start of the query. But we need to use pg_hint_plan. Therefore, there is a proposal to add an feature that allows you to insert hint at an arbitrary place in the query, for example, in string constants.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.