*** pgsql/src/backend/optimizer/plan/createplan.c 2009/01/01 17:23:44 1.255 --- pgsql/src/backend/optimizer/plan/createplan.c 2009/03/21 00:04:39 1.256 *************** *** 10,16 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.254 2008/12/31 00:08:36 tgl Exp $ * *------------------------------------------------------------------------- */ --- 10,16 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.255 2009/01/01 17:23:44 momjian Exp $ * *------------------------------------------------------------------------- */ *************** static HashJoin *make_hashjoin(List *tli *** 112,118 **** List *hashclauses, Plan *lefttree, Plan *righttree, JoinType jointype); ! static Hash *make_hash(Plan *lefttree); static MergeJoin *make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, List *mergeclauses, --- 112,122 ---- List *hashclauses, Plan *lefttree, Plan *righttree, JoinType jointype); ! static Hash *make_hash(Plan *lefttree, ! Oid skewTable, ! AttrNumber skewColumn, ! Oid skewColType, ! int32 skewColTypmod); static MergeJoin *make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, List *mergeclauses, *************** create_hashjoin_plan(PlannerInfo *root, *** 1864,1869 **** --- 1868,1877 ---- List *joinclauses; List *otherclauses; List *hashclauses; + Oid skewTable = InvalidOid; + AttrNumber skewColumn = InvalidAttrNumber; + Oid skewColType = InvalidOid; + int32 skewColTypmod = -1; HashJoin *join_plan; Hash *hash_plan; *************** create_hashjoin_plan(PlannerInfo *root, *** 1903,1911 **** disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath); /* * Build the hash node and hash join node. */ ! hash_plan = make_hash(inner_plan); join_plan = make_hashjoin(tlist, joinclauses, otherclauses, --- 1911,1956 ---- disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath); /* + * If there is a single join clause and we can identify the outer + * variable as a simple column reference, supply its identity for + * possible use in skew optimization. (Note: in principle we could + * do skew optimization with multiple join clauses, but we'd have to + * be able to determine the most common combinations of outer values, + * which we don't currently have enough stats for.) + */ + if (list_length(hashclauses) == 1) + { + OpExpr *clause = (OpExpr *) linitial(hashclauses); + Node *node; + + Assert(is_opclause(clause)); + node = (Node *) linitial(clause->args); + if (IsA(node, RelabelType)) + node = (Node *) ((RelabelType *) node)->arg; + if (IsA(node, Var)) + { + Var *var = (Var *) node; + RangeTblEntry *rte; + + rte = root->simple_rte_array[var->varno]; + if (rte->rtekind == RTE_RELATION) + { + skewTable = rte->relid; + skewColumn = var->varattno; + skewColType = var->vartype; + skewColTypmod = var->vartypmod; + } + } + } + + /* * Build the hash node and hash join node. */ ! hash_plan = make_hash(inner_plan, ! skewTable, ! skewColumn, ! skewColType, ! skewColTypmod); join_plan = make_hashjoin(tlist, joinclauses, otherclauses, *************** make_hashjoin(List *tlist, *** 2713,2719 **** } static Hash * ! make_hash(Plan *lefttree) { Hash *node = makeNode(Hash); Plan *plan = &node->plan; --- 2758,2768 ---- } static Hash * ! make_hash(Plan *lefttree, ! Oid skewTable, ! AttrNumber skewColumn, ! Oid skewColType, ! int32 skewColTypmod) { Hash *node = makeNode(Hash); Plan *plan = &node->plan; *************** make_hash(Plan *lefttree) *** 2730,2735 **** --- 2779,2789 ---- plan->lefttree = lefttree; plan->righttree = NULL; + node->skewTable = skewTable; + node->skewColumn = skewColumn; + node->skewColType = skewColType; + node->skewColTypmod = skewColTypmod; + return node; }