* Add an entry for a CTE reference to the pstate's range table (p_rtable). * Then, construct and return a ParseNamespaceItem for the new RTE. * * This is much like addRangeTableEntry() except that it makes a CTE RTE. */
| 2468 | * This is much like addRangeTableEntry() except that it makes a CTE RTE. |
| 2469 | */ |
| 2470 | ParseNamespaceItem * |
| 2471 | addRangeTableEntryForCTE(ParseState *pstate, |
| 2472 | CommonTableExpr *cte, |
| 2473 | Index levelsup, |
| 2474 | RangeVar *rv, |
| 2475 | bool inFromCl) |
| 2476 | { |
| 2477 | RangeTblEntry *rte = makeNode(RangeTblEntry); |
| 2478 | Alias *alias = rv->alias; |
| 2479 | char *refname = alias ? alias->aliasname : cte->ctename; |
| 2480 | Alias *eref; |
| 2481 | int numaliases; |
| 2482 | int varattno; |
| 2483 | ListCell *lc; |
| 2484 | int n_dontexpand_columns = 0; |
| 2485 | ParseNamespaceItem *psi; |
| 2486 | |
| 2487 | Assert(pstate != NULL); |
| 2488 | |
| 2489 | rte->rtekind = RTE_CTE; |
| 2490 | rte->ctename = cte->ctename; |
| 2491 | rte->ctelevelsup = levelsup; |
| 2492 | |
| 2493 | /* Self-reference if and only if CTE's parse analysis isn't completed */ |
| 2494 | rte->self_reference = !IsA(cte->ctequery, Query); |
| 2495 | Assert(cte->cterecursive || !rte->self_reference); |
| 2496 | /* Bump the CTE's refcount if this isn't a self-reference */ |
| 2497 | if (!rte->self_reference) |
| 2498 | cte->cterefcount++; |
| 2499 | |
| 2500 | /* |
| 2501 | * We throw error if the CTE is INSERT/UPDATE/DELETE without RETURNING. |
| 2502 | * This won't get checked in case of a self-reference, but that's OK |
| 2503 | * because data-modifying CTEs aren't allowed to be recursive anyhow. |
| 2504 | */ |
| 2505 | if (IsA(cte->ctequery, Query)) |
| 2506 | { |
| 2507 | Query *ctequery = (Query *) cte->ctequery; |
| 2508 | |
| 2509 | if (ctequery->commandType != CMD_SELECT && |
| 2510 | ctequery->returningList == NIL) |
| 2511 | ereport(ERROR, |
| 2512 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 2513 | errmsg("WITH query \"%s\" does not have a RETURNING clause", |
| 2514 | cte->ctename), |
| 2515 | parser_errposition(pstate, rv->location))); |
| 2516 | } |
| 2517 | |
| 2518 | rte->coltypes = list_copy(cte->ctecoltypes); |
| 2519 | rte->coltypmods = list_copy(cte->ctecoltypmods); |
| 2520 | rte->colcollations = list_copy(cte->ctecolcollations); |
| 2521 | |
| 2522 | rte->alias = alias; |
| 2523 | if (alias) |
| 2524 | eref = copyObject(alias); |
| 2525 | else |
| 2526 | eref = makeAlias(refname, NIL); |
| 2527 | numaliases = list_length(eref->colnames); |
no test coverage detected