← Back to Overview

src/backend/parser/parse_target.c

Coverage: 4/4 lines (100.0%)
Total Lines
4
modified
Covered
4
100.0%
Uncovered
0
0.0%
키보드 네비게이션
markTargetListOrigin() lines 342-430
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
342 - markTargetListOrigin(ParseState *pstate, TargetEntry *tle, -
343 - Var *var, int levelsup) -
344 - { -
345 - int netlevelsup; -
346 - RangeTblEntry *rte; -
347 - AttrNumber attnum; -
348 - -
349 - if (var == NULL || !IsA(var, Var)) -
350 - return; -
351 - netlevelsup = var->varlevelsup + levelsup; -
352 - rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup); -
353 - attnum = var->varattno; -
354 - -
355 - switch (rte->rtekind) -
356 - { -
357 - case RTE_RELATION: -
358 - /* It's a table or view, report it */ -
359 - tle->resorigtbl = rte->relid; -
360 - tle->resorigcol = attnum; -
361 - break; -
362 915 case RTE_GRAPH_TABLE: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
363 915 tle->resorigtbl = rte->relid; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
364 915 tle->resorigcol = InvalidAttrNumber; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
365 915 break; 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
366 - case RTE_SUBQUERY: -
367 - /* Subselect-in-FROM: copy up from the subselect */ -
368 - if (attnum != InvalidAttrNumber) -
369 - { -
370 - TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList, -
371 - attnum); -
372 - -
373 - if (ste == NULL || ste->resjunk) -
374 - elog(ERROR, "subquery %s does not have attribute %d", -
375 - rte->eref->aliasname, attnum); -
376 - tle->resorigtbl = ste->resorigtbl; -
377 - tle->resorigcol = ste->resorigcol; -
378 - } -
379 - break; -
380 - case RTE_JOIN: -
381 - case RTE_FUNCTION: -
382 - case RTE_VALUES: -
383 - case RTE_TABLEFUNC: -
384 - case RTE_NAMEDTUPLESTORE: -
385 - case RTE_RESULT: -
386 - /* not a simple relation, leave it unmarked */ -
387 - break; -
388 - case RTE_CTE: -
389 - -
390 - /* -
391 - * CTE reference: copy up from the subquery, if possible. If the -
392 - * RTE is a recursive self-reference then we can't do anything -
393 - * because we haven't finished analyzing it yet. However, it's no -
394 - * big loss because we must be down inside the recursive term of a -
395 - * recursive CTE, and so any markings on the current targetlist -
396 - * are not going to affect the results anyway. -
397 - */ -
398 - if (attnum != InvalidAttrNumber && !rte->self_reference) -
399 - { -
400 - CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup); -
401 - TargetEntry *ste; -
402 - List *tl = GetCTETargetList(cte); -
403 - int extra_cols = 0; -
404 - -
405 - /* -
406 - * RTE for CTE will already have the search and cycle columns -
407 - * added, but the subquery won't, so skip looking those up. -
408 - */ -
409 - if (cte->search_clause) -
410 - extra_cols += 1; -
411 - if (cte->cycle_clause) -
412 - extra_cols += 2; -
413 - if (extra_cols && -
414 - attnum > list_length(tl) && -
415 - attnum <= list_length(tl) + extra_cols) -
416 - break; -
417 - -
418 - ste = get_tle_by_resno(tl, attnum); -
419 - if (ste == NULL || ste->resjunk) -
420 - elog(ERROR, "CTE %s does not have attribute %d", -
421 - rte->eref->aliasname, attnum); -
422 - tle->resorigtbl = ste->resorigtbl; -
423 - tle->resorigcol = ste->resorigcol; -
424 - } -
425 - break; -
426 - case RTE_GROUP: -
427 - /* We couldn't get here: the RTE_GROUP RTE has not been added */ -
428 - break; -
429 - } -
430 - } -
expandRecordVariable() lines 1525-1704
Modified Lines Coverage: 0/0 lines (0.0%)
LineHitsSourceCommit
1525 - expandRecordVariable(ParseState *pstate, Var *var, int levelsup) -
1526 - { -
1527 - TupleDesc tupleDesc; -
1528 - int netlevelsup; -
1529 - RangeTblEntry *rte; -
1530 - AttrNumber attnum; -
1531 - Node *expr; -
1532 - -
1533 - /* Check my caller didn't mess up */ -
1534 - Assert(IsA(var, Var)); -
1535 - Assert(var->vartype == RECORDOID); -
1536 - -
1537 - /* -
1538 - * Note: it's tempting to use GetNSItemByRangeTablePosn here so that we -
1539 - * can use expandNSItemVars instead of expandRTE; but that does not work -
1540 - * for some of the recursion cases below, where we have consed up a -
1541 - * ParseState that lacks p_namespace data. -
1542 - */ -
1543 - netlevelsup = var->varlevelsup + levelsup; -
1544 - rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup); -
1545 - attnum = var->varattno; -
1546 - -
1547 - if (attnum == InvalidAttrNumber) -
1548 - { -
1549 - /* Whole-row reference to an RTE, so expand the known fields */ -
1550 - List *names, -
1551 - *vars; -
1552 - ListCell *lname, -
1553 - *lvar; -
1554 - int i; -
1555 - -
1556 - expandRTE(rte, var->varno, 0, var->varreturningtype, -
1557 - var->location, false, &names, &vars); -
1558 - -
1559 - tupleDesc = CreateTemplateTupleDesc(list_length(vars)); -
1560 - i = 1; -
1561 - forboth(lname, names, lvar, vars) -
1562 - { -
1563 - char *label = strVal(lfirst(lname)); -
1564 - Node *varnode = (Node *) lfirst(lvar); -
1565 - -
1566 - TupleDescInitEntry(tupleDesc, i, -
1567 - label, -
1568 - exprType(varnode), -
1569 - exprTypmod(varnode), -
1570 - 0); -
1571 - TupleDescInitEntryCollation(tupleDesc, i, -
1572 - exprCollation(varnode)); -
1573 - i++; -
1574 - } -
1575 - Assert(lname == NULL && lvar == NULL); /* lists same length? */ -
1576 - -
1577 - return tupleDesc; -
1578 - } -
1579 - -
1580 - expr = (Node *) var; /* default if we can't drill down */ -
1581 - -
1582 - switch (rte->rtekind) -
1583 - { -
1584 - case RTE_RELATION: -
1585 - case RTE_VALUES: -
1586 - case RTE_NAMEDTUPLESTORE: -
1587 - case RTE_GRAPH_TABLE: 86c14eaWIP: SQL Property Graph Queries (SQL/PGQ)
1588 - case RTE_RESULT: -
1589 - -
1590 - /* -
1591 - * This case should not occur: a column of a table, values list, -
1592 - * or ENR shouldn't have type RECORD. Fall through and fail (most -
1593 - * likely) at the bottom. -
1594 - */ -
1595 - break; -
1596 - case RTE_SUBQUERY: -
1597 - { -
1598 - /* Subselect-in-FROM: examine sub-select's output expr */ -
1599 - TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList, -
1600 - attnum); -
1601 - -
1602 - if (ste == NULL || ste->resjunk) -
1603 - elog(ERROR, "subquery %s does not have attribute %d", -
1604 - rte->eref->aliasname, attnum); -
1605 - expr = (Node *) ste->expr; -
1606 - if (IsA(expr, Var)) -
1607 - { -
1608 - /* -
1609 - * Recurse into the sub-select to see what its Var refers -
1610 - * to. We have to build an additional level of ParseState -
1611 - * to keep in step with varlevelsup in the subselect; -
1612 - * furthermore, the subquery RTE might be from an outer -
1613 - * query level, in which case the ParseState for the -
1614 - * subselect must have that outer level as parent. -
1615 - */ -
1616 - ParseState mypstate = {0}; -
1617 - Index levelsup; -
1618 - -
1619 - /* this loop must work, since GetRTEByRangeTablePosn did */ -
1620 - for (levelsup = 0; levelsup < netlevelsup; levelsup++) -
1621 - pstate = pstate->parentParseState; -
1622 - mypstate.parentParseState = pstate; -
1623 - mypstate.p_rtable = rte->subquery->rtable; -
1624 - /* don't bother filling the rest of the fake pstate */ -
1625 - -
1626 - return expandRecordVariable(&mypstate, (Var *) expr, 0); -
1627 - } -
1628 - /* else fall through to inspect the expression */ -
1629 - } -
1630 - break; -
1631 - case RTE_JOIN: -
1632 - /* Join RTE --- recursively inspect the alias variable */ -
1633 - Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars)); -
1634 - expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1); -
1635 - Assert(expr != NULL); -
1636 - /* We intentionally don't strip implicit coercions here */ -
1637 - if (IsA(expr, Var)) -
1638 - return expandRecordVariable(pstate, (Var *) expr, netlevelsup); -
1639 - /* else fall through to inspect the expression */ -
1640 - break; -
1641 - case RTE_FUNCTION: -
1642 - -
1643 - /* -
1644 - * We couldn't get here unless a function is declared with one of -
1645 - * its result columns as RECORD, which is not allowed. -
1646 - */ -
1647 - break; -
1648 - case RTE_TABLEFUNC: -
1649 - -
1650 - /* -
1651 - * Table function cannot have columns with RECORD type. -
1652 - */ -
1653 - break; -
1654 - case RTE_CTE: -
1655 - /* CTE reference: examine subquery's output expr */ -
1656 - if (!rte->self_reference) -
1657 - { -
1658 - CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup); -
1659 - TargetEntry *ste; -
1660 - -
1661 - ste = get_tle_by_resno(GetCTETargetList(cte), attnum); -
1662 - if (ste == NULL || ste->resjunk) -
1663 - elog(ERROR, "CTE %s does not have attribute %d", -
1664 - rte->eref->aliasname, attnum); -
1665 - expr = (Node *) ste->expr; -
1666 - if (IsA(expr, Var)) -
1667 - { -
1668 - /* -
1669 - * Recurse into the CTE to see what its Var refers to. We -
1670 - * have to build an additional level of ParseState to keep -
1671 - * in step with varlevelsup in the CTE; furthermore it -
1672 - * could be an outer CTE (compare SUBQUERY case above). -
1673 - */ -
1674 - ParseState mypstate = {0}; -
1675 - Index levelsup; -
1676 - -
1677 - /* this loop must work, since GetCTEForRTE did */ -
1678 - for (levelsup = 0; -
1679 - levelsup < rte->ctelevelsup + netlevelsup; -
1680 - levelsup++) -
1681 - pstate = pstate->parentParseState; -
1682 - mypstate.parentParseState = pstate; -
1683 - mypstate.p_rtable = ((Query *) cte->ctequery)->rtable; -
1684 - /* don't bother filling the rest of the fake pstate */ -
1685 - -
1686 - return expandRecordVariable(&mypstate, (Var *) expr, 0); -
1687 - } -
1688 - /* else fall through to inspect the expression */ -
1689 - } -
1690 - break; -
1691 - case RTE_GROUP: -
1692 - -
1693 - /* -
1694 - * We couldn't get here: the RTE_GROUP RTE has not been added. -
1695 - */ -
1696 - break; -
1697 - } -
1698 - -
1699 - /* -
1700 - * We now have an expression we can't expand any more, so see if -
1701 - * get_expr_result_tupdesc() can do anything with it. -
1702 - */ -
1703 - return get_expr_result_tupdesc(expr, false); -
1704 - } -