* Given a bitmapqual tree, generate the Plan tree that implements it * * As byproducts, we also return in *qual and *indexqual the qual lists * (in implicit-AND form, without RestrictInfos) describing the original index * conditions and the generated indexqual conditions. (These are the same in * simple cases, but when special index operators are involved, the former * list includes the spe
| 4041 | * messy, since we'd have to build new RestrictInfos in many cases.) |
| 4042 | */ |
| 4043 | static Plan * |
| 4044 | create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, |
| 4045 | List **qual, List **indexqual, List **indexECs) |
| 4046 | { |
| 4047 | Plan *plan; |
| 4048 | |
| 4049 | if (IsA(bitmapqual, BitmapAndPath)) |
| 4050 | { |
| 4051 | BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; |
| 4052 | List *subplans = NIL; |
| 4053 | List *subquals = NIL; |
| 4054 | List *subindexquals = NIL; |
| 4055 | List *subindexECs = NIL; |
| 4056 | ListCell *l; |
| 4057 | double numsegments; |
| 4058 | |
| 4059 | if (apath->path.parent->cdbpolicy && apath->path.parent->cdbpolicy->ptype == POLICYTYPE_PARTITIONED) |
| 4060 | numsegments = apath->path.parent->cdbpolicy->numsegments; |
| 4061 | else |
| 4062 | numsegments = 1; |
| 4063 | |
| 4064 | /* |
| 4065 | * There may well be redundant quals among the subplans, since a |
| 4066 | * top-level WHERE qual might have gotten used to form several |
| 4067 | * different index quals. We don't try exceedingly hard to eliminate |
| 4068 | * redundancies, but we do eliminate obvious duplicates by using |
| 4069 | * list_concat_unique. |
| 4070 | */ |
| 4071 | foreach(l, apath->bitmapquals) |
| 4072 | { |
| 4073 | Plan *subplan; |
| 4074 | List *subqual; |
| 4075 | List *subindexqual; |
| 4076 | List *subindexEC; |
| 4077 | |
| 4078 | subplan = create_bitmap_subplan(root, (Path *) lfirst(l), |
| 4079 | &subqual, &subindexqual, |
| 4080 | &subindexEC); |
| 4081 | subplans = lappend(subplans, subplan); |
| 4082 | subquals = list_concat_unique(subquals, subqual); |
| 4083 | subindexquals = list_concat_unique(subindexquals, subindexqual); |
| 4084 | /* Duplicates in indexECs aren't worth getting rid of */ |
| 4085 | subindexECs = list_concat(subindexECs, subindexEC); |
| 4086 | } |
| 4087 | plan = (Plan *) make_bitmap_and(subplans); |
| 4088 | plan->startup_cost = apath->path.startup_cost; |
| 4089 | plan->total_cost = apath->path.total_cost; |
| 4090 | plan->plan_rows = |
| 4091 | clamp_row_est(apath->bitmapselectivity * apath->path.parent->tuples / numsegments); |
| 4092 | plan->plan_width = 0; /* meaningless */ |
| 4093 | plan->parallel_aware = false; |
| 4094 | plan->parallel_safe = apath->path.parallel_safe; |
| 4095 | *qual = subquals; |
| 4096 | *indexqual = subindexquals; |
| 4097 | *indexECs = subindexECs; |
| 4098 | } |
| 4099 | else if (IsA(bitmapqual, BitmapOrPath)) |
| 4100 | { |
no test coverage detected