* Compute columns that actually need to be stored in hashtable entries. The * incoming tuples from the child plan node will contain grouping columns, * other columns referenced in our targetlist and qual, columns used to * compute the aggregate functions, and perhaps just junk columns we don't use * at all. Only columns of the first two types need to be stored in the * hashtable, and gettin
| 1622 | * the per-query context (unlike the hash table itself). |
| 1623 | */ |
| 1624 | static void |
| 1625 | find_hash_columns(AggState *aggstate) |
| 1626 | { |
| 1627 | Bitmapset *base_colnos; |
| 1628 | Bitmapset *aggregated_colnos; |
| 1629 | TupleDesc scanDesc = aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; |
| 1630 | List *outerTlist = outerPlanState(aggstate)->plan->targetlist; |
| 1631 | int numHashes = aggstate->num_hashes; |
| 1632 | EState *estate = aggstate->ss.ps.state; |
| 1633 | int j; |
| 1634 | |
| 1635 | /* Find Vars that will be needed in tlist and qual */ |
| 1636 | find_cols(aggstate, &aggregated_colnos, &base_colnos); |
| 1637 | aggstate->colnos_needed = bms_union(base_colnos, aggregated_colnos); |
| 1638 | aggstate->max_colno_needed = 0; |
| 1639 | aggstate->all_cols_needed = true; |
| 1640 | |
| 1641 | for (int i = 0; i < scanDesc->natts; i++) |
| 1642 | { |
| 1643 | int colno = i + 1; |
| 1644 | |
| 1645 | if (bms_is_member(colno, aggstate->colnos_needed)) |
| 1646 | aggstate->max_colno_needed = colno; |
| 1647 | else |
| 1648 | aggstate->all_cols_needed = false; |
| 1649 | } |
| 1650 | |
| 1651 | for (j = 0; j < numHashes; ++j) |
| 1652 | { |
| 1653 | AggStatePerHash perhash = &aggstate->perhash[j]; |
| 1654 | Bitmapset *colnos = bms_copy(base_colnos); |
| 1655 | AttrNumber *grpColIdx = perhash->aggnode->grpColIdx; |
| 1656 | List *hashTlist = NIL; |
| 1657 | TupleDesc hashDesc; |
| 1658 | int maxCols; |
| 1659 | int i; |
| 1660 | |
| 1661 | perhash->largestGrpColIdx = 0; |
| 1662 | |
| 1663 | /* |
| 1664 | * If we're doing grouping sets, then some Vars might be referenced in |
| 1665 | * tlist/qual for the benefit of other grouping sets, but not needed |
| 1666 | * when hashing; i.e. prepare_projection_slot will null them out, so |
| 1667 | * there'd be no point storing them. Use prepare_projection_slot's |
| 1668 | * logic to determine which. |
| 1669 | */ |
| 1670 | if (aggstate->phases[0].grouped_cols) |
| 1671 | { |
| 1672 | Bitmapset *grouped_cols = aggstate->phases[0].grouped_cols[j]; |
| 1673 | ListCell *lc; |
| 1674 | |
| 1675 | foreach(lc, aggstate->all_grouped_cols) |
| 1676 | { |
| 1677 | int attnum = lfirst_int(lc); |
| 1678 | |
| 1679 | if (!bms_is_member(attnum, grouped_cols)) |
| 1680 | colnos = bms_del_member(colnos, attnum); |
| 1681 | } |
no test coverage detected