* transformRangeSubselect --- transform a sub-SELECT appearing in FROM */
| 545 | * transformRangeSubselect --- transform a sub-SELECT appearing in FROM |
| 546 | */ |
| 547 | static ParseNamespaceItem * |
| 548 | transformRangeSubselect(ParseState *pstate, RangeSubselect *r) |
| 549 | { |
| 550 | Query *query; |
| 551 | |
| 552 | /* |
| 553 | * We require user to supply an alias for a subselect, per SQL92. To relax |
| 554 | * this, we'd have to be prepared to gin up a unique alias for an |
| 555 | * unlabeled subselect. (This is just elog, not ereport, because the |
| 556 | * grammar should have enforced it already. It'd probably be better to |
| 557 | * report the error here, but we don't have a good error location here.) |
| 558 | */ |
| 559 | if (r->alias == NULL) |
| 560 | elog(ERROR, "subquery in FROM must have an alias"); |
| 561 | |
| 562 | /* |
| 563 | * Set p_expr_kind to show this parse level is recursing to a subselect. |
| 564 | * We can't be nested within any expression, so don't need save-restore |
| 565 | * logic here. |
| 566 | */ |
| 567 | Assert(pstate->p_expr_kind == EXPR_KIND_NONE); |
| 568 | pstate->p_expr_kind = EXPR_KIND_FROM_SUBSELECT; |
| 569 | |
| 570 | /* |
| 571 | * If the subselect is LATERAL, make lateral_only names of this level |
| 572 | * visible to it. (LATERAL can't nest within a single pstate level, so we |
| 573 | * don't need save/restore logic here.) |
| 574 | */ |
| 575 | Assert(!pstate->p_lateral_active); |
| 576 | pstate->p_lateral_active = r->lateral; |
| 577 | |
| 578 | /* |
| 579 | * Analyze and transform the subquery. |
| 580 | */ |
| 581 | query = parse_sub_analyze(r->subquery, pstate, NULL, |
| 582 | getLockedRefname(pstate, r->alias->aliasname), |
| 583 | true); |
| 584 | |
| 585 | /* Restore state */ |
| 586 | pstate->p_lateral_active = false; |
| 587 | pstate->p_expr_kind = EXPR_KIND_NONE; |
| 588 | |
| 589 | /* |
| 590 | * Check that we got a SELECT. Anything else should be impossible given |
| 591 | * restrictions of the grammar, but check anyway. |
| 592 | */ |
| 593 | if (!IsA(query, Query) || |
| 594 | query->commandType != CMD_SELECT) |
| 595 | elog(ERROR, "unexpected non-SELECT command in subquery in FROM"); |
| 596 | |
| 597 | /* |
| 598 | * OK, build an RTE and nsitem for the subquery. |
| 599 | */ |
| 600 | return addRangeTableEntryForSubquery(pstate, |
| 601 | query, |
| 602 | r->alias, |
| 603 | r->lateral, |
| 604 | true); |
no test coverage detected