* ApplyRetrieveRule - expand an ON SELECT rule */
| 1773 | * ApplyRetrieveRule - expand an ON SELECT rule |
| 1774 | */ |
| 1775 | static Query * |
| 1776 | ApplyRetrieveRule(Query *parsetree, |
| 1777 | RewriteRule *rule, |
| 1778 | int rt_index, |
| 1779 | Relation relation, |
| 1780 | List *activeRIRs) |
| 1781 | { |
| 1782 | Query *rule_action; |
| 1783 | RangeTblEntry *rte, |
| 1784 | *subrte; |
| 1785 | RowMarkClause *rc; |
| 1786 | |
| 1787 | if (list_length(rule->actions) != 1) |
| 1788 | elog(ERROR, "expected just one rule action"); |
| 1789 | if (rule->qual != NULL) |
| 1790 | elog(ERROR, "cannot handle qualified ON SELECT rule"); |
| 1791 | |
| 1792 | if (rt_index == parsetree->resultRelation) |
| 1793 | { |
| 1794 | /* |
| 1795 | * We have a view as the result relation of the query, and it wasn't |
| 1796 | * rewritten by any rule. This case is supported if there is an |
| 1797 | * INSTEAD OF trigger that will trap attempts to insert/update/delete |
| 1798 | * view rows. The executor will check that; for the moment just plow |
| 1799 | * ahead. We have two cases: |
| 1800 | * |
| 1801 | * For INSERT, we needn't do anything. The unmodified RTE will serve |
| 1802 | * fine as the result relation. |
| 1803 | * |
| 1804 | * For UPDATE/DELETE, we need to expand the view so as to have source |
| 1805 | * data for the operation. But we also need an unmodified RTE to |
| 1806 | * serve as the target. So, copy the RTE and add the copy to the |
| 1807 | * rangetable. Note that the copy does not get added to the jointree. |
| 1808 | * Also note that there's a hack in fireRIRrules to avoid calling this |
| 1809 | * function again when it arrives at the copied RTE. |
| 1810 | */ |
| 1811 | if (parsetree->commandType == CMD_INSERT) |
| 1812 | return parsetree; |
| 1813 | else if (parsetree->commandType == CMD_UPDATE || |
| 1814 | parsetree->commandType == CMD_DELETE) |
| 1815 | { |
| 1816 | RangeTblEntry *newrte; |
| 1817 | Var *var; |
| 1818 | TargetEntry *tle; |
| 1819 | |
| 1820 | rte = rt_fetch(rt_index, parsetree->rtable); |
| 1821 | newrte = copyObject(rte); |
| 1822 | parsetree->rtable = lappend(parsetree->rtable, newrte); |
| 1823 | parsetree->resultRelation = list_length(parsetree->rtable); |
| 1824 | |
| 1825 | /* |
| 1826 | * There's no need to do permissions checks twice, so wipe out the |
| 1827 | * permissions info for the original RTE (we prefer to keep the |
| 1828 | * bits set on the result RTE). |
| 1829 | */ |
| 1830 | rte->requiredPerms = 0; |
| 1831 | rte->checkAsUser = InvalidOid; |
| 1832 | rte->selectedCols = NULL; |
no test coverage detected