OSDN Git Service

Ignore non-existent prepared statement in get_query_string.
[pghintplan/pg_hint_plan.git] / core.c
diff --git a/core.c b/core.c
index b36cdd8..54f5d3b 100644 (file)
--- a/core.c
+++ b/core.c
@@ -3,7 +3,6 @@
  * core.c
  *       Routines copied from PostgreSQL core distribution.
  *
-
  * The main purpose of this files is having access to static functions in core.
  * Another purpose is tweaking functions behavior by replacing part of them by
  * macro definitions. See at the end of pg_hint_plan.c for details. Anyway,
  *
  * src/backend/optimizer/path/allpaths.c
  *
- *     static functions:
- *        set_plain_rel_pathlist()
- *     set_append_rel_pathlist()
- *     add_paths_to_append_rel()
- *     generate_mergeappend_paths()
- *     get_cheapest_parameterized_child_path()
- *     accumulate_append_subpath()
- *
  *  public functions:
  *     standard_join_search(): This funcion is not static. The reason for
  *        including this function is make_rels_by_clause_joins. In order to
  *        change the behavior of make_join_rel, which is called under this
  *        function.
  *
+ *     static functions:
+ *        set_plain_rel_pathlist()
+ *        create_plain_partial_paths()
+ *        set_append_rel_pathlist()
+ *        add_paths_to_append_rel()
+ *        generate_mergeappend_paths()
+ *        get_cheapest_parameterized_child_path()
+ *
  * src/backend/optimizer/path/joinrels.c
  *
  *     public functions:
  *     make_rels_by_clauseless_joins()
  *     join_is_legal()
  *     has_join_restriction()
- *     is_dummy_rel()
  *     mark_dummy_rel()
  *     restriction_is_constant_false()
  *
- *
- * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *-------------------------------------------------------------------------
  */
 
+static void populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1,
+                                                       RelOptInfo *rel2, RelOptInfo *joinrel,
+                                                       SpecialJoinInfo *sjinfo, List *restrictlist);
 
 /*
  * set_plain_rel_pathlist
@@ -83,6 +83,26 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
 
 
 /*
+ * create_plain_partial_paths
+ *       Build partial access paths for parallel scan of a plain relation
+ */
+static void
+create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
+{
+       int                     parallel_workers;
+
+       parallel_workers = compute_parallel_worker(rel, rel->pages, -1);
+
+       /* If any limit was set to zero, the user doesn't want a parallel scan. */
+       if (parallel_workers <= 0)
+               return;
+
+       /* Add an unordered partial path based on a parallel sequential scan. */
+       add_partial_path(rel, create_seqscan_path(root, rel, NULL, parallel_workers));
+}
+
+
+/*
  * set_append_rel_pathlist
  *       Build access paths for an "append relation"
  */
@@ -144,6 +164,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
        add_paths_to_append_rel(root, rel, live_childrels);
 }
 
+
 /*
  * add_paths_to_append_rel
  *             Generate paths for given "append" relation given the set of non-dummy
@@ -195,7 +216,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
                        build_partitioned_rels = true;
                        break;
                default:
-                       elog(ERROR, "unexpcted rtekind: %d", (int) rte->rtekind);
+                       elog(ERROR, "unexpected rtekind: %d", (int) rte->rtekind);
        }
 
        /*
@@ -316,7 +337,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
        /*
         * Consider an append of partial unordered, unparameterized partial paths.
         */
-       if (partial_subpaths_valid)
+       if (partial_subpaths_valid && partial_subpaths != NIL)
        {
                AppendPath *appendpath;
                ListCell   *lc;
@@ -716,25 +737,6 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
        return rel;
 }
 
-/*
- * create_plain_partial_paths
- *       Build partial access paths for parallel scan of a plain relation
- */
-static void
-create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
-{
-       int                     parallel_workers;
-
-       parallel_workers = compute_parallel_worker(rel, rel->pages, -1);
-
-       /* If any limit was set to zero, the user doesn't want a parallel scan. */
-       if (parallel_workers <= 0)
-               return;
-
-       /* Add an unordered partial path based on a parallel sequential scan. */
-       add_partial_path(rel, create_seqscan_path(root, rel, NULL, parallel_workers));
-}
-
 
 /*
  * join_search_one_level
@@ -1312,6 +1314,10 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
                                {
                                        SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l);
 
+                                       /* ignore full joins --- their ordering is predetermined */
+                                       if (sjinfo->jointype == JOIN_FULL)
+                                               continue;
+
                                        if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) &&
                                                !bms_is_subset(sjinfo->min_righthand, join_plus_rhs))
                                        {
@@ -1319,15 +1325,6 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
                                                                                                                sjinfo->min_righthand);
                                                more = true;
                                        }
-                                       /* full joins constrain both sides symmetrically */
-                                       if (sjinfo->jointype == JOIN_FULL &&
-                                               bms_overlap(sjinfo->min_righthand, join_plus_rhs) &&
-                                               !bms_is_subset(sjinfo->min_lefthand, join_plus_rhs))
-                                       {
-                                               join_plus_rhs = bms_add_members(join_plus_rhs,
-                                                                                                               sjinfo->min_lefthand);
-                                               more = true;
-                                       }
                                }
                        } while (more);
                        if (bms_overlap(join_plus_rhs, join_lateral_rels))
@@ -1394,16 +1391,6 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
 
 
 /*
- * is_dummy_rel --- has relation been proven empty?
- */
-static bool
-is_dummy_rel(RelOptInfo *rel)
-{
-       return IS_DUMMY_REL(rel);
-}
-
-
-/*
  * Mark a relation as proven empty.
  *
  * During GEQO planning, this can get invoked more than once on the same
@@ -1438,7 +1425,9 @@ mark_dummy_rel(RelOptInfo *rel)
        rel->partial_pathlist = NIL;
 
        /* Set up the dummy path */
-       add_path(rel, (Path *) create_append_path(rel, NIL, NULL, 0, NIL));
+       add_path(rel, (Path *) create_append_path(rel, NIL,
+                                                                                         rel->lateral_relids,
+                                                                                         0, NIL));
 
        /* Set or update cheapest_total_path and related fields */
        set_cheapest(rel);
@@ -1448,18 +1437,21 @@ mark_dummy_rel(RelOptInfo *rel)
 
 
 /*
- * restriction_is_constant_false --- is a restrictlist just FALSE?
+ * restriction_is_constant_false --- is a restrictlist just false?
  *
- * In cases where a qual is provably constant FALSE, eval_const_expressions
+ * In cases where a qual is provably constant false, eval_const_expressions
  * will generally have thrown away anything that's ANDed with it.  In outer
  * join situations this will leave us computing cartesian products only to
  * decide there's no match for an outer row, which is pretty stupid.  So,
  * we need to detect the case.
  *
- * If only_pushed_down is TRUE, then consider only pushed-down quals.
+ * If only_pushed_down is true, then consider only quals that are pushed-down
+ * from the point of view of the joinrel.
  */
 static bool
-restriction_is_constant_false(List *restrictlist, bool only_pushed_down)
+restriction_is_constant_false(List *restrictlist,
+                                                         RelOptInfo *joinrel,
+                                                         bool only_pushed_down)
 {
        ListCell   *lc;
 
@@ -1473,7 +1465,7 @@ restriction_is_constant_false(List *restrictlist, bool only_pushed_down)
        {
                RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
 
-               if (only_pushed_down && !rinfo->is_pushed_down)
+               if (only_pushed_down && !RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids))
                        continue;
 
                if (rinfo->clause && IsA(rinfo->clause, Const))