OSDN Git Service

テーブルが1つの場合は、常にget_relation_info()でスキャン方式を
authorMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Fri, 6 Jul 2012 05:39:25 +0000 (14:39 +0900)
committerMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Fri, 6 Jul 2012 05:39:25 +0000 (14:39 +0900)
制御するように変更した。
その他、リファクタリング。

expected/pg_hint_plan.out
pg_hint_plan.c
sql/pg_hint_plan.sql

index 7109385..74df80f 100644 (file)
@@ -1001,3 +1001,1791 @@ error hint:
          Index Cond: (id = $1)
 (16 rows)
 
+-- full scan hint pattern test
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+            QUERY PLAN             
+-----------------------------------
+ Tid Scan on t1
+   TID Cond: (ctid = '(1,1)'::tid)
+   Filter: (id < 10)
+(3 rows)
+
+/*+SeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+                   QUERY PLAN                    
+-------------------------------------------------
+ Seq Scan on t1
+   Filter: ((id < 10) AND (ctid = '(1,1)'::tid))
+(2 rows)
+
+/*+IndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+           QUERY PLAN            
+---------------------------------
+ Index Scan using t1_pkey on t1
+   Index Cond: (id < 10)
+   Filter: (ctid = '(1,1)'::tid)
+(3 rows)
+
+/*+BitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+             QUERY PLAN             
+------------------------------------
+ Bitmap Heap Scan on t1
+   Recheck Cond: (id < 10)
+   Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Index Scan on t1_pkey
+         Index Cond: (id < 10)
+(5 rows)
+
+/*+TidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+            QUERY PLAN             
+-----------------------------------
+ Tid Scan on t1
+   TID Cond: (ctid = '(1,1)'::tid)
+   Filter: (id < 10)
+(3 rows)
+
+/*+NoSeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+            QUERY PLAN             
+-----------------------------------
+ Tid Scan on t1
+   TID Cond: (ctid = '(1,1)'::tid)
+   Filter: (id < 10)
+(3 rows)
+
+/*+NoIndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+            QUERY PLAN             
+-----------------------------------
+ Tid Scan on t1
+   TID Cond: (ctid = '(1,1)'::tid)
+   Filter: (id < 10)
+(3 rows)
+
+/*+NoBitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+            QUERY PLAN             
+-----------------------------------
+ Tid Scan on t1
+   TID Cond: (ctid = '(1,1)'::tid)
+   Filter: (id < 10)
+(3 rows)
+
+/*+NoTidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+           QUERY PLAN            
+---------------------------------
+ Index Scan using t1_pkey on t1
+   Index Cond: (id < 10)
+   Filter: (ctid = '(1,1)'::tid)
+(3 rows)
+
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+SeqScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+SeqScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+SeqScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Index Scan using t2_pkey on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Index Scan using t1_pkey on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+IndexScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+IndexScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+IndexScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+BitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+BitmapScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Index Scan using t2_pkey on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Index Scan using t2_pkey on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+BitmapScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+BitmapScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t1
+         Recheck Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t1_pkey
+               Index Cond: (id = t2.id)
+(8 rows)
+
+/*+TidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+TidScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+TidScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+TidScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+NoSeqScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoSeqScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoSeqScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+NoIndexScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoIndexScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoIndexScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+NoBitmapScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   Join Filter: (t1.id = t2.id)
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoBitmapScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoBitmapScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t1
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t2_pkey on t2
+         Index Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+SeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+IndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Index Scan using t2_pkey on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+BitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+                QUERY PLAN                
+------------------------------------------
+ Nested Loop
+   ->  Seq Scan on t1
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Bitmap Heap Scan on t2
+         Recheck Cond: (id = t1.id)
+         Filter: (ctid = '(1,1)'::tid)
+         ->  Bitmap Index Scan on t2_pkey
+               Index Cond: (id = t1.id)
+(8 rows)
+
+/*+NoTidScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+TidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+NoSeqScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+NoIndexScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+NoBitmapScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+               QUERY PLAN                
+-----------------------------------------
+ Nested Loop
+   ->  Tid Scan on t2
+         TID Cond: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
+/*+NoTidScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+LOG:  pg_hint_plan:
+used hint:
+NoTidScan(t1)
+NoTidScan(t2)
+not used hint:
+duplication hint:
+error hint:
+
+              QUERY PLAN               
+---------------------------------------
+ Nested Loop
+   ->  Seq Scan on t2
+         Filter: (ctid = '(1,1)'::tid)
+   ->  Index Scan using t1_pkey on t1
+         Index Cond: (id = t2.id)
+         Filter: (ctid = '(1,1)'::tid)
+(6 rows)
+
index 0f71af3..d9b0218 100644 (file)
@@ -174,6 +174,7 @@ struct PlanHint
        int                             njoin_hints;            /* # of valid join hints */
        int                             max_join_hints;         /* # of slots for join hints */
        JoinMethodHint **join_hints;            /* parsed join hints */
+       int                             init_join_mask;         /* initial value join parameter */
 
        int                             nlevel;                         /* # of relations to be joined */
        List              **join_hint_level;
@@ -482,13 +483,14 @@ PlanHintCreate(void)
 
        hint = palloc(sizeof(PlanHint));
        hint->hint_str = NULL;
-       hint->init_scan_mask = 0;
        hint->nscan_hints = 0;
        hint->max_scan_hints = 0;
        hint->scan_hints = NULL;
+       hint->init_scan_mask = 0;
        hint->njoin_hints = 0;
        hint->max_join_hints = 0;
        hint->join_hints = NULL;
+       hint->init_join_mask = 0;
        hint->nlevel = 0;
        hint->join_hint_level = NULL;
        hint->nleading_hints = 0;
@@ -1439,30 +1441,12 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
        if (enable_indexonlyscan)
                global->init_scan_mask |= ENABLE_INDEXONLYSCAN;
 #endif
-
-       /*
-        * TODO ビュー定義で指定したテーブル数が1つの場合にもこのタイミングでGUCを変更する必
-        * 要がある。
-        */
-       if (list_length(parse->rtable) == 1 &&
-               ((RangeTblEntry *) linitial(parse->rtable))->rtekind == RTE_RELATION)
-       {
-               int     i;
-               RangeTblEntry  *rte = linitial(parse->rtable);
-               
-               for (i = 0; i < global->nscan_hints; i++)
-               {
-                       ScanMethodHint *hint = global->scan_hints[i];
-
-                       if (!hint_state_enabled(hint))
-                               continue;
-
-                       if (RelnameCmp(&rte->eref->aliasname, &hint->relname) != 0)
-                               parse_ereport(hint->base.hint_str, ("Relation \"%s\" does not exist.", hint->relname));
-
-                       set_scan_config_options(hint->enforce_mask, global->context);
-               }
-       }
+       if (enable_nestloop)
+               global->init_join_mask |= ENABLE_NESTLOOP;
+       if (enable_mergejoin)
+               global->init_join_mask |= ENABLE_MERGEJOIN;
+       if (enable_hashjoin)
+               global->init_join_mask |= ENABLE_HASHJOIN;
 
        if (prev_planner_hook)
                result = (*prev_planner_hook) (parse, cursorOptions, boundParams);
@@ -1495,10 +1479,23 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
  * aliasnameと一致するSCANヒントを探す
  */
 static ScanMethodHint *
-find_scan_hint(RangeTblEntry *rte)
+find_scan_hint(PlannerInfo *root, RelOptInfo *rel)
 {
+       RangeTblEntry  *rte;
        int     i;
 
+       /* RELOPT_BASEREL でなければ、scan method ヒントが適用できない。 */
+       if (rel->reloptkind != RELOPT_BASEREL)
+               return NULL;
+
+       rte = root->simple_rte_array[rel->relid];
+
+       /*
+        * VALUESリストはValuesScanのみが選択できるため、ヒントが適用できない。
+        */
+       if (rte->rtekind == RTE_VALUES)
+               return NULL;
+
        for (i = 0; i < global->nscan_hints; i++)
        {
                ScanMethodHint *hint = global->scan_hints[i];
@@ -1529,16 +1526,16 @@ pg_hint_plan_get_relation_info(PlannerInfo *root, Oid relationObjectId,
        if (!global)
                return;
 
-       if (rel->reloptkind != RELOPT_BASEREL)
-               return;
-
        /* scan hint が指定されない場合は、GUCパラメータをリセットする。 */
-       if ((hint = find_scan_hint(root->simple_rte_array[rel->relid])) == NULL)
+       if ((hint = find_scan_hint(root, rel)) == NULL)
        {
                set_scan_config_options(global->init_scan_mask, global->context);
                return;
        }
 
+       set_scan_config_options(hint->enforce_mask, global->context);
+       hint->base.state = HINT_STATE_USED;
+
        /* インデックスを全て削除し、スキャンに使えなくする */
        if (hint->enforce_mask == ENABLE_SEQSCAN ||
                hint->enforce_mask == ENABLE_TIDSCAN)
@@ -1550,9 +1547,6 @@ pg_hint_plan_get_relation_info(PlannerInfo *root, Oid relationObjectId,
                return;
        }
 
-       set_scan_config_options(hint->enforce_mask, global->context);
-       hint->base.state = HINT_STATE_USED;
-
        /* 後でパスを作り直すため、ここではなにもしない */
        if (hint->indexnames == NULL)
                return;
@@ -1782,21 +1776,16 @@ rebuild_scan_path(PlanHint *plan, PlannerInfo *root, int level, List *initial_re
                 * scan method hint が指定されていなければ、初期値のGUCパラメータでscan
                 * path を再生成する。
                 */
-               if ((hint = find_scan_hint(rte)) == NULL || !hint_state_enabled(hint))
+               if ((hint = find_scan_hint(root, rel)) == NULL)
                        set_scan_config_options(plan->init_scan_mask, plan->context);
                else
                {
-                       /*
-                        * XXX ヒントで指定されたScan方式が最安価でない場合のみ、Pathを生成
-                        * しなおす
-                        */
                        set_scan_config_options(hint->enforce_mask, plan->context);
+                       hint->base.state = HINT_STATE_USED;
                }
 
                rel->pathlist = NIL;    /* TODO 解放の必要はある? */
                set_plain_rel_pathlist(root, rel, rte);
-               if (hint)
-                       hint->base.state = HINT_STATE_USED;
        }
 
        /*
@@ -1882,10 +1871,11 @@ pg_hint_plan_join_search(PlannerInfo *root, int levels_needed, List *initial_rel
 #define add_paths_to_joinrel(root, joinrel, outerrel, innerrel, jointype, sjinfo, restrictlist) \
 do { \
        ScanMethodHint *hint = NULL; \
-       if ((innerrel)->reloptkind == RELOPT_BASEREL && \
-               ((root)->simple_rte_array[(innerrel)->relid])->rtekind != RTE_VALUES && \
-               (hint = find_scan_hint((root)->simple_rte_array[(innerrel)->relid])) != NULL) \
+       if ((hint = find_scan_hint((root), (innerrel))) != NULL) \
+       { \
                set_scan_config_options(hint->enforce_mask, global->context); \
+               hint->base.state = HINT_STATE_USED; \
+       } \
        add_paths_to_joinrel((root), (joinrel), (outerrel), (innerrel), (jointype), (sjinfo), (restrictlist)); \
        if (hint != NULL) \
                set_scan_config_options(global->init_scan_mask, global->context); \
index 570ecc4..36613df 100644 (file)
@@ -119,3 +119,193 @@ EXPLAIN SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.i
 EXPLAIN SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10);
 /*+BitmapScan(v_1)BitmapScan(v_2)BitmapScan(t1)*/
 EXPLAIN SELECT (SELECT max(id) FROM t1 v_1 WHERE id < 10), id FROM v1 WHERE v1.id = (SELECT max(id) FROM t1 v_2 WHERE id < 10);
+
+-- full scan hint pattern test
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+SeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+IndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+BitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+TidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+NoSeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+NoIndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+NoBitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+/*+NoTidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1 WHERE id < 10 AND ctid = '(1,1)';
+
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+SeqScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+IndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+IndexScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+BitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+BitmapScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+TidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+TidScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+NoSeqScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoSeqScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+NoIndexScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoIndexScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+NoBitmapScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoBitmapScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+
+/*+NoTidScan(t1)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) SeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) IndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) BitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) TidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) NoSeqScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) NoIndexScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) NoBitmapScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';
+/*+NoTidScan(t1) NoTidScan(t2)*/
+EXPLAIN (COSTS false) SELECT * FROM t1, t2 WHERE t1.id = t2.id AND t1.ctid = '(1,1)' AND t2.ctid = '(1,1)';