*** pgsql/src/backend/optimizer/path/allpaths.c 2009/11/22 14:54:31 1.190 --- pgsql/src/backend/optimizer/path/allpaths.c 2009/11/28 00:46:19 1.191 *************** *** 8,14 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.189 2009/11/15 02:45:35 tgl Exp $ * *------------------------------------------------------------------------- */ --- 8,14 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.190 2009/11/22 14:54:31 heikki Exp $ * *------------------------------------------------------------------------- */ *************** make_rel_from_joinlist(PlannerInfo *root *** 898,938 **** RelOptInfo * standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels) { - List **joinitems; int lev; RelOptInfo *rel; /* * 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. * ! * joinitems[j] is a list of all the j-item rels. Initially we set ! * joinitems[1] to represent all the single-jointree-item relations. */ ! joinitems = (List **) palloc0((levels_needed + 1) * sizeof(List *)); ! joinitems[1] = initial_rels; for (lev = 2; lev <= levels_needed; lev++) { ! ListCell *x; /* * 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. */ ! joinitems[lev] = join_search_one_level(root, lev, joinitems); /* * Do cleanup work on each just-processed rel. */ ! foreach(x, joinitems[lev]) { ! rel = (RelOptInfo *) lfirst(x); /* Find and save the cheapest paths for this rel */ set_cheapest(rel); --- 898,944 ---- 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); *************** standard_join_search(PlannerInfo *root, *** 946,956 **** /* * We should have a single rel at the final level. */ ! if (joinitems[levels_needed] == NIL) elog(ERROR, "failed to build any %d-way joins", levels_needed); ! Assert(list_length(joinitems[levels_needed]) == 1); ! rel = (RelOptInfo *) linitial(joinitems[levels_needed]); return rel; } --- 952,964 ---- /* * 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; }