diff --git a/expected/pg_hint_plan.out b/expected/pg_hint_plan.out index 2757225..9cb6aec 100644 --- a/expected/pg_hint_plan.out +++ b/expected/pg_hint_plan.out @@ -5571,15 +5571,15 @@ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(t5 no_exist) +not used hint: duplication hint: error hint: - QUERY PLAN ----------------------------------------------------------------------------------------- - Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+IndexScan(t5 t5_id1 t5_id2)*/ @@ -5619,15 +5619,15 @@ EXPLAIN (COSTS false) SELECT * FROM t5 WHERE t5.id = 1; LOG: available indexes for IndexScan(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(t5 no_exist5 no_exist2) +not used hint: duplication hint: error hint: - QUERY PLAN ----------------------------------------------------------------------------------------- - Index Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) -- outer inner @@ -6746,8 +6746,8 @@ LOG: available indexes for IndexScan(p2_c3_c1): LOG: available indexes for IndexScan(p2_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(p2 p2_val) +not used hint: duplication hint: error hint: @@ -6924,8 +6924,8 @@ LOG: available indexes for IndexScan(p2_c1_c1): LOG: available indexes for IndexScan(p2_c1_c2): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(p2 no_exist) +not used hint: duplication hint: error hint: @@ -7287,15 +7287,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScanRegexp(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexScanRegexp(t5 t5[^_].*) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ IndexScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ @@ -7303,15 +7303,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScanRegexp(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ IndexScan(t5 t5_id[0-9].*)*/ @@ -7319,15 +7319,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexScan(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(t5 t5_id[0-9].*) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ IndexOnlyScanRegexp(t5 t5_[^i].*)*/ @@ -7367,15 +7367,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScanRegexp(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexOnlyScanRegexp(t5 t5[^_].*) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ IndexOnlyScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ @@ -7383,15 +7383,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScanRegexp(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexOnlyScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ IndexOnlyScan(t5 t5_id[0-9].*)*/ @@ -7399,15 +7399,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for IndexOnlyScan(t5): LOG: pg_hint_plan: used hint: -not used hint: IndexOnlyScan(t5 t5_id[0-9].*) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ BitmapScanRegexp(t5 t5_[^i].*)*/ @@ -7451,15 +7451,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScanRegexp(t5): LOG: pg_hint_plan: used hint: -not used hint: BitmapScanRegexp(t5 t5[^_].*) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ BitmapScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab)*/ @@ -7467,15 +7467,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScanRegexp(t5): LOG: pg_hint_plan: used hint: -not used hint: BitmapScanRegexp(t5 ^.*t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) /*+ BitmapScan(t5 t5_id[0-9].*)*/ @@ -7483,15 +7483,15 @@ EXPLAIN (COSTS false) SELECT id FROM t5 WHERE id = 1; LOG: available indexes for BitmapScan(t5): LOG: pg_hint_plan: used hint: -not used hint: BitmapScan(t5 t5_id[0-9].*) +not used hint: duplication hint: error hint: - QUERY PLAN ---------------------------------------------------------------------------------------------- - Index Only Scan using t5_idaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa on t5 - Index Cond: (id = 1) + QUERY PLAN +-------------------- + Seq Scan on t5 + Filter: (id = 1) (2 rows) -- Inheritance @@ -7614,8 +7614,8 @@ LOG: available indexes for IndexScanRegexp(p1_c3_c1): LOG: available indexes for IndexScanRegexp(p1_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: IndexScanRegexp(p1 p1[^_].*) +not used hint: duplication hint: error hint: @@ -7655,8 +7655,8 @@ LOG: available indexes for IndexScan(p1_c3_c1): LOG: available indexes for IndexScan(p1_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(p1 p1_.*val2.*) +not used hint: duplication hint: error hint: @@ -7778,8 +7778,8 @@ LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c1): LOG: available indexes for IndexOnlyScanRegexp(p1_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: IndexOnlyScanRegexp(p1 p1[^_].*) +not used hint: duplication hint: error hint: @@ -7819,8 +7819,8 @@ LOG: available indexes for IndexOnlyScan(p1_c3_c1): LOG: available indexes for IndexOnlyScan(p1_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: IndexOnlyScan(p1 p1_.*val2.*) +not used hint: duplication hint: error hint: @@ -7960,8 +7960,8 @@ LOG: available indexes for BitmapScanRegexp(p1_c3_c1): LOG: available indexes for BitmapScanRegexp(p1_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: BitmapScanRegexp(p1 p1[^_].*) +not used hint: duplication hint: error hint: @@ -8001,8 +8001,8 @@ LOG: available indexes for BitmapScan(p1_c3_c1): LOG: available indexes for BitmapScan(p1_c3_c2): LOG: pg_hint_plan: used hint: -not used hint: BitmapScan(p1 p1_.*val2.*) +not used hint: duplication hint: error hint: diff --git a/expected/ut-S.out b/expected/ut-S.out index 047d1ce..82cb440 100644 --- a/expected/ut-S.out +++ b/expected/ut-S.out @@ -4474,8 +4474,8 @@ error hint: LOG: available indexes for IndexScan(ti1): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(ti1 not_exist) +not used hint: duplication hint: error hint: @@ -4483,8 +4483,8 @@ error hint: \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- - Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) - Index Cond: (c1 = 100) + Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) + Filter: (c1 = 100) -- No. S-3-5-5 \o results/ut-S.tmpout @@ -4492,8 +4492,8 @@ error hint: LOG: available indexes for BitmapScan(ti1): LOG: pg_hint_plan: used hint: -not used hint: BitmapScan(ti1 not_exist) +not used hint: duplication hint: error hint: @@ -4501,8 +4501,8 @@ error hint: \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- - Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) - Index Cond: (c1 = 100) + Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) + Filter: (c1 = 100) -- No. S-3-5-6 \o results/ut-S.tmpout @@ -4510,8 +4510,8 @@ error hint: LOG: available indexes for IndexOnlyScan(ti1): LOG: pg_hint_plan: used hint: -not used hint: IndexOnlyScan(ti1 not_exist) +not used hint: duplication hint: error hint: @@ -4519,8 +4519,8 @@ error hint: \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- - Index Scan using ti1_hash on ti1 (cost=xxx..xxx rows=1 width=xxx) - Index Cond: (c1 = 100) + Seq Scan on ti1 (cost={inf}..{inf} rows=1 width=xxx) + Filter: (c1 = 100) -- No. S-3-5-7 EXPLAIN (COSTS false) SELECT * FROM s1.t1 WHERE t1.c1 = 1; @@ -5223,11 +5223,11 @@ error hint: Append (cost=xxx..xxx rows=4 width=xxx) -> Index Scan using p1_i2 on p1 p1_1 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c2 = 1) - -> Seq Scan on p1c1 p1_2 (cost=xxx..xxx rows=1 width=xxx) + -> Seq Scan on p1c1 p1_2 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c2 = 1) - -> Seq Scan on p1c2 p1_3 (cost=xxx..xxx rows=1 width=xxx) + -> Seq Scan on p1c2 p1_3 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c2 = 1) - -> Seq Scan on p1c3 p1_4 (cost=xxx..xxx rows=1 width=xxx) + -> Seq Scan on p1c3 p1_4 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c2 = 1) -- No. S-3-10-5 @@ -5247,12 +5247,12 @@ error hint: \! sql/maskout.sh results/ut-S.tmpout QUERY PLAN ---------------- - Append (cost=xxx..xxx rows=3 width=xxx) - -> Seq Scan on p2 p2_1 (cost=xxx..xxx rows=1 width=xxx) + Append (cost={inf}..{inf} rows=3 width=xxx) + -> Seq Scan on p2 p2_1 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 1) -> Index Scan using p2c1_pkey on p2c1 p2_2 (cost=xxx..xxx rows=1 width=xxx) Index Cond: (c1 = 1) - -> Seq Scan on p2c1c1 p2_3 (cost=xxx..xxx rows=1 width=xxx) + -> Seq Scan on p2c1c1 p2_3 (cost={inf}..{inf} rows=1 width=xxx) Filter: (c1 = 1) ---- @@ -5950,15 +5950,15 @@ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScanRegexp(ti1): LOG: pg_hint_plan: used hint: -not used hint: IndexScanRegexp(ti1 no.*_exist) +not used hint: duplication hint: error hint: - QUERY PLAN --------------------------------- - Index Scan using ti1_i4 on ti1 - Index Cond: (c2 = 1) + QUERY PLAN +-------------------- + Seq Scan on ti1 + Filter: (c2 = 1) (2 rows) -- No. S-3-14-4 @@ -6010,8 +6010,8 @@ LOG: available indexes for IndexScanRegexp(p1): LOG: available indexes for IndexScanRegexp(p1c1): LOG: pg_hint_plan: used hint: -not used hint: IndexScanRegexp(p1 no.*_exist) +not used hint: duplication hint: error hint: @@ -6050,15 +6050,15 @@ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(ti1 not_exist) +not used hint: duplication hint: error hint: - QUERY PLAN --------------------------------- - Index Scan using ti1_i4 on ti1 - Index Cond: (c2 = 1) + QUERY PLAN +-------------------- + Seq Scan on ti1 + Filter: (c2 = 1) (2 rows) -- No. S-3-15-3 @@ -6101,15 +6101,15 @@ EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c2 = 1; LOG: available indexes for IndexScan(ti1): LOG: pg_hint_plan: used hint: -not used hint: IndexScan(ti1 not_exist1 not_exist2) +not used hint: duplication hint: error hint: - QUERY PLAN --------------------------------- - Index Scan using ti1_i4 on ti1 - Index Cond: (c2 = 1) + QUERY PLAN +-------------------- + Seq Scan on ti1 + Filter: (c2 = 1) (2 rows) DELETE FROM pg_db_role_setting WHERE setrole = (SELECT oid FROM pg_roles WHERE rolname = current_user); diff --git a/pg_hint_plan.c b/pg_hint_plan.c index 6bf23cc..d4ae5f3 100644 --- a/pg_hint_plan.c +++ b/pg_hint_plan.c @@ -3449,25 +3449,15 @@ regexpeq(const char *s1, const char *s2) } -/* - * Filter out indexes instructed in the hint as not to be used. - * - * This routine is used in relationship with the scan method enforcement, and - * it returns true to allow the follow-up scan method to be enforced, and false - * to prevent the scan enforcement. Currently, this code will not enforce - * the scan enforcement if *all* the indexes available to a relation have been - * discarded. - */ -static bool +/* Remove indexes instructed not to use by hint. */ +static void restrict_indexes(PlannerInfo *root, ScanMethodHint *hint, RelOptInfo *rel, - bool using_parent_hint) + bool using_parent_hint) { ListCell *cell; StringInfoData buf; RangeTblEntry *rte = root->simple_rte_array[rel->relid]; Oid relationObjectId = rte->relid; - List *unused_indexes = NIL; - bool restrict_result; /* * We delete all the IndexOptInfo list and prevent you from being usable by @@ -3480,20 +3470,18 @@ restrict_indexes(PlannerInfo *root, ScanMethodHint *hint, RelOptInfo *rel, rel->indexlist = NIL; hint->base.state = HINT_STATE_USED; - return true; + return; } /* * When a list of indexes is not specified, we just use all indexes. */ if (hint->indexnames == NIL) - return true; + return; /* * Leaving only an specified index, we delete it from a IndexOptInfo list - * other than it. However, if none of the specified indexes are available, - * then we keep all the indexes and skip enforcing the scan method. i.e., - * we skip the scan hint altogether for the relation. + * other than it. */ if (debug_level > 0) initStringInfo(&buf); @@ -3687,42 +3675,11 @@ restrict_indexes(PlannerInfo *root, ScanMethodHint *hint, RelOptInfo *rel, } if (!use_index) - unused_indexes = lappend_oid(unused_indexes, info->indexoid); + rel->indexlist = foreach_delete_current(rel->indexlist, cell); pfree(indexname); } - /* - * Update the list of indexes available to the IndexOptInfo based on what - * has been discarded previously. - * - * If the hint has no matching indexes, skip applying the hinted scan - * method. For example if an IndexScan hint does not have any matching - * indexes, we should not enforce an enable_indexscan. - */ - if (list_length(unused_indexes) < list_length(rel->indexlist)) - { - foreach (cell, unused_indexes) - { - Oid final_oid = lfirst_oid(cell); - ListCell *l; - - foreach (l, rel->indexlist) - { - IndexOptInfo *info = (IndexOptInfo *) lfirst(l); - - if (info->indexoid == final_oid) - rel->indexlist = foreach_delete_current(rel->indexlist, l); - } - } - - restrict_result = true; - } - else - restrict_result = false; - - list_free(unused_indexes); - if (debug_level > 0) { StringInfoData rel_buf; @@ -3749,8 +3706,6 @@ restrict_indexes(PlannerInfo *root, ScanMethodHint *hint, RelOptInfo *rel, pfree(buf.data); pfree(rel_buf.data); } - - return restrict_result; } /* @@ -3939,6 +3894,8 @@ setup_hint_enforcement(PlannerInfo *root, RelOptInfo *rel, { ScanMethodHint * pshint = current_hint_state->parent_scan_hint; + pshint->base.state = HINT_STATE_USED; + /* Apply index mask in the same manner to the parent. */ if (pshint->indexnames) { @@ -3984,22 +3941,14 @@ setup_hint_enforcement(PlannerInfo *root, RelOptInfo *rel, { bool using_parent_hint = (shint == current_hint_state->parent_scan_hint); - bool restrict_result; ret |= HINT_BM_SCAN_METHOD; - /* restrict unwanted indexes */ - restrict_result = restrict_indexes(root, shint, rel, using_parent_hint); + /* Setup scan enforcement environment */ + setup_scan_method_enforcement(shint, current_hint_state); - /* - * Setup scan enforcement environment - * - * This has to be called after restrict_indexes(), that may decide to - * skip the scan method enforcement depending on the index restrictions - * applied. - */ - if (restrict_result) - setup_scan_method_enforcement(shint, current_hint_state); + /* restrict unwanted inexes */ + restrict_indexes(root, shint, rel, using_parent_hint); if (debug_level > 1) {