Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
-> Seq Scan on p1_c3 p1
Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c4 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c1_c1 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c1_c2 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c3_c1 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c3_c2 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Tid Scan on p1_c4 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c3_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c3_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(25 rows)
+(30 rows)
/*+IndexScan(p1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
duplication hint:
error hint:
- QUERY PLAN
------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------
Merge Join
Merge Cond: (public.p1.id = t1.id)
- -> Merge Append
+ -> Sort
Sort Key: public.p1.id
- -> Index Scan using p1_pkey on p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c1_pkey on p1_c1 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c2_pkey on p1_c2 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c3_pkey on p1_c3 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c4_pkey on p1_c4 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c3_c1_pkey on p1_c3_c1 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c3_c2_pkey on p1_c3_c2 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
+ -> Append
+ -> Seq Scan on p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c1 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c2 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c3 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Tid Scan on p1_c4 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c3_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c3_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(33 rows)
+(30 rows)
/*+BitmapScan(p1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
duplication hint:
error hint:
- QUERY PLAN
--------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------
Merge Join
Merge Cond: (public.p1.id = t1.id)
-> Sort
Sort Key: public.p1.id
-> Append
- -> Bitmap Heap Scan on p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c1 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c2 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c2_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c3 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c3_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c4 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c4_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c1_c1 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c1_c1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c1_c2 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c1_c2_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c3_c1 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c3_c1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c3_c2 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c3_c2_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
+ -> Seq Scan on p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c1 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c2 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c3 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Tid Scan on p1_c4 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c3_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c3_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(52 rows)
+(30 rows)
/*+TidScan(p1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
duplication hint:
error hint:
- QUERY PLAN
----------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------
Merge Join
Merge Cond: (public.p1.id = t1.id)
-> Sort
Sort Key: public.p1.id
-> Append
- -> Tid Scan on p1
- TID Cond: (ctid = '(1,1)'::tid)
- Filter: ((id >= 50) AND (id <= 51))
- -> Tid Scan on p1_c1 p1
- TID Cond: (ctid = '(1,1)'::tid)
- Filter: ((id >= 50) AND (id <= 51))
- -> Tid Scan on p1_c2 p1
- TID Cond: (ctid = '(1,1)'::tid)
- Filter: ((id >= 50) AND (id <= 51))
- -> Tid Scan on p1_c3 p1
- TID Cond: (ctid = '(1,1)'::tid)
- Filter: ((id >= 50) AND (id <= 51))
+ -> Seq Scan on p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c1 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c2 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c3 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
-> Tid Scan on p1_c4 p1
TID Cond: (ctid = '(1,1)'::tid)
Filter: ((id >= 50) AND (id <= 51))
Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(34 rows)
+(30 rows)
/*+NestLoop(p1 t1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
-> Seq Scan on p1_c1 p1
Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c1_c1 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
- -> Seq Scan on p1_c1_c2 p1
- Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Tid Scan on p1_c1_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(15 rows)
+(17 rows)
/*+IndexScan(p1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
duplication hint:
error hint:
- QUERY PLAN
------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------
Merge Join
Merge Cond: (public.p1.id = t1.id)
- -> Merge Append
+ -> Sort
Sort Key: public.p1.id
- -> Index Scan using p1_pkey on p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c1_pkey on p1_c1 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c1_c1_pkey on p1_c1_c1 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Index Scan using p1_c1_c2_pkey on p1_c1_c2 p1
- Index Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
+ -> Append
+ -> Seq Scan on p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c1 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Tid Scan on p1_c1_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(18 rows)
+(17 rows)
/*+BitmapScan(p1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
duplication hint:
error hint:
- QUERY PLAN
--------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------
Merge Join
Merge Cond: (public.p1.id = t1.id)
-> Sort
Sort Key: public.p1.id
-> Append
- -> Bitmap Heap Scan on p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c1 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c1_c1 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c1_c1_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
- -> Bitmap Heap Scan on p1_c1_c2 p1
- Recheck Cond: ((id >= 50) AND (id <= 51))
- Filter: (ctid = '(1,1)'::tid)
- -> Bitmap Index Scan on p1_c1_c2_pkey
- Index Cond: ((id >= 50) AND (id <= 51))
+ -> Seq Scan on p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c1 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Tid Scan on p1_c1_c1 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
+ -> Tid Scan on p1_c1_c2 p1
+ TID Cond: (ctid = '(1,1)'::tid)
+ Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(27 rows)
+(17 rows)
/*+TidScan(p1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
duplication hint:
error hint:
- QUERY PLAN
----------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------
Merge Join
Merge Cond: (public.p1.id = t1.id)
-> Sort
Sort Key: public.p1.id
-> Append
- -> Tid Scan on p1
- TID Cond: (ctid = '(1,1)'::tid)
- Filter: ((id >= 50) AND (id <= 51))
- -> Tid Scan on p1_c1 p1
- TID Cond: (ctid = '(1,1)'::tid)
- Filter: ((id >= 50) AND (id <= 51))
+ -> Seq Scan on p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
+ -> Seq Scan on p1_c1 p1
+ Filter: ((id >= 50) AND (id <= 51) AND (ctid = '(1,1)'::tid))
-> Tid Scan on p1_c1_c1 p1
TID Cond: (ctid = '(1,1)'::tid)
Filter: ((id >= 50) AND (id <= 51))
Filter: ((id >= 50) AND (id <= 51))
-> Index Scan using t1_pkey on t1
Index Cond: (id < 10)
-(19 rows)
+(17 rows)
/*+NestLoop(p1 t1)*/
EXPLAIN (COSTS false) SELECT * FROM p1, t1 WHERE p1.id >= 50 AND p1.id <= 51 AND p1.ctid = '(1,1)' AND p1.id = t1.id AND t1.id < 10;
ScanMethodHint **scan_hints; /* parsed scan hints */
int init_scan_mask; /* initial value scan parameter */
Index parent_relid; /* inherit parent table relid */
+ ScanMethodHint *parent_hint; /* inherit parent table scan hint */
/* for join method hints */
JoinMethodHint **join_hints; /* parsed join hints */
hint->scan_hints = NULL;
hint->init_scan_mask = 0;
hint->parent_relid = 0;
+ hint->parent_hint = NULL;
hint->join_hints = NULL;
hint->init_join_mask = 0;
hint->join_hint_level = NULL;
}
static void
-pg_hint_plan_get_relation_info(PlannerInfo *root, Oid relationObjectId,
- bool inhparent, RelOptInfo *rel)
+delete_indexes(ScanMethodHint *hint, RelOptInfo *rel)
{
- ScanMethodHint *hint;
ListCell *cell;
ListCell *prev;
ListCell *next;
- if (prev_get_relation_info)
- (*prev_get_relation_info) (root, relationObjectId, inhparent, rel);
-
- /* 有効なヒントが指定されなかった場合は処理をスキップする。 */
- if (!global)
- return;
-
- if (inhparent)
- {
- /* store does relids of parent table. */
- global->parent_relid = rel->relid;
- }
- else if (global->parent_relid != 0)
- {
- /*
- * We use the same GUC parameter if this table is the child table of a
- * table called pg_hint_plan_get_relation_info just before that.
- */
- ListCell *l;
-
- /* append_rel_list contains all append rels; ignore others */
- foreach(l, root->append_rel_list)
- {
- AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
-
- /* This rel is child table. */
- if (appinfo->parent_relid == global->parent_relid)
- return;
- }
-
- /* This rel is not inherit table. */
- global->parent_relid = 0;
- }
-
- /* scan hint が指定されない場合は、GUCパラメータをリセットする。 */
- 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;
-
/*
* We delete all the IndexOptInfo list and prevent you from being usable by
* a scan.
}
}
+static void
+pg_hint_plan_get_relation_info(PlannerInfo *root, Oid relationObjectId,
+ bool inhparent, RelOptInfo *rel)
+{
+ ScanMethodHint *hint;
+
+ if (prev_get_relation_info)
+ (*prev_get_relation_info) (root, relationObjectId, inhparent, rel);
+
+ /* 有効なヒントが指定されなかった場合は処理をスキップする。 */
+ if (!global)
+ return;
+
+ if (inhparent)
+ {
+ /* store does relids of parent table. */
+ global->parent_relid = rel->relid;
+ }
+ else if (global->parent_relid != 0)
+ {
+ /*
+ * We use the same GUC parameter if this table is the child table of a
+ * table called pg_hint_plan_get_relation_info just before that.
+ */
+ ListCell *l;
+
+ /* append_rel_list contains all append rels; ignore others */
+ foreach(l, root->append_rel_list)
+ {
+ AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
+
+ /* This rel is child table. */
+ if (appinfo->parent_relid == global->parent_relid &&
+ appinfo->child_relid == rel->relid)
+ {
+ if (global->parent_hint)
+ delete_indexes(global->parent_hint, rel);
+
+ return;
+ }
+ }
+
+ /* This rel is not inherit table. */
+ global->parent_relid = 0;
+ global->parent_hint = NULL;
+ }
+
+ /* scan hint が指定されない場合は、GUCパラメータをリセットする。 */
+ 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 (inhparent)
+ global->parent_hint = hint;
+
+ delete_indexes(hint, rel);
+}
+
/*
* aliasnameがクエリ中に指定した別名と一致する場合は、そのインデックスを返し、一致
* する別名がなければ0を返す。