OSDN Git Service

試験項目作成中に修正した以下のバグを元に戻した。
[pghintplan/pg_hint_plan.git] / core.c
diff --git a/core.c b/core.c
index dbea365..b37d3b5 100644 (file)
--- a/core.c
+++ b/core.c
@@ -3,22 +3,14 @@
  * core.c
  *       Routines copied from PostgreSQL core distribution.
  *
- * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *-------------------------------------------------------------------------
- */
-/*
- * PostgreSQL 本体から流用した関数
- *
  * src/backend/optimizer/path/allpaths.c
- *     standard_join_search()
  *     set_plain_rel_pathlist()
  *     set_append_rel_pathlist()
  *     accumulate_append_subpath()
  *     set_dummy_rel_pathlist()
+ *     standard_join_search()
  *
- * src/backend/optimizer/path/joinrels.c:
+ * src/backend/optimizer/path/joinrels.c
  *     join_search_one_level()
  *     make_rels_by_clause_joins()
  *     make_rels_by_clauseless_joins()
  *     is_dummy_rel()
  *     mark_dummy_rel()
  *     restriction_is_constant_false()
- */
-
-/*
- * standard_join_search
- *       Find possible joinpaths for a query by successively finding ways
- *       to join component relations into join relations.
- *
- * 'levels_needed' is the number of iterations needed, ie, the number of
- *             independent jointree items in the query.  This is > 1.
- *
- * 'initial_rels' is a list of RelOptInfo nodes for each independent
- *             jointree item.  These are the components to be joined together.
- *             Note that levels_needed == list_length(initial_rels).
- *
- * Returns the final level of join relations, i.e., the relation that is
- * the result of joining all the original relations together.
- * At least one implementation path must be provided for this relation and
- * all required sub-relations.
  *
- * To support loadable plugins that modify planner behavior by changing the
- * join searching algorithm, we provide a hook variable that lets a plugin
- * replace or supplement this function.  Any such hook must return the same
- * final join relation as the standard code would, but it might have a
- * different set of implementation paths attached, and only the sub-joinrels
- * needed for these paths need have been instantiated.
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
  *
- * Note to plugin authors: the functions invoked during standard_join_search()
- * modify root->join_rel_list and root->join_rel_hash. If you want to do more
- * than one join-order search, you'll probably need to save and restore the
- * original states of those data structures.  See geqo_eval() for an example.
+ *-------------------------------------------------------------------------
  */
-RelOptInfo *
-standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
-{
-       int                     lev;
-       RelOptInfo *rel;
-
-       /*
-        * This function cannot be invoked recursively within any one planning
-        * problem, so join_rel_level[] can't be in use already.
-        */
-       Assert(root->join_rel_level == NULL);
-
-       /*
-        * We employ a simple "dynamic programming" algorithm: we first find all
-        * ways to build joins of two jointree items, then all ways to build joins
-        * of three items (from two-item joins and single items), then four-item
-        * joins, and so on until we have considered all ways to join all the
-        * items into one rel.
-        *
-        * root->join_rel_level[j] is a list of all the j-item rels.  Initially we
-        * set root->join_rel_level[1] to represent all the single-jointree-item
-        * relations.
-        */
-       root->join_rel_level = (List **) palloc0((levels_needed + 1) * sizeof(List *));
-
-       root->join_rel_level[1] = initial_rels;
-
-       for (lev = 2; lev <= levels_needed; lev++)
-       {
-               ListCell   *lc;
-
-               /*
-                * Determine all possible pairs of relations to be joined at this
-                * level, and build paths for making each one from every available
-                * pair of lower-level relations.
-                */
-               join_search_one_level(root, lev);
-
-               /*
-                * Do cleanup work on each just-processed rel.
-                */
-               foreach(lc, root->join_rel_level[lev])
-               {
-                       rel = (RelOptInfo *) lfirst(lc);
-
-                       /* Find and save the cheapest paths for this rel */
-                       set_cheapest(rel);
-
-#ifdef OPTIMIZER_DEBUG
-                       debug_print_rel(root, rel);
-#endif
-               }
-       }
-
-       /*
-        * We should have a single rel at the final level.
-        */
-       if (root->join_rel_level[levels_needed] == NIL)
-               elog(ERROR, "failed to build any %d-way joins", levels_needed);
-       Assert(list_length(root->join_rel_level[levels_needed]) == 1);
-
-       rel = (RelOptInfo *) linitial(root->join_rel_level[levels_needed]);
-
-       root->join_rel_level = NULL;
-
-       return rel;
-}
 
 /*
  * set_plain_rel_pathlist
@@ -536,6 +436,102 @@ set_dummy_rel_pathlist(RelOptInfo *rel)
        set_cheapest(rel);
 }
 
+/*
+ * standard_join_search
+ *       Find possible joinpaths for a query by successively finding ways
+ *       to join component relations into join relations.
+ *
+ * 'levels_needed' is the number of iterations needed, ie, the number of
+ *             independent jointree items in the query.  This is > 1.
+ *
+ * 'initial_rels' is a list of RelOptInfo nodes for each independent
+ *             jointree item.  These are the components to be joined together.
+ *             Note that levels_needed == list_length(initial_rels).
+ *
+ * Returns the final level of join relations, i.e., the relation that is
+ * the result of joining all the original relations together.
+ * At least one implementation path must be provided for this relation and
+ * all required sub-relations.
+ *
+ * To support loadable plugins that modify planner behavior by changing the
+ * join searching algorithm, we provide a hook variable that lets a plugin
+ * replace or supplement this function.  Any such hook must return the same
+ * final join relation as the standard code would, but it might have a
+ * different set of implementation paths attached, and only the sub-joinrels
+ * needed for these paths need have been instantiated.
+ *
+ * Note to plugin authors: the functions invoked during standard_join_search()
+ * modify root->join_rel_list and root->join_rel_hash. If you want to do more
+ * than one join-order search, you'll probably need to save and restore the
+ * original states of those data structures.  See geqo_eval() for an example.
+ */
+RelOptInfo *
+standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
+{
+       int                     lev;
+       RelOptInfo *rel;
+
+       /*
+        * This function cannot be invoked recursively within any one planning
+        * problem, so join_rel_level[] can't be in use already.
+        */
+       Assert(root->join_rel_level == NULL);
+
+       /*
+        * We employ a simple "dynamic programming" algorithm: we first find all
+        * ways to build joins of two jointree items, then all ways to build joins
+        * of three items (from two-item joins and single items), then four-item
+        * joins, and so on until we have considered all ways to join all the
+        * items into one rel.
+        *
+        * root->join_rel_level[j] is a list of all the j-item rels.  Initially we
+        * set root->join_rel_level[1] to represent all the single-jointree-item
+        * relations.
+        */
+       root->join_rel_level = (List **) palloc0((levels_needed + 1) * sizeof(List *));
+
+       root->join_rel_level[1] = initial_rels;
+
+       for (lev = 2; lev <= levels_needed; lev++)
+       {
+               ListCell   *lc;
+
+               /*
+                * Determine all possible pairs of relations to be joined at this
+                * level, and build paths for making each one from every available
+                * pair of lower-level relations.
+                */
+               join_search_one_level(root, lev);
+
+               /*
+                * Do cleanup work on each just-processed rel.
+                */
+               foreach(lc, root->join_rel_level[lev])
+               {
+                       rel = (RelOptInfo *) lfirst(lc);
+
+                       /* Find and save the cheapest paths for this rel */
+                       set_cheapest(rel);
+
+#ifdef OPTIMIZER_DEBUG
+                       debug_print_rel(root, rel);
+#endif
+               }
+       }
+
+       /*
+        * We should have a single rel at the final level.
+        */
+       if (root->join_rel_level[levels_needed] == NIL)
+               elog(ERROR, "failed to build any %d-way joins", levels_needed);
+       Assert(list_length(root->join_rel_level[levels_needed]) == 1);
+
+       rel = (RelOptInfo *) linitial(root->join_rel_level[levels_needed]);
+
+       root->join_rel_level = NULL;
+
+       return rel;
+}
 
 /*
  * join_search_one_level
@@ -1013,7 +1009,6 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
        return true;
 }
 
-
 /*
  * has_join_restriction
  *             Detect whether the specified relation has join-order restrictions
@@ -1051,7 +1046,6 @@ has_join_restriction(PlannerInfo *root, RelOptInfo *rel)
        return false;
 }
 
-
 /*
  * is_dummy_rel --- has relation been proven empty?
  *
@@ -1064,7 +1058,6 @@ is_dummy_rel(RelOptInfo *rel)
                        IS_DUMMY_PATH(rel->cheapest_total_path));
 }
 
-
 /*
  * Mark a relation as proven empty.
  *
@@ -1107,7 +1100,6 @@ mark_dummy_rel(RelOptInfo *rel)
        MemoryContextSwitchTo(oldcontext);
 }
 
-
 /*
  * restriction_is_constant_false --- is a restrictlist just FALSE?
  *