* transformSetOperationStmt - * transforms a set-operations tree * * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT * structure to it. We must transform each leaf SELECT and build up a top- * level Query that contains the leaf SELECTs as subqueries in its rangetable. * The tree of set operations is converted into the setOperations field of * the top-level Query.
| 1780 | * the top-level Query. |
| 1781 | */ |
| 1782 | static Query * |
| 1783 | transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) |
| 1784 | { |
| 1785 | Query *qry = makeNode(Query); |
| 1786 | SelectStmt *leftmostSelect; |
| 1787 | int leftmostRTI; |
| 1788 | Query *leftmostQuery; |
| 1789 | SetOperationStmt *sostmt; |
| 1790 | List *sortClause; |
| 1791 | Node *limitOffset; |
| 1792 | Node *limitCount; |
| 1793 | List *lockingClause; |
| 1794 | WithClause *withClause; |
| 1795 | Node *node; |
| 1796 | ListCell *left_tlist, |
| 1797 | *lct, |
| 1798 | *lcm, |
| 1799 | *lcc, |
| 1800 | *l; |
| 1801 | List *targetvars, |
| 1802 | *targetnames, |
| 1803 | *sv_namespace; |
| 1804 | int sv_rtable_length; |
| 1805 | ParseNamespaceItem *jnsitem; |
| 1806 | ParseNamespaceColumn *sortnscolumns; |
| 1807 | int sortcolindex; |
| 1808 | int tllen; |
| 1809 | |
| 1810 | qry->commandType = CMD_SELECT; |
| 1811 | |
| 1812 | /* |
| 1813 | * Find leftmost leaf SelectStmt. We currently only need to do this in |
| 1814 | * order to deliver a suitable error message if there's an INTO clause |
| 1815 | * there, implying the set-op tree is in a context that doesn't allow |
| 1816 | * INTO. (transformSetOperationTree would throw error anyway, but it |
| 1817 | * seems worth the trouble to throw a different error for non-leftmost |
| 1818 | * INTO, so we produce that error in transformSetOperationTree.) |
| 1819 | */ |
| 1820 | leftmostSelect = stmt->larg; |
| 1821 | while (leftmostSelect && leftmostSelect->op != SETOP_NONE) |
| 1822 | leftmostSelect = leftmostSelect->larg; |
| 1823 | Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) && |
| 1824 | leftmostSelect->larg == NULL); |
| 1825 | if (leftmostSelect->intoClause) |
| 1826 | ereport(ERROR, |
| 1827 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 1828 | errmsg("SELECT ... INTO is not allowed here"), |
| 1829 | parser_errposition(pstate, |
| 1830 | exprLocation((Node *) leftmostSelect->intoClause)))); |
| 1831 | |
| 1832 | /* |
| 1833 | * We need to extract ORDER BY and other top-level clauses here and not |
| 1834 | * let transformSetOperationTree() see them --- else it'll just recurse |
| 1835 | * right back here! |
| 1836 | */ |
| 1837 | sortClause = stmt->sortClause; |
| 1838 | limitOffset = stmt->limitOffset; |
| 1839 | limitCount = stmt->limitCount; |
no test coverage detected