| 2239 | |
| 2240 | |
| 2241 | static Node * |
| 2242 | transformSetOperationTree_internal(ParseState *pstate, SelectStmt *stmt, |
| 2243 | bool isTopLevel, setop_types_ctx *setop_types) |
| 2244 | { |
| 2245 | bool isLeaf; |
| 2246 | |
| 2247 | Assert(stmt && IsA(stmt, SelectStmt)); |
| 2248 | |
| 2249 | /* Guard against stack overflow due to overly complex set-expressions */ |
| 2250 | check_stack_depth(); |
| 2251 | |
| 2252 | /* |
| 2253 | * Validity-check both leaf and internal SELECTs for disallowed ops. |
| 2254 | */ |
| 2255 | if (stmt->intoClause) |
| 2256 | ereport(ERROR, |
| 2257 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 2258 | errmsg("INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT"), |
| 2259 | parser_errposition(pstate, |
| 2260 | exprLocation((Node *) stmt->intoClause)))); |
| 2261 | |
| 2262 | /* We don't support FOR UPDATE/SHARE with set ops at the moment. */ |
| 2263 | if (stmt->lockingClause) |
| 2264 | ereport(ERROR, |
| 2265 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 2266 | /*------ |
| 2267 | translator: %s is a SQL row locking clause such as FOR UPDATE */ |
| 2268 | errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT", |
| 2269 | LCS_asString(((LockingClause *) |
| 2270 | linitial(stmt->lockingClause))->strength)))); |
| 2271 | |
| 2272 | /* |
| 2273 | * If an internal node of a set-op tree has ORDER BY, LIMIT, FOR UPDATE, |
| 2274 | * or WITH clauses attached, we need to treat it like a leaf node to |
| 2275 | * generate an independent sub-Query tree. Otherwise, it can be |
| 2276 | * represented by a SetOperationStmt node underneath the parent Query. |
| 2277 | */ |
| 2278 | if (stmt->op == SETOP_NONE) |
| 2279 | { |
| 2280 | Assert(stmt->larg == NULL && stmt->rarg == NULL); |
| 2281 | isLeaf = true; |
| 2282 | } |
| 2283 | else |
| 2284 | { |
| 2285 | Assert(stmt->larg != NULL && stmt->rarg != NULL); |
| 2286 | if (stmt->sortClause || stmt->limitOffset || stmt->limitCount || |
| 2287 | stmt->lockingClause || stmt->withClause) |
| 2288 | isLeaf = true; |
| 2289 | else |
| 2290 | isLeaf = false; |
| 2291 | } |
| 2292 | |
| 2293 | if (isLeaf) |
| 2294 | { |
| 2295 | /* Process leaf SELECT */ |
| 2296 | Query *selectQuery; |
| 2297 | char selectName[32]; |
| 2298 | ParseNamespaceItem *nsitem; |
no test coverage detected