PostgreSQL Source Code git master
Loading...
Searching...
No Matches
parse_relation.h File Reference
Include dependency graph for parse_relation.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ParseNamespaceItemrefnameNamespaceItem (ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
 
CommonTableExprscanNameSpaceForCTE (ParseState *pstate, const char *refname, Index *ctelevelsup)
 
bool scanNameSpaceForENR (ParseState *pstate, const char *refname)
 
void checkNameSpaceConflicts (ParseState *pstate, List *namespace1, List *namespace2)
 
ParseNamespaceItemGetNSItemByRangeTablePosn (ParseState *pstate, int varno, int sublevels_up)
 
ParseNamespaceItemGetNSItemByVar (ParseState *pstate, Var *var)
 
RangeTblEntryGetRTEByRangeTablePosn (ParseState *pstate, int varno, int sublevels_up)
 
CommonTableExprGetCTEForRTE (ParseState *pstate, RangeTblEntry *rte, int rtelevelsup)
 
NodescanNSItemForColumn (ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, const char *colname, int location)
 
NodecolNameToVar (ParseState *pstate, const char *colname, bool localonly, int location)
 
void markNullableIfNeeded (ParseState *pstate, Var *var)
 
void markVarForSelectPriv (ParseState *pstate, Var *var)
 
Relation parserOpenTable (ParseState *pstate, const RangeVar *relation, LOCKMODE lockmode)
 
ParseNamespaceItemaddRangeTableEntry (ParseState *pstate, RangeVar *relation, Alias *alias, bool inh, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForRelation (ParseState *pstate, Relation rel, LOCKMODE lockmode, Alias *alias, bool inh, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForSubquery (ParseState *pstate, Query *subquery, Alias *alias, bool lateral, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForFunction (ParseState *pstate, List *funcnames, List *funcexprs, List *coldeflists, RangeFunction *rangefunc, bool lateral, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForValues (ParseState *pstate, List *exprs, List *coltypes, List *coltypmods, List *colcollations, Alias *alias, bool lateral, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForTableFunc (ParseState *pstate, TableFunc *tf, Alias *alias, bool lateral, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForGraphTable (ParseState *pstate, Oid graphid, GraphPattern *graph_pattern, List *columns, List *colnames, Alias *alias, bool lateral, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForJoin (ParseState *pstate, List *colnames, ParseNamespaceColumn *nscolumns, JoinType jointype, int nummergedcols, List *aliasvars, List *leftcols, List *rightcols, Alias *join_using_alias, Alias *alias, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForCTE (ParseState *pstate, CommonTableExpr *cte, Index levelsup, RangeVar *rv, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForENR (ParseState *pstate, RangeVar *rv, bool inFromCl)
 
ParseNamespaceItemaddRangeTableEntryForGroup (ParseState *pstate, List *groupClauses)
 
RTEPermissionInfoaddRTEPermissionInfo (List **rteperminfos, RangeTblEntry *rte)
 
RTEPermissionInfogetRTEPermissionInfo (List *rteperminfos, RangeTblEntry *rte)
 
bool isLockedRefname (ParseState *pstate, const char *refname)
 
void addNSItemToQuery (ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace)
 
pg_noreturn void errorMissingRTE (ParseState *pstate, RangeVar *relation)
 
pg_noreturn void errorMissingColumn (ParseState *pstate, const char *relname, const char *colname, int location)
 
void expandRTE (RangeTblEntry *rte, int rtindex, int sublevels_up, VarReturningType returning_type, int location, bool include_dropped, List **colnames, List **colvars)
 
ListexpandNSItemVars (ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location, List **colnames)
 
ListexpandNSItemAttrs (ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, bool require_col_privs, int location)
 
int attnameAttNum (Relation rd, const char *attname, bool sysColOK)
 
const NameDataattnumAttName (Relation rd, int attid)
 
Oid attnumTypeId (Relation rd, int attid)
 
Oid attnumCollationId (Relation rd, int attid)
 

Function Documentation

◆ addNSItemToQuery()

void addNSItemToQuery ( ParseState pstate,
ParseNamespaceItem nsitem,
bool  addToJoinList,
bool  addToRelNameSpace,
bool  addToVarNameSpace 
)
extern

Definition at line 2825 of file parse_relation.c.

2828{
2829 if (addToJoinList)
2830 {
2832
2833 rtr->rtindex = nsitem->p_rtindex;
2834 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
2835 }
2837 {
2838 /* Set the new nsitem's visibility flags correctly */
2839 nsitem->p_rel_visible = addToRelNameSpace;
2840 nsitem->p_cols_visible = addToVarNameSpace;
2841 nsitem->p_lateral_only = false;
2842 nsitem->p_lateral_ok = true;
2843 pstate->p_namespace = lappend(pstate->p_namespace, nsitem);
2844 }
2845}
List * lappend(List *list, void *datum)
Definition list.c:339
#define makeNode(_type_)
Definition nodes.h:159
static int fb(int x)
List * p_namespace
Definition parse_node.h:222
List * p_joinlist
Definition parse_node.h:220

References fb(), lappend(), makeNode, ParseState::p_joinlist, and ParseState::p_namespace.

Referenced by addNSItemForReturning(), AddRelationNewConstraints(), AlterPolicy(), CreatePolicy(), CreateTriggerFiringOn(), DefineRelation(), DoCopy(), insert_property_records(), setTargetTable(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), transformAlterTableStmt(), transformIndexStmt(), transformInsertStmt(), transformMergeStmt(), transformOnConflictClause(), transformPartitionSpec(), TransformPubWhereClauses(), transformRuleStmt(), transformSetOperationStmt(), transformStatsStmt(), and transformValuesClause().

◆ addRangeTableEntry()

ParseNamespaceItem * addRangeTableEntry ( ParseState pstate,
RangeVar relation,
Alias alias,
bool  inh,
bool  inFromCl 
)
extern

Definition at line 1511 of file parse_relation.c.

1516{
1519 char *refname = alias ? alias->aliasname : relation->relname;
1520 LOCKMODE lockmode;
1521 Relation rel;
1523
1524 Assert(pstate != NULL);
1525
1526 rte->rtekind = RTE_RELATION;
1527 rte->alias = alias;
1528
1529 /*
1530 * Identify the type of lock we'll need on this relation. It's not the
1531 * query's target table (that case is handled elsewhere), so we need
1532 * either RowShareLock if it's locked by FOR UPDATE/SHARE, or plain
1533 * AccessShareLock otherwise.
1534 */
1535 lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock;
1536
1537 /*
1538 * Get the rel's OID. This access also ensures that we have an up-to-date
1539 * relcache entry for the rel. Since this is typically the first access
1540 * to a rel in a statement, we must open the rel with the proper lockmode.
1541 */
1542 rel = parserOpenTable(pstate, relation, lockmode);
1543 rte->relid = RelationGetRelid(rel);
1544 rte->inh = inh;
1545 rte->relkind = rel->rd_rel->relkind;
1546 rte->rellockmode = lockmode;
1547
1548 /*
1549 * Build the list of effective column names using user-supplied aliases
1550 * and/or actual column names.
1551 */
1552 rte->eref = makeAlias(refname, NIL);
1553 buildRelationAliases(rel->rd_att, alias, rte->eref);
1554
1555 /*
1556 * Set flags and initialize access permissions.
1557 *
1558 * The initial default on access checks is always check-for-READ-access,
1559 * which is the right thing for all except target tables.
1560 */
1561 rte->lateral = false;
1562 rte->inFromCl = inFromCl;
1563
1565 perminfo->requiredPerms = ACL_SELECT;
1566
1567 /*
1568 * Add completed RTE to pstate's range table list, so that we know its
1569 * index. But we don't add it to the join list --- caller must do that if
1570 * appropriate.
1571 */
1572 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1573
1574 /*
1575 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
1576 * list --- caller must do that if appropriate.
1577 */
1579 perminfo, rel->rd_att);
1580
1581 /*
1582 * Drop the rel refcount, but keep the access lock till end of transaction
1583 * so that the table can't be deleted or have its schema modified
1584 * underneath us.
1585 */
1586 table_close(rel, NoLock);
1587
1588 return nsitem;
1589}
#define Assert(condition)
Definition c.h:943
int LOCKMODE
Definition lockdefs.h:26
#define NoLock
Definition lockdefs.h:34
#define AccessShareLock
Definition lockdefs.h:36
#define RowShareLock
Definition lockdefs.h:37
Alias * makeAlias(const char *aliasname, List *colnames)
Definition makefuncs.c:438
Relation parserOpenTable(ParseState *pstate, const RangeVar *relation, LOCKMODE lockmode)
static ParseNamespaceItem * buildNSItemFromTupleDesc(RangeTblEntry *rte, Index rtindex, RTEPermissionInfo *perminfo, TupleDesc tupdesc)
bool isLockedRefname(ParseState *pstate, const char *refname)
RTEPermissionInfo * addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)
static void buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
@ RTE_RELATION
#define ACL_SELECT
Definition parsenodes.h:77
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define RelationGetRelid(relation)
Definition rel.h:516
char * aliasname
Definition primnodes.h:52
List * p_rteperminfos
Definition parse_node.h:216
List * p_rtable
Definition parse_node.h:215
char * relname
Definition primnodes.h:84
TupleDesc rd_att
Definition rel.h:112
Form_pg_class rd_rel
Definition rel.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126

References AccessShareLock, ACL_SELECT, addRTEPermissionInfo(), Alias::aliasname, Assert, buildNSItemFromTupleDesc(), buildRelationAliases(), fb(), isLockedRefname(), lappend(), list_length(), makeAlias(), makeNode, NIL, NoLock, ParseState::p_rtable, ParseState::p_rteperminfos, parserOpenTable(), RelationData::rd_att, RelationData::rd_rel, RelationGetRelid, RangeVar::relname, RowShareLock, RTE_RELATION, and table_close().

Referenced by transformTableEntry().

◆ addRangeTableEntryForCTE()

ParseNamespaceItem * addRangeTableEntryForCTE ( ParseState pstate,
CommonTableExpr cte,
Index  levelsup,
RangeVar rv,
bool  inFromCl 
)
extern

Definition at line 2447 of file parse_relation.c.

2452{
2454 Alias *alias = rv->alias;
2455 char *refname = alias ? alias->aliasname : cte->ctename;
2456 Alias *eref;
2457 int numaliases;
2458 int varattno;
2459 ListCell *lc;
2460 int n_dontexpand_columns = 0;
2462
2463 Assert(pstate != NULL);
2464
2465 rte->rtekind = RTE_CTE;
2466 rte->ctename = cte->ctename;
2467 rte->ctelevelsup = levelsup;
2468
2469 /* Self-reference if and only if CTE's parse analysis isn't completed */
2470 rte->self_reference = !IsA(cte->ctequery, Query);
2471 Assert(cte->cterecursive || !rte->self_reference);
2472 /* Bump the CTE's refcount if this isn't a self-reference */
2473 if (!rte->self_reference)
2474 cte->cterefcount++;
2475
2476 /*
2477 * We throw error if the CTE is INSERT/UPDATE/DELETE/MERGE without
2478 * RETURNING. This won't get checked in case of a self-reference, but
2479 * that's OK because data-modifying CTEs aren't allowed to be recursive
2480 * anyhow.
2481 */
2482 if (IsA(cte->ctequery, Query))
2483 {
2484 Query *ctequery = (Query *) cte->ctequery;
2485
2486 if (ctequery->commandType != CMD_SELECT &&
2487 ctequery->returningList == NIL)
2488 ereport(ERROR,
2490 errmsg("WITH query \"%s\" does not have a RETURNING clause",
2491 cte->ctename),
2492 parser_errposition(pstate, rv->location)));
2493 }
2494
2495 rte->coltypes = list_copy(cte->ctecoltypes);
2496 rte->coltypmods = list_copy(cte->ctecoltypmods);
2497 rte->colcollations = list_copy(cte->ctecolcollations);
2498
2499 rte->alias = alias;
2500 if (alias)
2501 eref = copyObject(alias);
2502 else
2503 eref = makeAlias(refname, NIL);
2504 numaliases = list_length(eref->colnames);
2505
2506 /* fill in any unspecified alias columns */
2507 varattno = 0;
2508 foreach(lc, cte->ctecolnames)
2509 {
2510 varattno++;
2511 if (varattno > numaliases)
2512 eref->colnames = lappend(eref->colnames, lfirst(lc));
2513 }
2514 if (varattno < numaliases)
2515 ereport(ERROR,
2517 errmsg("table \"%s\" has %d columns available but %d columns specified",
2518 refname, varattno, numaliases)));
2519
2520 rte->eref = eref;
2521
2522 if (cte->search_clause)
2523 {
2524 rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->search_clause->search_seq_column));
2525 if (cte->search_clause->search_breadth_first)
2526 rte->coltypes = lappend_oid(rte->coltypes, RECORDOID);
2527 else
2528 rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID);
2529 rte->coltypmods = lappend_int(rte->coltypmods, -1);
2530 rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
2531
2533 }
2534
2535 if (cte->cycle_clause)
2536 {
2537 rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column));
2538 rte->coltypes = lappend_oid(rte->coltypes, cte->cycle_clause->cycle_mark_type);
2539 rte->coltypmods = lappend_int(rte->coltypmods, cte->cycle_clause->cycle_mark_typmod);
2540 rte->colcollations = lappend_oid(rte->colcollations, cte->cycle_clause->cycle_mark_collation);
2541
2542 rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_path_column));
2543 rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID);
2544 rte->coltypmods = lappend_int(rte->coltypmods, -1);
2545 rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
2546
2548 }
2549
2550 /*
2551 * Set flags and access permissions.
2552 *
2553 * Subqueries are never checked for access rights, so no need to perform
2554 * addRTEPermissionInfo().
2555 */
2556 rte->lateral = false;
2557 rte->inFromCl = inFromCl;
2558
2559 /*
2560 * Add completed RTE to pstate's range table list, so that we know its
2561 * index. But we don't add it to the join list --- caller must do that if
2562 * appropriate.
2563 */
2564 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2565
2566 /*
2567 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2568 * list --- caller must do that if appropriate.
2569 */
2571 rte->coltypes, rte->coltypmods,
2572 rte->colcollations);
2573
2574 /*
2575 * The columns added by search and cycle clauses are not included in star
2576 * expansion in queries contained in the CTE.
2577 */
2578 if (rte->ctelevelsup > 0)
2579 for (int i = 0; i < n_dontexpand_columns; i++)
2580 psi->p_nscolumns[list_length(psi->p_names->colnames) - 1 - i].p_dontexpand = true;
2581
2582 return psi;
2583}
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
int i
Definition isn.c:77
List * list_copy(const List *oldlist)
Definition list.c:1573
List * lappend_int(List *list, int datum)
Definition list.c:357
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
#define IsA(nodeptr, _type_)
Definition nodes.h:162
#define copyObject(obj)
Definition nodes.h:230
@ CMD_SELECT
Definition nodes.h:273
static char * errmsg
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
static ParseNamespaceItem * buildNSItemFromLists(RangeTblEntry *rte, Index rtindex, List *coltypes, List *coltypmods, List *colcollations)
@ RTE_CTE
#define lfirst(lc)
Definition pg_list.h:172
#define InvalidOid
Alias * alias
Definition primnodes.h:93
ParseLoc location
Definition primnodes.h:96
String * makeString(char *str)
Definition value.c:63

References RangeVar::alias, Alias::aliasname, Assert, buildNSItemFromLists(), CMD_SELECT, Query::commandType, copyObject, CommonTableExpr::ctename, CommonTableExpr::ctequery, ereport, errcode(), errmsg, ERROR, fb(), i, InvalidOid, IsA, lappend(), lappend_int(), lappend_oid(), lfirst, list_copy(), list_length(), RangeVar::location, makeAlias(), makeNode, makeString(), NIL, ParseState::p_rtable, parser_errposition(), Query::returningList, and RTE_CTE.

Referenced by getNSItemForSpecialRelationTypes().

◆ addRangeTableEntryForENR()

ParseNamespaceItem * addRangeTableEntryForENR ( ParseState pstate,
RangeVar rv,
bool  inFromCl 
)
extern

Definition at line 2599 of file parse_relation.c.

2602{
2604 Alias *alias = rv->alias;
2605 char *refname = alias ? alias->aliasname : rv->relname;
2607 TupleDesc tupdesc;
2608 int attno;
2609
2610 Assert(pstate != NULL);
2611 enrmd = get_visible_ENR(pstate, rv->relname);
2612 Assert(enrmd != NULL);
2613
2614 switch (enrmd->enrtype)
2615 {
2617 rte->rtekind = RTE_NAMEDTUPLESTORE;
2618 break;
2619
2620 default:
2621 elog(ERROR, "unexpected enrtype: %d", enrmd->enrtype);
2622 return NULL; /* for fussy compilers */
2623 }
2624
2625 /*
2626 * Record dependency on a relation. This allows plans to be invalidated
2627 * if they access transition tables linked to a table that is altered.
2628 */
2629 rte->relid = enrmd->reliddesc;
2630
2631 /*
2632 * Build the list of effective column names using user-supplied aliases
2633 * and/or actual column names.
2634 */
2635 tupdesc = ENRMetadataGetTupDesc(enrmd);
2636 rte->eref = makeAlias(refname, NIL);
2637 buildRelationAliases(tupdesc, alias, rte->eref);
2638
2639 /* Record additional data for ENR, including column type info */
2640 rte->enrname = enrmd->name;
2641 rte->enrtuples = enrmd->enrtuples;
2642 rte->coltypes = NIL;
2643 rte->coltypmods = NIL;
2644 rte->colcollations = NIL;
2645 for (attno = 1; attno <= tupdesc->natts; ++attno)
2646 {
2647 Form_pg_attribute att = TupleDescAttr(tupdesc, attno - 1);
2648
2649 if (att->attisdropped)
2650 {
2651 /* Record zeroes for a dropped column */
2652 rte->coltypes = lappend_oid(rte->coltypes, InvalidOid);
2653 rte->coltypmods = lappend_int(rte->coltypmods, 0);
2654 rte->colcollations = lappend_oid(rte->colcollations, InvalidOid);
2655 }
2656 else
2657 {
2658 /* Let's just make sure we can tell this isn't dropped */
2659 if (att->atttypid == InvalidOid)
2660 elog(ERROR, "atttypid is invalid for non-dropped column in \"%s\"",
2661 rv->relname);
2662 rte->coltypes = lappend_oid(rte->coltypes, att->atttypid);
2663 rte->coltypmods = lappend_int(rte->coltypmods, att->atttypmod);
2664 rte->colcollations = lappend_oid(rte->colcollations,
2665 att->attcollation);
2666 }
2667 }
2668
2669 /*
2670 * Set flags and access permissions.
2671 *
2672 * ENRs are never checked for access rights, so no need to perform
2673 * addRTEPermissionInfo().
2674 */
2675 rte->lateral = false;
2676 rte->inFromCl = inFromCl;
2677
2678 /*
2679 * Add completed RTE to pstate's range table list, so that we know its
2680 * index. But we don't add it to the join list --- caller must do that if
2681 * appropriate.
2682 */
2683 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2684
2685 /*
2686 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2687 * list --- caller must do that if appropriate.
2688 */
2690 tupdesc);
2691}
#define elog(elevel,...)
Definition elog.h:228
EphemeralNamedRelationMetadata get_visible_ENR(ParseState *pstate, const char *refname)
Definition parse_enr.c:26
@ RTE_NAMEDTUPLESTORE
FormData_pg_attribute * Form_pg_attribute
TupleDesc ENRMetadataGetTupDesc(EphemeralNamedRelationMetadata enrmd)
@ ENR_NAMED_TUPLESTORE
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178

References RangeVar::alias, Alias::aliasname, Assert, buildNSItemFromTupleDesc(), buildRelationAliases(), elog, ENR_NAMED_TUPLESTORE, ENRMetadataGetTupDesc(), ERROR, fb(), get_visible_ENR(), InvalidOid, lappend(), lappend_int(), lappend_oid(), list_length(), makeAlias(), makeNode, TupleDescData::natts, NIL, ParseState::p_rtable, RangeVar::relname, RTE_NAMEDTUPLESTORE, and TupleDescAttr().

Referenced by getNSItemForSpecialRelationTypes().

◆ addRangeTableEntryForFunction()

ParseNamespaceItem * addRangeTableEntryForFunction ( ParseState pstate,
List funcnames,
List funcexprs,
List coldeflists,
RangeFunction rangefunc,
bool  lateral,
bool  inFromCl 
)
extern

Definition at line 1771 of file parse_relation.c.

1778{
1780 Alias *alias = rangefunc->alias;
1781 Alias *eref;
1782 char *aliasname;
1783 int nfuncs = list_length(funcexprs);
1785 TupleDesc tupdesc;
1786 ListCell *lc1,
1787 *lc2,
1788 *lc3;
1789 int i;
1790 int j;
1791 int funcno;
1792 int natts,
1793 totalatts;
1794
1795 Assert(pstate != NULL);
1796
1797 rte->rtekind = RTE_FUNCTION;
1798 rte->relid = InvalidOid;
1799 rte->subquery = NULL;
1800 rte->functions = NIL; /* we'll fill this list below */
1801 rte->funcordinality = rangefunc->ordinality;
1802 rte->alias = alias;
1803
1804 /*
1805 * Choose the RTE alias name. We default to using the first function's
1806 * name even when there's more than one; which is maybe arguable but beats
1807 * using something constant like "table".
1808 */
1809 if (alias)
1810 aliasname = alias->aliasname;
1811 else
1812 aliasname = linitial(funcnames);
1813
1814 eref = makeAlias(aliasname, NIL);
1815 rte->eref = eref;
1816
1817 /* Process each function ... */
1819
1820 totalatts = 0;
1821 funcno = 0;
1823 {
1824 Node *funcexpr = (Node *) lfirst(lc1);
1825 char *funcname = (char *) lfirst(lc2);
1826 List *coldeflist = (List *) lfirst(lc3);
1830
1831 /* Initialize RangeTblFunction node */
1832 rtfunc->funcexpr = funcexpr;
1833 rtfunc->funccolnames = NIL;
1834 rtfunc->funccoltypes = NIL;
1835 rtfunc->funccoltypmods = NIL;
1836 rtfunc->funccolcollations = NIL;
1837 rtfunc->funcparams = NULL; /* not set until planning */
1838
1839 /*
1840 * Now determine if the function returns a simple or composite type.
1841 */
1843 &funcrettype,
1844 &tupdesc);
1845
1846 /*
1847 * A coldeflist is required if the function returns RECORD and hasn't
1848 * got a predetermined record type, and is prohibited otherwise. This
1849 * can be a bit confusing, so we expend some effort on delivering a
1850 * relevant error message.
1851 */
1852 if (coldeflist != NIL)
1853 {
1854 switch (functypclass)
1855 {
1856 case TYPEFUNC_RECORD:
1857 /* ok */
1858 break;
1859 case TYPEFUNC_COMPOSITE:
1861
1862 /*
1863 * If the function's raw result type is RECORD, we must
1864 * have resolved it using its OUT parameters. Otherwise,
1865 * it must have a named composite type.
1866 */
1867 if (exprType(funcexpr) == RECORDOID)
1868 ereport(ERROR,
1870 errmsg("a column definition list is redundant for a function with OUT parameters"),
1871 parser_errposition(pstate,
1872 exprLocation((Node *) coldeflist))));
1873 else
1874 ereport(ERROR,
1876 errmsg("a column definition list is redundant for a function returning a named composite type"),
1877 parser_errposition(pstate,
1878 exprLocation((Node *) coldeflist))));
1879 break;
1880 default:
1881 ereport(ERROR,
1883 errmsg("a column definition list is only allowed for functions returning \"record\""),
1884 parser_errposition(pstate,
1885 exprLocation((Node *) coldeflist))));
1886 break;
1887 }
1888 }
1889 else
1890 {
1892 ereport(ERROR,
1894 errmsg("a column definition list is required for functions returning \"record\""),
1895 parser_errposition(pstate, exprLocation(funcexpr))));
1896 }
1897
1900 {
1901 /* Composite data type, e.g. a table's row type */
1902 Assert(tupdesc);
1903 }
1904 else if (functypclass == TYPEFUNC_SCALAR)
1905 {
1906 /* Base data type, i.e. scalar */
1907 tupdesc = CreateTemplateTupleDesc(1);
1908 TupleDescInitEntry(tupdesc,
1909 (AttrNumber) 1,
1911 alias, nfuncs),
1913 exprTypmod(funcexpr),
1914 0);
1916 (AttrNumber) 1,
1917 exprCollation(funcexpr));
1918 TupleDescFinalize(tupdesc);
1919 }
1920 else if (functypclass == TYPEFUNC_RECORD)
1921 {
1922 ListCell *col;
1923
1924 /*
1925 * Use the column definition list to construct a tupdesc and fill
1926 * in the RangeTblFunction's lists. Limit number of columns to
1927 * MaxHeapAttributeNumber, because CheckAttributeNamesTypes will.
1928 */
1929 if (list_length(coldeflist) > MaxHeapAttributeNumber)
1930 ereport(ERROR,
1932 errmsg("column definition lists can have at most %d entries",
1934 parser_errposition(pstate,
1935 exprLocation((Node *) coldeflist))));
1936 tupdesc = CreateTemplateTupleDesc(list_length(coldeflist));
1937 i = 1;
1938 foreach(col, coldeflist)
1939 {
1940 ColumnDef *n = (ColumnDef *) lfirst(col);
1941 char *attrname;
1942 Oid attrtype;
1943 int32 attrtypmod;
1945
1946 attrname = n->colname;
1947 if (n->typeName->setof)
1948 ereport(ERROR,
1950 errmsg("column \"%s\" cannot be declared SETOF",
1951 attrname),
1952 parser_errposition(pstate, n->location)));
1953 typenameTypeIdAndMod(pstate, n->typeName,
1954 &attrtype, &attrtypmod);
1955 attrcollation = GetColumnDefCollation(pstate, n, attrtype);
1956 TupleDescInitEntry(tupdesc,
1957 (AttrNumber) i,
1958 attrname,
1959 attrtype,
1960 attrtypmod,
1961 0);
1963 (AttrNumber) i,
1965 rtfunc->funccolnames = lappend(rtfunc->funccolnames,
1967 rtfunc->funccoltypes = lappend_oid(rtfunc->funccoltypes,
1968 attrtype);
1969 rtfunc->funccoltypmods = lappend_int(rtfunc->funccoltypmods,
1970 attrtypmod);
1971 rtfunc->funccolcollations = lappend_oid(rtfunc->funccolcollations,
1973
1974 i++;
1975 }
1976 TupleDescFinalize(tupdesc);
1977
1978 /*
1979 * Ensure that the coldeflist defines a legal set of names (no
1980 * duplicates, but we needn't worry about system column names) and
1981 * datatypes. Although we mostly can't allow pseudo-types, it
1982 * seems safe to allow RECORD and RECORD[], since values within
1983 * those type classes are self-identifying at runtime, and the
1984 * coldeflist doesn't represent anything that will be visible to
1985 * other sessions.
1986 */
1989 }
1990 else
1991 ereport(ERROR,
1993 errmsg("function \"%s\" in FROM has unsupported return type %s",
1995 parser_errposition(pstate, exprLocation(funcexpr))));
1996
1997 /* Finish off the RangeTblFunction and add it to the RTE's list */
1998 rtfunc->funccolcount = tupdesc->natts;
1999 rte->functions = lappend(rte->functions, rtfunc);
2000
2001 /* Save the tupdesc for use below */
2002 functupdescs[funcno] = tupdesc;
2003 totalatts += tupdesc->natts;
2004 funcno++;
2005 }
2006
2007 /*
2008 * If there's more than one function, or we want an ordinality column, we
2009 * have to produce a merged tupdesc.
2010 */
2011 if (nfuncs > 1 || rangefunc->ordinality)
2012 {
2013 if (rangefunc->ordinality)
2014 totalatts++;
2015
2016 /* Disallow more columns than will fit in a tuple */
2018 ereport(ERROR,
2020 errmsg("functions in FROM can return at most %d columns",
2022 parser_errposition(pstate,
2023 exprLocation((Node *) funcexprs))));
2024
2025 /* Merge the tuple descs of each function into a composite one */
2027 natts = 0;
2028 for (i = 0; i < nfuncs; i++)
2029 {
2030 for (j = 1; j <= functupdescs[i]->natts; j++)
2031 TupleDescCopyEntry(tupdesc, ++natts, functupdescs[i], j);
2032 }
2033
2034 /* Add the ordinality column if needed */
2035 if (rangefunc->ordinality)
2036 {
2037 TupleDescInitEntry(tupdesc,
2038 (AttrNumber) ++natts,
2039 "ordinality",
2040 INT8OID,
2041 -1,
2042 0);
2043 /* no need to set collation */
2044 }
2045 TupleDescFinalize(tupdesc);
2046 Assert(natts == totalatts);
2047 }
2048 else
2049 {
2050 /* We can just use the single function's tupdesc as-is */
2051 tupdesc = functupdescs[0];
2052 }
2053
2054 /* Use the tupdesc while assigning column aliases for the RTE */
2055 buildRelationAliases(tupdesc, alias, eref);
2056
2057 /*
2058 * Set flags and access permissions.
2059 *
2060 * Functions are never checked for access rights (at least, not by
2061 * ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
2062 */
2063 rte->lateral = lateral;
2064 rte->inFromCl = inFromCl;
2065
2066 /*
2067 * Add completed RTE to pstate's range table list, so that we know its
2068 * index. But we don't add it to the join list --- caller must do that if
2069 * appropriate.
2070 */
2071 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2072
2073 /*
2074 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2075 * list --- caller must do that if appropriate.
2076 */
2078 tupdesc);
2079}
int16 AttrNumber
Definition attnum.h:21
int32_t int32
Definition c.h:620
#define palloc_array(type, count)
Definition fe_memutils.h:91
char * format_type_be(Oid type_oid)
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:299
TypeFuncClass
Definition funcapi.h:147
@ TYPEFUNC_SCALAR
Definition funcapi.h:148
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
@ TYPEFUNC_RECORD
Definition funcapi.h:151
@ TYPEFUNC_COMPOSITE_DOMAIN
Definition funcapi.h:150
void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, int flags)
Definition heap.c:453
#define CHKATYPE_ANYRECORD
Definition heap.h:24
#define MaxTupleAttributeNumber
#define MaxHeapAttributeNumber
#define funcname
int j
Definition isn.c:78
char * pstrdup(const char *in)
Definition mcxt.c:1910
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
Oid exprCollation(const Node *expr)
Definition nodeFuncs.c:826
int exprLocation(const Node *expr)
Definition nodeFuncs.c:1403
static char * chooseScalarFunctionAlias(Node *funcexpr, char *funcname, Alias *alias, int nfuncs)
void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p)
Definition parse_type.c:310
Oid GetColumnDefCollation(ParseState *pstate, const ColumnDef *coldef, Oid typeOid)
Definition parse_type.c:540
@ RTE_FUNCTION
#define forthree(cell1, list1, cell2, list2, cell3, list3)
Definition pg_list.h:595
#define linitial(l)
Definition pg_list.h:178
unsigned int Oid
char * colname
Definition parsenodes.h:772
TypeName * typeName
Definition parsenodes.h:773
ParseLoc location
Definition parsenodes.h:791
Definition pg_list.h:54
Definition nodes.h:133
bool setof
Definition parsenodes.h:292
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:511
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition tupdesc.c:1093
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:909
void TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno, TupleDesc src, AttrNumber srcAttno)
Definition tupdesc.c:472

References Alias::aliasname, Assert, buildNSItemFromTupleDesc(), buildRelationAliases(), CheckAttributeNamesTypes(), CHKATYPE_ANYRECORD, chooseScalarFunctionAlias(), ColumnDef::colname, CreateTemplateTupleDesc(), ereport, errcode(), errmsg, ERROR, exprCollation(), exprLocation(), exprType(), exprTypmod(), fb(), format_type_be(), forthree, RangeTblFunction::funcexpr, funcname, get_expr_result_type(), GetColumnDefCollation(), i, InvalidOid, j, lappend(), lappend_int(), lappend_oid(), lfirst, linitial, list_length(), ColumnDef::location, makeAlias(), makeNode, makeString(), MaxHeapAttributeNumber, MaxTupleAttributeNumber, TupleDescData::natts, NIL, ParseState::p_rtable, palloc_array, parser_errposition(), pstrdup(), RTE_FUNCTION, TypeName::setof, TupleDescCopyEntry(), TupleDescFinalize(), TupleDescInitEntry(), TupleDescInitEntryCollation(), TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, TYPEFUNC_RECORD, TYPEFUNC_SCALAR, ColumnDef::typeName, and typenameTypeIdAndMod().

Referenced by transformRangeFunction().

◆ addRangeTableEntryForGraphTable()

ParseNamespaceItem * addRangeTableEntryForGraphTable ( ParseState pstate,
Oid  graphid,
GraphPattern graph_pattern,
List columns,
List colnames,
Alias alias,
bool  lateral,
bool  inFromCl 
)
extern

Definition at line 2167 of file parse_relation.c.

2175{
2177 char *refname = alias ? alias->aliasname : pstrdup("graph_table");
2178 Alias *eref;
2179 int numaliases;
2180 int varattno;
2181 ListCell *lc;
2182 List *coltypes = NIL;
2183 List *coltypmods = NIL;
2187
2188 Assert(pstate != NULL);
2189
2190 rte->rtekind = RTE_GRAPH_TABLE;
2191 rte->relid = graphid;
2192 rte->relkind = RELKIND_PROPGRAPH;
2193 rte->graph_pattern = graph_pattern;
2194 rte->graph_table_columns = columns;
2195 rte->alias = alias;
2196 rte->rellockmode = AccessShareLock;
2197
2198 eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
2199
2200 if (!eref->colnames)
2201 eref->colnames = colnames;
2202
2203 numaliases = list_length(eref->colnames);
2204
2205 /* fill in any unspecified alias columns */
2206 varattno = 0;
2207 foreach(lc, colnames)
2208 {
2209 varattno++;
2210 if (varattno > numaliases)
2211 eref->colnames = lappend(eref->colnames, lfirst(lc));
2212 }
2213 if (varattno < numaliases)
2214 ereport(ERROR,
2216 errmsg("GRAPH_TABLE \"%s\" has %d columns available but %d columns specified",
2217 refname, varattno, numaliases)));
2218
2219 rte->eref = eref;
2220
2221 foreach(lc, columns)
2222 {
2224 Node *colexpr = (Node *) te->expr;
2225
2229 }
2230
2231 /*
2232 * Set flags and access permissions.
2233 */
2234 rte->lateral = lateral;
2235 rte->inFromCl = inFromCl;
2236
2238 perminfo->requiredPerms = ACL_SELECT;
2239
2240 /*
2241 * Add completed RTE to pstate's range table list, so that we know its
2242 * index. But we don't add it to the join list --- caller must do that if
2243 * appropriate.
2244 */
2245 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2246
2247 /*
2248 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2249 * list --- caller must do that if appropriate.
2250 */
2253
2254 nsitem->p_perminfo = perminfo;
2255
2256 return nsitem;
2257}
@ RTE_GRAPH_TABLE
#define lfirst_node(type, lc)
Definition pg_list.h:176
List * colnames
Definition primnodes.h:53
Expr * expr
Definition primnodes.h:2259

References AccessShareLock, ACL_SELECT, addRTEPermissionInfo(), Alias::aliasname, Assert, buildNSItemFromLists(), copyObject, ereport, errcode(), errmsg, ERROR, TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), fb(), lappend(), lappend_int(), lappend_oid(), lfirst, lfirst_node, list_length(), makeAlias(), makeNode, NIL, ParseState::p_rtable, ParseState::p_rteperminfos, pstrdup(), and RTE_GRAPH_TABLE.

Referenced by transformRangeGraphTable().

◆ addRangeTableEntryForGroup()

ParseNamespaceItem * addRangeTableEntryForGroup ( ParseState pstate,
List groupClauses 
)
extern

Definition at line 2698 of file parse_relation.c.

2700{
2702 Alias *eref;
2703 List *groupexprs;
2704 List *coltypes,
2705 *coltypmods,
2707 ListCell *lc;
2709
2710 Assert(pstate != NULL);
2711
2712 rte->rtekind = RTE_GROUP;
2713 rte->alias = NULL;
2714
2715 eref = makeAlias("*GROUP*", NIL);
2716
2717 /* fill in any unspecified alias columns, and extract column type info */
2718 groupexprs = NIL;
2720 foreach(lc, groupClauses)
2721 {
2722 TargetEntry *te = (TargetEntry *) lfirst(lc);
2723 char *colname = te->resname ? pstrdup(te->resname) : "?column?";
2724
2725 eref->colnames = lappend(eref->colnames, makeString(colname));
2726
2727 groupexprs = lappend(groupexprs, copyObject(te->expr));
2728
2730 exprType((Node *) te->expr));
2732 exprTypmod((Node *) te->expr));
2734 exprCollation((Node *) te->expr));
2735 }
2736
2737 rte->eref = eref;
2738 rte->groupexprs = groupexprs;
2739
2740 /*
2741 * Set flags.
2742 *
2743 * The grouping step is never checked for access rights, so no need to
2744 * perform addRTEPermissionInfo().
2745 */
2746 rte->lateral = false;
2747 rte->inFromCl = false;
2748
2749 /*
2750 * Add completed RTE to pstate's range table list, so that we know its
2751 * index. But we don't add it to the join list --- caller must do that if
2752 * appropriate.
2753 */
2754 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2755
2756 /*
2757 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2758 * list --- caller must do that if appropriate.
2759 */
2762
2763 return nsitem;
2764}
@ RTE_GROUP

References Assert, buildNSItemFromLists(), copyObject, TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), fb(), lappend(), lappend_int(), lappend_oid(), lfirst, list_length(), makeAlias(), makeNode, makeString(), NIL, ParseState::p_rtable, pstrdup(), and RTE_GROUP.

Referenced by parseCheckAggregates().

◆ addRangeTableEntryForJoin()

ParseNamespaceItem * addRangeTableEntryForJoin ( ParseState pstate,
List colnames,
ParseNamespaceColumn nscolumns,
JoinType  jointype,
int  nummergedcols,
List aliasvars,
List leftcols,
List rightcols,
Alias join_using_alias,
Alias alias,
bool  inFromCl 
)
extern

Definition at line 2348 of file parse_relation.c.

2359{
2361 Alias *eref;
2362 int numaliases;
2364
2365 Assert(pstate != NULL);
2366
2367 /*
2368 * Fail if join has too many columns --- we must be able to reference any
2369 * of the columns with an AttrNumber.
2370 */
2372 ereport(ERROR,
2374 errmsg("joins can have at most %d columns",
2375 MaxAttrNumber)));
2376
2377 rte->rtekind = RTE_JOIN;
2378 rte->relid = InvalidOid;
2379 rte->subquery = NULL;
2380 rte->jointype = jointype;
2381 rte->joinmergedcols = nummergedcols;
2382 rte->joinaliasvars = aliasvars;
2383 rte->joinleftcols = leftcols;
2384 rte->joinrightcols = rightcols;
2385 rte->join_using_alias = join_using_alias;
2386 rte->alias = alias;
2387
2388 eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL);
2389 numaliases = list_length(eref->colnames);
2390
2391 /* fill in any unspecified alias columns */
2392 if (numaliases < list_length(colnames))
2393 eref->colnames = list_concat(eref->colnames,
2394 list_copy_tail(colnames, numaliases));
2395
2396 if (numaliases > list_length(colnames))
2397 ereport(ERROR,
2399 errmsg("join expression \"%s\" has %d columns available but %d columns specified",
2400 eref->aliasname, list_length(colnames), numaliases)));
2401
2402 rte->eref = eref;
2403
2404 /*
2405 * Set flags and access permissions.
2406 *
2407 * Joins are never checked for access rights, so no need to perform
2408 * addRTEPermissionInfo().
2409 */
2410 rte->lateral = false;
2411 rte->inFromCl = inFromCl;
2412
2413 /*
2414 * Add completed RTE to pstate's range table list, so that we know its
2415 * index. But we don't add it to the join list --- caller must do that if
2416 * appropriate.
2417 */
2418 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2419
2420 /*
2421 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2422 * list --- caller must do that if appropriate.
2423 */
2425 nsitem->p_names = rte->eref;
2426 nsitem->p_rte = rte;
2427 nsitem->p_perminfo = NULL;
2428 nsitem->p_rtindex = list_length(pstate->p_rtable);
2429 nsitem->p_nscolumns = nscolumns;
2430 /* set default visibility flags; might get changed later */
2431 nsitem->p_rel_visible = true;
2432 nsitem->p_cols_visible = true;
2433 nsitem->p_lateral_only = false;
2434 nsitem->p_lateral_ok = true;
2435 nsitem->p_returning_type = VAR_RETURNING_DEFAULT;
2436
2437 return nsitem;
2438}
#define MaxAttrNumber
Definition attnum.h:24
#define palloc_object(type)
Definition fe_memutils.h:89
List * list_copy_tail(const List *oldlist, int nskip)
Definition list.c:1613
List * list_concat(List *list1, const List *list2)
Definition list.c:561
@ RTE_JOIN
@ VAR_RETURNING_DEFAULT
Definition primnodes.h:257

References Assert, copyObject, ereport, errcode(), errmsg, ERROR, fb(), InvalidOid, lappend(), list_concat(), list_copy_tail(), list_length(), makeAlias(), makeNode, MaxAttrNumber, NIL, ParseState::p_rtable, palloc_object, RTE_JOIN, and VAR_RETURNING_DEFAULT.

Referenced by transformFromClauseItem(), and transformSetOperationStmt().

◆ addRangeTableEntryForRelation()

ParseNamespaceItem * addRangeTableEntryForRelation ( ParseState pstate,
Relation  rel,
LOCKMODE  lockmode,
Alias alias,
bool  inh,
bool  inFromCl 
)
extern

Definition at line 1604 of file parse_relation.c.

1610{
1613 char *refname = alias ? alias->aliasname : RelationGetRelationName(rel);
1614
1615 Assert(pstate != NULL);
1616
1617 Assert(lockmode == AccessShareLock ||
1618 lockmode == RowShareLock ||
1619 lockmode == RowExclusiveLock);
1620 Assert(CheckRelationLockedByMe(rel, lockmode, true));
1621
1622 rte->rtekind = RTE_RELATION;
1623 rte->alias = alias;
1624 rte->relid = RelationGetRelid(rel);
1625 rte->inh = inh;
1626 rte->relkind = rel->rd_rel->relkind;
1627 rte->rellockmode = lockmode;
1628
1629 /*
1630 * Build the list of effective column names using user-supplied aliases
1631 * and/or actual column names.
1632 */
1633 rte->eref = makeAlias(refname, NIL);
1634 buildRelationAliases(rel->rd_att, alias, rte->eref);
1635
1636 /*
1637 * Set flags and initialize access permissions.
1638 *
1639 * The initial default on access checks is always check-for-READ-access,
1640 * which is the right thing for all except target tables.
1641 */
1642 rte->lateral = false;
1643 rte->inFromCl = inFromCl;
1644
1646 perminfo->requiredPerms = ACL_SELECT;
1647
1648 /*
1649 * Add completed RTE to pstate's range table list, so that we know its
1650 * index. But we don't add it to the join list --- caller must do that if
1651 * appropriate.
1652 */
1653 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1654
1655 /*
1656 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
1657 * list --- caller must do that if appropriate.
1658 */
1660 perminfo, rel->rd_att);
1661}
bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger)
Definition lmgr.c:334
#define RowExclusiveLock
Definition lockdefs.h:38
#define RelationGetRelationName(relation)
Definition rel.h:550

References AccessShareLock, ACL_SELECT, addRTEPermissionInfo(), Alias::aliasname, Assert, buildNSItemFromTupleDesc(), buildRelationAliases(), CheckRelationLockedByMe(), fb(), lappend(), list_length(), makeAlias(), makeNode, NIL, ParseState::p_rtable, ParseState::p_rteperminfos, RelationData::rd_att, RelationData::rd_rel, RelationGetRelationName, RelationGetRelid, RowExclusiveLock, RowShareLock, and RTE_RELATION.

Referenced by AddRelationNewConstraints(), AlterPolicy(), copy_table(), CreatePolicy(), CreateTriggerFiringOn(), DefineRelation(), DoCopy(), generate_query_for_graph_path(), insert_property_records(), rewriteTargetView(), setTargetTable(), test_rls_hooks_permissive(), test_rls_hooks_restrictive(), transformAlterTableStmt(), transformIndexStmt(), transformOnConflictClause(), transformPartitionSpec(), TransformPubWhereClauses(), transformRuleStmt(), and transformStatsStmt().

◆ addRangeTableEntryForSubquery()

ParseNamespaceItem * addRangeTableEntryForSubquery ( ParseState pstate,
Query subquery,
Alias alias,
bool  lateral,
bool  inFromCl 
)
extern

Definition at line 1675 of file parse_relation.c.

1680{
1682 Alias *eref;
1683 int numaliases;
1684 List *coltypes,
1685 *coltypmods,
1687 int varattno;
1690
1691 Assert(pstate != NULL);
1692
1693 rte->rtekind = RTE_SUBQUERY;
1694 rte->subquery = subquery;
1695 rte->alias = alias;
1696
1697 eref = alias ? copyObject(alias) : makeAlias("unnamed_subquery", NIL);
1698 numaliases = list_length(eref->colnames);
1699
1700 /* fill in any unspecified alias columns, and extract column type info */
1702 varattno = 0;
1703 foreach(tlistitem, subquery->targetList)
1704 {
1706
1707 if (te->resjunk)
1708 continue;
1709 varattno++;
1710 Assert(varattno == te->resno);
1711 if (varattno > numaliases)
1712 {
1713 char *attrname;
1714
1715 attrname = pstrdup(te->resname);
1716 eref->colnames = lappend(eref->colnames, makeString(attrname));
1717 }
1719 exprType((Node *) te->expr));
1721 exprTypmod((Node *) te->expr));
1723 exprCollation((Node *) te->expr));
1724 }
1725 if (varattno < numaliases)
1726 ereport(ERROR,
1728 errmsg("table \"%s\" has %d columns available but %d columns specified",
1729 eref->aliasname, varattno, numaliases)));
1730
1731 rte->eref = eref;
1732
1733 /*
1734 * Set flags.
1735 *
1736 * Subqueries are never checked for access rights, so no need to perform
1737 * addRTEPermissionInfo().
1738 */
1739 rte->lateral = lateral;
1740 rte->inFromCl = inFromCl;
1741
1742 /*
1743 * Add completed RTE to pstate's range table list, so that we know its
1744 * index. But we don't add it to the join list --- caller must do that if
1745 * appropriate.
1746 */
1747 pstate->p_rtable = lappend(pstate->p_rtable, rte);
1748
1749 /*
1750 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
1751 * list --- caller must do that if appropriate.
1752 */
1755
1756 /*
1757 * Mark it visible as a relation name only if it had a user-written alias.
1758 */
1759 nsitem->p_rel_visible = (alias != NULL);
1760
1761 return nsitem;
1762}
@ RTE_SUBQUERY
List * targetList
Definition parsenodes.h:203
AttrNumber resno
Definition primnodes.h:2261

References Assert, buildNSItemFromLists(), copyObject, ereport, errcode(), errmsg, ERROR, TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), fb(), lappend(), lappend_int(), lappend_oid(), lfirst, list_length(), makeAlias(), makeNode, makeString(), NIL, ParseState::p_rtable, pstrdup(), TargetEntry::resno, RTE_SUBQUERY, and Query::targetList.

Referenced by convert_ANY_sublink_to_join(), generate_setop_from_pathqueries(), transformInsertStmt(), transformRangeSubselect(), and transformSetOperationTree().

◆ addRangeTableEntryForTableFunc()

ParseNamespaceItem * addRangeTableEntryForTableFunc ( ParseState pstate,
TableFunc tf,
Alias alias,
bool  lateral,
bool  inFromCl 
)
extern

Definition at line 2088 of file parse_relation.c.

2093{
2095 char *refname;
2096 Alias *eref;
2097 int numaliases;
2098
2099 Assert(pstate != NULL);
2100
2101 /* Disallow more columns than will fit in a tuple */
2102 if (list_length(tf->colnames) > MaxTupleAttributeNumber)
2103 ereport(ERROR,
2105 errmsg("functions in FROM can return at most %d columns",
2107 parser_errposition(pstate,
2108 exprLocation((Node *) tf))));
2109 Assert(list_length(tf->coltypes) == list_length(tf->colnames));
2110 Assert(list_length(tf->coltypmods) == list_length(tf->colnames));
2111 Assert(list_length(tf->colcollations) == list_length(tf->colnames));
2112
2113 rte->rtekind = RTE_TABLEFUNC;
2114 rte->relid = InvalidOid;
2115 rte->subquery = NULL;
2116 rte->tablefunc = tf;
2117 rte->coltypes = tf->coltypes;
2118 rte->coltypmods = tf->coltypmods;
2119 rte->colcollations = tf->colcollations;
2120 rte->alias = alias;
2121
2122 refname = alias ? alias->aliasname :
2123 pstrdup(tf->functype == TFT_XMLTABLE ? "xmltable" : "json_table");
2124 eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
2125 numaliases = list_length(eref->colnames);
2126
2127 /* fill in any unspecified alias columns */
2128 if (numaliases < list_length(tf->colnames))
2129 eref->colnames = list_concat(eref->colnames,
2130 list_copy_tail(tf->colnames, numaliases));
2131
2132 if (numaliases > list_length(tf->colnames))
2133 ereport(ERROR,
2135 errmsg("%s function has %d columns available but %d columns specified",
2136 tf->functype == TFT_XMLTABLE ? "XMLTABLE" : "JSON_TABLE",
2137 list_length(tf->colnames), numaliases)));
2138
2139 rte->eref = eref;
2140
2141 /*
2142 * Set flags and access permissions.
2143 *
2144 * Tablefuncs are never checked for access rights (at least, not by
2145 * ExecCheckPermissions()), so no need to perform addRTEPermissionInfo().
2146 */
2147 rte->lateral = lateral;
2148 rte->inFromCl = inFromCl;
2149
2150 /*
2151 * Add completed RTE to pstate's range table list, so that we know its
2152 * index. But we don't add it to the join list --- caller must do that if
2153 * appropriate.
2154 */
2155 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2156
2157 /*
2158 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2159 * list --- caller must do that if appropriate.
2160 */
2162 rte->coltypes, rte->coltypmods,
2163 rte->colcollations);
2164}
@ RTE_TABLEFUNC
@ TFT_XMLTABLE
Definition primnodes.h:101
TableFuncType functype
Definition primnodes.h:115

References Alias::aliasname, Assert, buildNSItemFromLists(), copyObject, ereport, errcode(), errmsg, ERROR, exprLocation(), fb(), TableFunc::functype, InvalidOid, lappend(), list_concat(), list_copy_tail(), list_length(), makeAlias(), makeNode, MaxTupleAttributeNumber, NIL, ParseState::p_rtable, parser_errposition(), pstrdup(), RTE_TABLEFUNC, and TFT_XMLTABLE.

Referenced by transformJsonTable(), and transformRangeTableFunc().

◆ addRangeTableEntryForValues()

ParseNamespaceItem * addRangeTableEntryForValues ( ParseState pstate,
List exprs,
List coltypes,
List coltypmods,
List colcollations,
Alias alias,
bool  lateral,
bool  inFromCl 
)
extern

Definition at line 2266 of file parse_relation.c.

2274{
2276 char *refname = alias ? alias->aliasname : pstrdup("*VALUES*");
2277 Alias *eref;
2278 int numaliases;
2279 int numcolumns;
2280
2281 Assert(pstate != NULL);
2282
2283 rte->rtekind = RTE_VALUES;
2284 rte->relid = InvalidOid;
2285 rte->subquery = NULL;
2286 rte->values_lists = exprs;
2287 rte->coltypes = coltypes;
2288 rte->coltypmods = coltypmods;
2289 rte->colcollations = colcollations;
2290 rte->alias = alias;
2291
2292 eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
2293
2294 /* fill in any unspecified alias columns */
2295 numcolumns = list_length((List *) linitial(exprs));
2296 numaliases = list_length(eref->colnames);
2297 while (numaliases < numcolumns)
2298 {
2299 char attrname[64];
2300
2301 numaliases++;
2302 snprintf(attrname, sizeof(attrname), "column%d", numaliases);
2303 eref->colnames = lappend(eref->colnames,
2305 }
2306 if (numcolumns < numaliases)
2307 ereport(ERROR,
2309 errmsg("VALUES lists \"%s\" have %d columns available but %d columns specified",
2310 refname, numcolumns, numaliases)));
2311
2312 rte->eref = eref;
2313
2314 /*
2315 * Set flags and access permissions.
2316 *
2317 * Subqueries are never checked for access rights, so no need to perform
2318 * addRTEPermissionInfo().
2319 */
2320 rte->lateral = lateral;
2321 rte->inFromCl = inFromCl;
2322
2323 /*
2324 * Add completed RTE to pstate's range table list, so that we know its
2325 * index. But we don't add it to the join list --- caller must do that if
2326 * appropriate.
2327 */
2328 pstate->p_rtable = lappend(pstate->p_rtable, rte);
2329
2330 /*
2331 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
2332 * list --- caller must do that if appropriate.
2333 */
2335 rte->coltypes, rte->coltypmods,
2336 rte->colcollations);
2337}
@ RTE_VALUES
#define snprintf
Definition port.h:261

References Alias::aliasname, Assert, buildNSItemFromLists(), copyObject, ereport, errcode(), errmsg, ERROR, fb(), InvalidOid, lappend(), linitial, list_length(), makeAlias(), makeNode, makeString(), NIL, ParseState::p_rtable, pstrdup(), RTE_VALUES, and snprintf.

Referenced by transformInsertStmt(), and transformValuesClause().

◆ addRTEPermissionInfo()

RTEPermissionInfo * addRTEPermissionInfo ( List **  rteperminfos,
RangeTblEntry rte 
)
extern

Definition at line 4051 of file parse_relation.c.

4052{
4054
4055 Assert(OidIsValid(rte->relid));
4056 Assert(rte->perminfoindex == 0);
4057
4058 /* Nope, so make one and add to the list. */
4060 perminfo->relid = rte->relid;
4061 perminfo->inh = rte->inh;
4062 /* Other information is set by fetching the node as and where needed. */
4063
4064 *rteperminfos = lappend(*rteperminfos, perminfo);
4065
4066 /* Note its index (1-based!) */
4067 rte->perminfoindex = list_length(*rteperminfos);
4068
4069 return perminfo;
4070}
#define OidIsValid(objectId)
Definition c.h:858

References Assert, fb(), lappend(), list_length(), makeNode, and OidIsValid.

Referenced by add_rte_to_flat_rtable(), addRangeTableEntry(), addRangeTableEntryForGraphTable(), addRangeTableEntryForRelation(), create_edata_for_relation(), create_estate_for_relation(), plan_cluster_use_sort(), plan_create_index_workers(), and rewriteTargetView().

◆ attnameAttNum()

int attnameAttNum ( Relation  rd,
const char attname,
bool  sysColOK 
)
extern

Definition at line 3706 of file parse_relation.c.

3707{
3708 int i;
3709
3710 for (i = 0; i < RelationGetNumberOfAttributes(rd); i++)
3711 {
3712 Form_pg_attribute att = TupleDescAttr(rd->rd_att, i);
3713
3714 if (namestrcmp(&(att->attname), attname) == 0 && !att->attisdropped)
3715 return i + 1;
3716 }
3717
3718 if (sysColOK)
3719 {
3721 return i;
3722 }
3723
3724 /* on failure */
3725 return InvalidAttrNumber;
3726}
#define InvalidAttrNumber
Definition attnum.h:23
int namestrcmp(Name name, const char *str)
Definition name.c:247
static int specialAttNum(const char *attname)
NameData attname
#define RelationGetNumberOfAttributes(relation)
Definition rel.h:522

References attname, fb(), i, InvalidAttrNumber, namestrcmp(), RelationGetNumberOfAttributes, specialAttNum(), and TupleDescAttr().

Referenced by checkInsertTargets(), CreateTriggerFiringOn(), do_analyze_rel(), transformForPortionOfClause(), transformUpdateTargetList(), and validate_va_cols_list().

◆ attnumAttName()

const NameData * attnumAttName ( Relation  rd,
int  attid 
)
extern

Definition at line 3757 of file parse_relation.c.

3758{
3759 if (attid <= 0)
3760 {
3762
3764 return &sysatt->attname;
3765 }
3766 if (attid > rd->rd_att->natts)
3767 elog(ERROR, "invalid attribute number %d", attid);
3768 return &TupleDescAttr(rd->rd_att, attid - 1)->attname;
3769}
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
Definition heap.c:236
FormData_pg_attribute

References elog, ERROR, fb(), FormData_pg_attribute, SystemAttributeDefinition(), and TupleDescAttr().

Referenced by transformFkeyGetPrimaryKey().

◆ attnumCollationId()

Oid attnumCollationId ( Relation  rd,
int  attid 
)
extern

Definition at line 3799 of file parse_relation.c.

3800{
3801 if (attid <= 0)
3802 {
3803 /* All system attributes are of noncollatable types. */
3804 return InvalidOid;
3805 }
3806 if (attid > rd->rd_att->natts)
3807 elog(ERROR, "invalid attribute number %d", attid);
3808 return TupleDescAttr(rd->rd_att, attid - 1)->attcollation;
3809}

References elog, ERROR, fb(), InvalidOid, and TupleDescAttr().

Referenced by transformFkeyGetPrimaryKey().

◆ attnumTypeId()

Oid attnumTypeId ( Relation  rd,
int  attid 
)
extern

Definition at line 3779 of file parse_relation.c.

3780{
3781 if (attid <= 0)
3782 {
3784
3786 return sysatt->atttypid;
3787 }
3788 if (attid > rd->rd_att->natts)
3789 elog(ERROR, "invalid attribute number %d", attid);
3790 return TupleDescAttr(rd->rd_att, attid - 1)->atttypid;
3791}

References elog, ERROR, fb(), FormData_pg_attribute, SystemAttributeDefinition(), and TupleDescAttr().

Referenced by transformAssignedExpr(), and transformFkeyGetPrimaryKey().

◆ checkNameSpaceConflicts()

void checkNameSpaceConflicts ( ParseState pstate,
List namespace1,
List namespace2 
)
extern

Definition at line 438 of file parse_relation.c.

440{
441 ListCell *l1;
442
443 foreach(l1, namespace1)
444 {
446 RangeTblEntry *rte1 = nsitem1->p_rte;
447 const char *aliasname1 = nsitem1->p_names->aliasname;
448 ListCell *l2;
449
450 if (!nsitem1->p_rel_visible)
451 continue;
452
453 foreach(l2, namespace2)
454 {
456 RangeTblEntry *rte2 = nsitem2->p_rte;
457 const char *aliasname2 = nsitem2->p_names->aliasname;
458
459 if (!nsitem2->p_rel_visible)
460 continue;
461 if (strcmp(aliasname2, aliasname1) != 0)
462 continue; /* definitely no conflict */
463 if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL &&
464 rte2->rtekind == RTE_RELATION && rte2->alias == NULL &&
465 rte1->relid != rte2->relid)
466 continue; /* no conflict per SQL rule */
469 errmsg("table name \"%s\" specified more than once",
470 aliasname1)));
471 }
472 }
473}

References ereport, errcode(), errmsg, ERROR, fb(), lfirst, and RTE_RELATION.

Referenced by transformFromClause(), and transformFromClauseItem().

◆ colNameToVar()

Node * colNameToVar ( ParseState pstate,
const char colname,
bool  localonly,
int  location 
)
extern

Definition at line 926 of file parse_relation.c.

928{
929 Node *result = NULL;
930 int sublevels_up = 0;
931 ParseState *orig_pstate = pstate;
932
933 while (pstate != NULL)
934 {
935 ListCell *l;
936
937 foreach(l, pstate->p_namespace)
938 {
941
942 /* Ignore table-only items */
943 if (!nsitem->p_cols_visible)
944 continue;
945 /* If not inside LATERAL, ignore lateral-only items */
946 if (nsitem->p_lateral_only && !pstate->p_lateral_active)
947 continue;
948
949 /* use orig_pstate here for consistency with other callers */
951 colname, location);
952
953 if (newresult)
954 {
955 if (result)
958 errmsg("column reference \"%s\" is ambiguous",
959 colname),
960 parser_errposition(pstate, location)));
961 check_lateral_ref_ok(pstate, nsitem, location);
963 }
964 }
965
966 if (result != NULL || localonly)
967 break; /* found, or don't want to look at parent */
968
969 pstate = pstate->parentParseState;
970 sublevels_up++;
971 }
972
973 return result;
974}
uint32 result
Node * scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, const char *colname, int location)
static void check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem, int location)
ParseState * parentParseState
Definition parse_node.h:213
bool p_lateral_active
Definition parse_node.h:224

References check_lateral_ref_ok(), ereport, errcode(), errmsg, ERROR, fb(), lfirst, ParseState::p_lateral_active, ParseState::p_namespace, ParseState::parentParseState, parser_errposition(), result, and scanNSItemForColumn().

Referenced by findTargetlistEntrySQL92(), and transformColumnRef().

◆ errorMissingColumn()

pg_noreturn void errorMissingColumn ( ParseState pstate,
const char relname,
const char colname,
int  location 
)
extern

Definition at line 3889 of file parse_relation.c.

3891{
3893
3894 /*
3895 * Search the entire rtable looking for possible matches. If we find one,
3896 * emit a hint about it.
3897 */
3898 state = searchRangeTableForCol(pstate, relname, colname, location);
3899
3900 /*
3901 * If there are exact match(es), they must be inaccessible for some
3902 * reason.
3903 */
3904 if (state->rexact1)
3905 {
3906 /*
3907 * We don't try too hard when there's multiple inaccessible exact
3908 * matches, but at least be sure that we don't misleadingly suggest
3909 * that there's only one.
3910 */
3911 if (state->rexact2)
3912 ereport(ERROR,
3914 relname ?
3915 errmsg("column %s.%s does not exist", relname, colname) :
3916 errmsg("column \"%s\" does not exist", colname),
3917 errdetail("There are columns named \"%s\", but they are in tables that cannot be referenced from this part of the query.",
3918 colname),
3919 !relname ? errhint("Try using a table-qualified name.") : 0,
3920 parser_errposition(pstate, location)));
3921 /* Single exact match, so try to determine why it's inaccessible. */
3922 ereport(ERROR,
3924 relname ?
3925 errmsg("column %s.%s does not exist", relname, colname) :
3926 errmsg("column \"%s\" does not exist", colname),
3927 errdetail("There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query.",
3928 colname, state->rexact1->eref->aliasname),
3929 rte_visible_if_lateral(pstate, state->rexact1) ?
3930 errhint("To reference that column, you must mark this subquery with LATERAL.") :
3931 (!relname && rte_visible_if_qualified(pstate, state->rexact1)) ?
3932 errhint("To reference that column, you must use a table-qualified name.") : 0,
3933 parser_errposition(pstate, location)));
3934 }
3935
3936 if (!state->rsecond)
3937 {
3938 /* If we found no match at all, we have little to report */
3939 if (!state->rfirst)
3940 ereport(ERROR,
3942 relname ?
3943 errmsg("column %s.%s does not exist", relname, colname) :
3944 errmsg("column \"%s\" does not exist", colname),
3945 parser_errposition(pstate, location)));
3946 /* Handle case where we have a single alternative spelling to offer */
3947 ereport(ERROR,
3949 relname ?
3950 errmsg("column %s.%s does not exist", relname, colname) :
3951 errmsg("column \"%s\" does not exist", colname),
3952 errhint("Perhaps you meant to reference the column \"%s.%s\".",
3953 state->rfirst->eref->aliasname,
3954 strVal(list_nth(state->rfirst->eref->colnames,
3955 state->first - 1))),
3956 parser_errposition(pstate, location)));
3957 }
3958 else
3959 {
3960 /* Handle case where there are two equally useful column hints */
3961 ereport(ERROR,
3963 relname ?
3964 errmsg("column %s.%s does not exist", relname, colname) :
3965 errmsg("column \"%s\" does not exist", colname),
3966 errhint("Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\".",
3967 state->rfirst->eref->aliasname,
3968 strVal(list_nth(state->rfirst->eref->colnames,
3969 state->first - 1)),
3970 state->rsecond->eref->aliasname,
3971 strVal(list_nth(state->rsecond->eref->colnames,
3972 state->second - 1))),
3973 parser_errposition(pstate, location)));
3974 }
3975}
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
static bool rte_visible_if_lateral(ParseState *pstate, RangeTblEntry *rte)
static FuzzyAttrMatchState * searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colname, int location)
static bool rte_visible_if_qualified(ParseState *pstate, RangeTblEntry *rte)
NameData relname
Definition pg_class.h:40
static void * list_nth(const List *list, int n)
Definition pg_list.h:331
#define strVal(v)
Definition value.h:82

References ereport, errcode(), errdetail(), errhint(), errmsg, ERROR, fb(), list_nth(), parser_errposition(), relname, rte_visible_if_lateral(), rte_visible_if_qualified(), searchRangeTableForCol(), and strVal.

Referenced by transformColumnRef().

◆ errorMissingRTE()

pg_noreturn void errorMissingRTE ( ParseState pstate,
RangeVar relation 
)
extern

Definition at line 3818 of file parse_relation.c.

3819{
3821 const char *badAlias = NULL;
3822
3823 /*
3824 * Check to see if there are any potential matches in the query's
3825 * rangetable. (Note: cases involving a bad schema name in the RangeVar
3826 * will throw error immediately here. That seems OK.)
3827 */
3828 rte = searchRangeTableForRel(pstate, relation);
3829
3830 /*
3831 * If we found a match that has an alias and the alias is visible in the
3832 * namespace, then the problem is probably use of the relation's real name
3833 * instead of its alias, ie "SELECT foo.* FROM foo f". This mistake is
3834 * common enough to justify a specific hint.
3835 *
3836 * If we found a match that doesn't meet those criteria, assume the
3837 * problem is illegal use of a relation outside its scope, as in the
3838 * MySQL-ism "SELECT ... FROM a, b LEFT JOIN c ON (a.x = c.y)".
3839 */
3840 if (rte && rte->alias &&
3841 strcmp(rte->eref->aliasname, relation->relname) != 0)
3842 {
3844 int sublevels_up;
3845
3846 nsitem = refnameNamespaceItem(pstate, NULL, rte->eref->aliasname,
3847 relation->location,
3848 &sublevels_up);
3849 if (nsitem && nsitem->p_rte == rte)
3850 badAlias = rte->eref->aliasname;
3851 }
3852
3853 /* If it looks like the user forgot to use an alias, hint about that */
3854 if (badAlias)
3855 ereport(ERROR,
3857 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
3858 relation->relname),
3859 errhint("Perhaps you meant to reference the table alias \"%s\".",
3860 badAlias),
3861 parser_errposition(pstate, relation->location)));
3862 /* Hint about case where we found an (inaccessible) exact match */
3863 else if (rte)
3864 ereport(ERROR,
3866 errmsg("invalid reference to FROM-clause entry for table \"%s\"",
3867 relation->relname),
3868 errdetail("There is an entry for table \"%s\", but it cannot be referenced from this part of the query.",
3869 rte->eref->aliasname),
3870 rte_visible_if_lateral(pstate, rte) ?
3871 errhint("To reference that table, you must mark this subquery with LATERAL.") : 0,
3872 parser_errposition(pstate, relation->location)));
3873 /* Else, we have nothing to offer but the bald statement of error */
3874 else
3875 ereport(ERROR,
3877 errmsg("missing FROM-clause entry for table \"%s\"",
3878 relation->relname),
3879 parser_errposition(pstate, relation->location)));
3880}
static RangeTblEntry * searchRangeTableForRel(ParseState *pstate, RangeVar *relation)
ParseNamespaceItem * refnameNamespaceItem(ParseState *pstate, const char *schemaname, const char *refname, int location, int *sublevels_up)
#define ERRCODE_UNDEFINED_TABLE
Definition pgbench.c:79

References ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errdetail(), errhint(), errmsg, ERROR, fb(), RangeVar::location, parser_errposition(), refnameNamespaceItem(), RangeVar::relname, rte_visible_if_lateral(), and searchRangeTableForRel().

Referenced by ExpandColumnRefStar(), and transformColumnRef().

◆ expandNSItemAttrs()

List * expandNSItemAttrs ( ParseState pstate,
ParseNamespaceItem nsitem,
int  sublevels_up,
bool  require_col_privs,
int  location 
)
extern

Definition at line 3408 of file parse_relation.c.

3410{
3411 RangeTblEntry *rte = nsitem->p_rte;
3412 RTEPermissionInfo *perminfo = nsitem->p_perminfo;
3413 List *names,
3414 *vars;
3415 ListCell *name,
3416 *var;
3417 List *te_list = NIL;
3418
3419 vars = expandNSItemVars(pstate, nsitem, sublevels_up, location, &names);
3420
3421 /*
3422 * Require read access to the table. This is normally redundant with the
3423 * markVarForSelectPriv calls below, but not if the table has zero
3424 * columns. We need not do anything if the nsitem is for a join: its
3425 * component tables will have been marked ACL_SELECT when they were added
3426 * to the rangetable. (This step changes things only for the target
3427 * relation of UPDATE/DELETE, which cannot be under a join.)
3428 */
3429 if (rte->rtekind == RTE_RELATION)
3430 {
3431 Assert(perminfo != NULL);
3432 perminfo->requiredPerms |= ACL_SELECT;
3433 }
3434
3435 forboth(name, names, var, vars)
3436 {
3437 char *label = strVal(lfirst(name));
3438 Var *varnode = (Var *) lfirst(var);
3439 TargetEntry *te;
3440
3441 te = makeTargetEntry((Expr *) varnode,
3442 (AttrNumber) pstate->p_next_resno++,
3443 label,
3444 false);
3445 te_list = lappend(te_list, te);
3446
3448 {
3449 /* Require read access to each column */
3451 }
3452 }
3453
3454 Assert(name == NULL && var == NULL); /* lists not the same length? */
3455
3456 return te_list;
3457}
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition makefuncs.c:289
void markVarForSelectPriv(ParseState *pstate, Var *var)
List * expandNSItemVars(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location, List **colnames)
static char * label
#define forboth(cell1, list1, cell2, list2)
Definition pg_list.h:550
int p_next_resno
Definition parse_node.h:233
const char * name

References ACL_SELECT, Assert, expandNSItemVars(), fb(), forboth, label, lappend(), lfirst, makeTargetEntry(), markVarForSelectPriv(), name, NIL, ParseState::p_next_resno, RTE_RELATION, and strVal.

Referenced by ExpandAllTables(), ExpandSingleTable(), and transformValuesClause().

◆ expandNSItemVars()

List * expandNSItemVars ( ParseState pstate,
ParseNamespaceItem nsitem,
int  sublevels_up,
int  location,
List **  colnames 
)
extern

Definition at line 3343 of file parse_relation.c.

3346{
3347 List *result = NIL;
3348 int colindex;
3349 ListCell *lc;
3350
3351 if (colnames)
3352 *colnames = NIL;
3353 colindex = 0;
3354 foreach(lc, nsitem->p_names->colnames)
3355 {
3357 const char *colname = strVal(colnameval);
3358 ParseNamespaceColumn *nscol = nsitem->p_nscolumns + colindex;
3359
3360 if (nscol->p_dontexpand)
3361 {
3362 /* skip */
3363 }
3364 else if (colname[0])
3365 {
3366 Var *var;
3367
3368 Assert(nscol->p_varno > 0);
3369 var = makeVar(nscol->p_varno,
3370 nscol->p_varattno,
3371 nscol->p_vartype,
3372 nscol->p_vartypmod,
3373 nscol->p_varcollid,
3374 sublevels_up);
3375 /* makeVar doesn't offer parameters for these, so set by hand: */
3376 var->varreturningtype = nscol->p_varreturningtype;
3377 var->varnosyn = nscol->p_varnosyn;
3378 var->varattnosyn = nscol->p_varattnosyn;
3379 var->location = location;
3380
3381 /* ... and update varnullingrels */
3382 markNullableIfNeeded(pstate, var);
3383
3384 result = lappend(result, var);
3385 if (colnames)
3386 *colnames = lappend(*colnames, colnameval);
3387 }
3388 else
3389 {
3390 /* dropped column, ignore */
3391 Assert(nscol->p_varno == 0);
3392 }
3393 colindex++;
3394 }
3395 return result;
3396}
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition makefuncs.c:66
void markNullableIfNeeded(ParseState *pstate, Var *var)
Definition value.h:64
ParseLoc location
Definition primnodes.h:311
VarReturningType varreturningtype
Definition primnodes.h:298

References Assert, fb(), lappend(), lfirst, Var::location, makeVar(), markNullableIfNeeded(), NIL, result, strVal, and Var::varreturningtype.

Referenced by coerce_record_to_complex(), expandNSItemAttrs(), ExpandSingleTable(), and transformInsertStmt().

◆ expandRTE()

void expandRTE ( RangeTblEntry rte,
int  rtindex,
int  sublevels_up,
VarReturningType  returning_type,
int  location,
bool  include_dropped,
List **  colnames,
List **  colvars 
)
extern

Definition at line 2866 of file parse_relation.c.

2870{
2871 int varattno;
2872
2873 if (colnames)
2874 *colnames = NIL;
2875 if (colvars)
2876 *colvars = NIL;
2877
2878 switch (rte->rtekind)
2879 {
2880 case RTE_RELATION:
2881 /* Ordinary relation RTE */
2882 expandRelation(rte->relid, rte->eref,
2883 rtindex, sublevels_up, returning_type, location,
2884 include_dropped, colnames, colvars);
2885 break;
2886 case RTE_SUBQUERY:
2887 {
2888 /* Subquery RTE */
2889 ListCell *aliasp_item = list_head(rte->eref->colnames);
2891
2892 varattno = 0;
2893 foreach(tlistitem, rte->subquery->targetList)
2894 {
2896
2897 if (te->resjunk)
2898 continue;
2899 varattno++;
2900 Assert(varattno == te->resno);
2901
2902 /*
2903 * Formerly it was possible for the subquery tlist to have
2904 * more non-junk entries than the colnames list does (if
2905 * this RTE has been expanded from a view that has more
2906 * columns than it did when the current query was parsed).
2907 * Now that ApplyRetrieveRule cleans up such cases, we
2908 * shouldn't see that anymore, but let's just check.
2909 */
2910 if (!aliasp_item)
2911 elog(ERROR, "too few column names for subquery %s",
2912 rte->eref->aliasname);
2913
2914 if (colnames)
2915 {
2916 char *label = strVal(lfirst(aliasp_item));
2917
2918 *colnames = lappend(*colnames, makeString(pstrdup(label)));
2919 }
2920
2921 if (colvars)
2922 {
2923 Var *varnode;
2924
2925 varnode = makeVar(rtindex, varattno,
2926 exprType((Node *) te->expr),
2927 exprTypmod((Node *) te->expr),
2928 exprCollation((Node *) te->expr),
2929 sublevels_up);
2930 varnode->varreturningtype = returning_type;
2931 varnode->location = location;
2932
2934 }
2935
2936 aliasp_item = lnext(rte->eref->colnames, aliasp_item);
2937 }
2938 }
2939 break;
2940 case RTE_FUNCTION:
2941 {
2942 /* Function RTE */
2943 int atts_done = 0;
2944 ListCell *lc;
2945
2946 foreach(lc, rte->functions)
2947 {
2951 TupleDesc tupdesc = NULL;
2952
2953 /* If it has a coldeflist, it returns RECORD */
2954 if (rtfunc->funccolnames != NIL)
2956 else
2958 &funcrettype,
2959 &tupdesc);
2960
2963 {
2964 /* Composite data type, e.g. a table's row type */
2965 Assert(tupdesc);
2966 expandTupleDesc(tupdesc, rte->eref,
2967 rtfunc->funccolcount, atts_done,
2968 rtindex, sublevels_up,
2969 returning_type, location,
2970 include_dropped, colnames, colvars);
2971 }
2972 else if (functypclass == TYPEFUNC_SCALAR)
2973 {
2974 /* Base data type, i.e. scalar */
2975 if (colnames)
2976 *colnames = lappend(*colnames,
2977 list_nth(rte->eref->colnames,
2978 atts_done));
2979
2980 if (colvars)
2981 {
2982 Var *varnode;
2983
2984 varnode = makeVar(rtindex, atts_done + 1,
2986 exprTypmod(rtfunc->funcexpr),
2987 exprCollation(rtfunc->funcexpr),
2988 sublevels_up);
2989 varnode->varreturningtype = returning_type;
2990 varnode->location = location;
2991
2993 }
2994 }
2995 else if (functypclass == TYPEFUNC_RECORD)
2996 {
2997 if (colnames)
2998 {
2999 List *namelist;
3000
3001 /* extract appropriate subset of column list */
3002 namelist = list_copy_tail(rte->eref->colnames,
3003 atts_done);
3005 rtfunc->funccolcount);
3006 *colnames = list_concat(*colnames, namelist);
3007 }
3008
3009 if (colvars)
3010 {
3011 ListCell *l1;
3012 ListCell *l2;
3013 ListCell *l3;
3014 int attnum = atts_done;
3015
3016 forthree(l1, rtfunc->funccoltypes,
3017 l2, rtfunc->funccoltypmods,
3018 l3, rtfunc->funccolcollations)
3019 {
3020 Oid attrtype = lfirst_oid(l1);
3021 int32 attrtypmod = lfirst_int(l2);
3023 Var *varnode;
3024
3025 attnum++;
3026 varnode = makeVar(rtindex,
3027 attnum,
3028 attrtype,
3029 attrtypmod,
3031 sublevels_up);
3032 varnode->varreturningtype = returning_type;
3033 varnode->location = location;
3035 }
3036 }
3037 }
3038 else
3039 {
3040 /* addRangeTableEntryForFunction should've caught this */
3041 elog(ERROR, "function in FROM has unsupported return type");
3042 }
3043 atts_done += rtfunc->funccolcount;
3044 }
3045
3046 /* Append the ordinality column if any */
3047 if (rte->funcordinality)
3048 {
3049 if (colnames)
3050 *colnames = lappend(*colnames,
3051 llast(rte->eref->colnames));
3052
3053 if (colvars)
3054 {
3055 Var *varnode = makeVar(rtindex,
3056 atts_done + 1,
3057 INT8OID,
3058 -1,
3059 InvalidOid,
3060 sublevels_up);
3061
3062 varnode->varreturningtype = returning_type;
3064 }
3065 }
3066 }
3067 break;
3068 case RTE_JOIN:
3069 {
3070 /* Join RTE */
3071 ListCell *colname;
3073
3074 Assert(list_length(rte->eref->colnames) == list_length(rte->joinaliasvars));
3075
3076 varattno = 0;
3077 forboth(colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
3078 {
3079 Node *avar = (Node *) lfirst(aliasvar);
3080
3081 varattno++;
3082
3083 /*
3084 * During ordinary parsing, there will never be any
3085 * deleted columns in the join. While this function is
3086 * also used by the rewriter and planner, they do not
3087 * currently call it on any JOIN RTEs. Therefore, this
3088 * next bit is dead code, but it seems prudent to handle
3089 * the case correctly anyway.
3090 */
3091 if (avar == NULL)
3092 {
3093 if (include_dropped)
3094 {
3095 if (colnames)
3096 *colnames = lappend(*colnames,
3097 makeString(pstrdup("")));
3098 if (colvars)
3099 {
3100 /*
3101 * Can't use join's column type here (it might
3102 * be dropped!); but it doesn't really matter
3103 * what type the Const claims to be.
3104 */
3107 InvalidOid));
3108 }
3109 }
3110 continue;
3111 }
3112
3113 if (colnames)
3114 {
3115 char *label = strVal(lfirst(colname));
3116
3117 *colnames = lappend(*colnames,
3119 }
3120
3121 if (colvars)
3122 {
3123 Var *varnode;
3124
3125 /*
3126 * If the joinaliasvars entry is a simple Var, just
3127 * copy it (with adjustment of varlevelsup and
3128 * location); otherwise it is a JOIN USING column and
3129 * we must generate a join alias Var. This matches
3130 * the results that expansion of "join.*" by
3131 * expandNSItemVars would have produced, if we had
3132 * access to the ParseNamespaceItem for the join.
3133 */
3134 if (IsA(avar, Var))
3135 {
3136 varnode = copyObject((Var *) avar);
3137 varnode->varlevelsup = sublevels_up;
3138 }
3139 else
3140 varnode = makeVar(rtindex, varattno,
3141 exprType(avar),
3144 sublevels_up);
3145 varnode->varreturningtype = returning_type;
3146 varnode->location = location;
3147
3149 }
3150 }
3151 }
3152 break;
3153 case RTE_TABLEFUNC:
3154 case RTE_VALUES:
3155 case RTE_CTE:
3157 case RTE_GRAPH_TABLE:
3158 {
3159 /* Tablefunc, Values, CTE, or ENR RTE */
3160 ListCell *aliasp_item = list_head(rte->eref->colnames);
3161 ListCell *lct;
3162 ListCell *lcm;
3163 ListCell *lcc;
3164
3165 varattno = 0;
3166 forthree(lct, rte->coltypes,
3167 lcm, rte->coltypmods,
3168 lcc, rte->colcollations)
3169 {
3170 Oid coltype = lfirst_oid(lct);
3173
3174 varattno++;
3175
3176 if (colnames)
3177 {
3178 /* Assume there is one alias per output column */
3179 if (OidIsValid(coltype))
3180 {
3181 char *label = strVal(lfirst(aliasp_item));
3182
3183 *colnames = lappend(*colnames,
3185 }
3186 else if (include_dropped)
3187 *colnames = lappend(*colnames,
3188 makeString(pstrdup("")));
3189
3190 aliasp_item = lnext(rte->eref->colnames, aliasp_item);
3191 }
3192
3193 if (colvars)
3194 {
3195 if (OidIsValid(coltype))
3196 {
3197 Var *varnode;
3198
3199 varnode = makeVar(rtindex, varattno,
3200 coltype, coltypmod, colcoll,
3201 sublevels_up);
3202 varnode->varreturningtype = returning_type;
3203 varnode->location = location;
3204
3206 }
3207 else if (include_dropped)
3208 {
3209 /*
3210 * It doesn't really matter what type the Const
3211 * claims to be.
3212 */
3215 InvalidOid));
3216 }
3217 }
3218 }
3219 }
3220 break;
3221 case RTE_RESULT:
3222 case RTE_GROUP:
3223 /* These expose no columns, so nothing to do */
3224 break;
3225 default:
3226 elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
3227 }
3228}
List * list_truncate(List *list, int new_size)
Definition list.c:631
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition makefuncs.c:388
static void expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset, int rtindex, int sublevels_up, VarReturningType returning_type, int location, bool include_dropped, List **colnames, List **colvars)
static void expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up, VarReturningType returning_type, int location, bool include_dropped, List **colnames, List **colvars)
@ RTE_RESULT
int16 attnum
#define llast(l)
Definition pg_list.h:198
#define lfirst_int(lc)
Definition pg_list.h:173
static ListCell * list_head(const List *l)
Definition pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition pg_list.h:375
#define lfirst_oid(lc)
Definition pg_list.h:174

References Assert, attnum, copyObject, elog, ERROR, expandRelation(), expandTupleDesc(), TargetEntry::expr, exprCollation(), exprType(), exprTypmod(), fb(), forboth, forthree, RangeTblFunction::funcexpr, get_expr_result_type(), InvalidOid, IsA, label, lappend(), lfirst, lfirst_int, lfirst_oid, list_concat(), list_copy_tail(), list_head(), list_length(), list_nth(), list_truncate(), llast, lnext(), makeNullConst(), makeString(), makeVar(), NIL, OidIsValid, pstrdup(), TargetEntry::resno, RTE_CTE, RTE_FUNCTION, RTE_GRAPH_TABLE, RTE_GROUP, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, strVal, TYPEFUNC_COMPOSITE, TYPEFUNC_COMPOSITE_DOMAIN, TYPEFUNC_RECORD, and TYPEFUNC_SCALAR.

Referenced by build_physical_tlist(), expandRecordVariable(), ReplaceVarFromTargetList(), set_relation_column_names(), and transformWholeRowRef().

◆ GetCTEForRTE()

CommonTableExpr * GetCTEForRTE ( ParseState pstate,
RangeTblEntry rte,
int  rtelevelsup 
)
extern

Definition at line 593 of file parse_relation.c.

594{
595 Index levelsup;
596 ListCell *lc;
597
598 Assert(rte->rtekind == RTE_CTE);
599 levelsup = rte->ctelevelsup + rtelevelsup;
600 while (levelsup-- > 0)
601 {
602 pstate = pstate->parentParseState;
603 if (!pstate) /* shouldn't happen */
604 elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
605 }
606 foreach(lc, pstate->p_ctenamespace)
607 {
609
610 if (strcmp(cte->ctename, rte->ctename) == 0)
611 return cte;
612 }
613 /* shouldn't happen */
614 elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
615 return NULL; /* keep compiler quiet */
616}
unsigned int Index
Definition c.h:698
List * p_ctenamespace
Definition parse_node.h:225

References Assert, CommonTableExpr::ctename, elog, ERROR, fb(), lfirst, ParseState::p_ctenamespace, ParseState::parentParseState, and RTE_CTE.

Referenced by expandRecordVariable(), and markTargetListOrigin().

◆ GetNSItemByRangeTablePosn()

ParseNamespaceItem * GetNSItemByRangeTablePosn ( ParseState pstate,
int  varno,
int  sublevels_up 
)
extern

Definition at line 517 of file parse_relation.c.

520{
521 ListCell *lc;
522
523 while (sublevels_up-- > 0)
524 {
525 pstate = pstate->parentParseState;
526 Assert(pstate != NULL);
527 }
528 foreach(lc, pstate->p_namespace)
529 {
531
532 if (nsitem->p_rtindex == varno)
533 return nsitem;
534 }
535 elog(ERROR, "nsitem not found (internal error)");
536 return NULL; /* keep compiler quiet */
537}

References Assert, elog, ERROR, fb(), lfirst, ParseState::p_namespace, and ParseState::parentParseState.

Referenced by transformMergeStmt().

◆ GetNSItemByVar()

ParseNamespaceItem * GetNSItemByVar ( ParseState pstate,
Var var 
)
extern

Definition at line 546 of file parse_relation.c.

547{
548 int sublevels_up = var->varlevelsup;
549 ListCell *lc;
550
551 while (sublevels_up-- > 0)
552 {
553 pstate = pstate->parentParseState;
554 Assert(pstate != NULL);
555 }
556 foreach(lc, pstate->p_namespace)
557 {
559
560 if (nsitem->p_rtindex == var->varno &&
561 nsitem->p_returning_type == var->varreturningtype)
562 return nsitem;
563 }
564 elog(ERROR, "nsitem not found (internal error)");
565 return NULL; /* keep compiler quiet */
566}
int varno
Definition primnodes.h:270
Index varlevelsup
Definition primnodes.h:295

References Assert, elog, ERROR, fb(), lfirst, ParseState::p_namespace, ParseState::parentParseState, Var::varlevelsup, Var::varno, and Var::varreturningtype.

Referenced by coerce_record_to_complex(), ExpandRowReference(), and ParseComplexProjection().

◆ GetRTEByRangeTablePosn()

RangeTblEntry * GetRTEByRangeTablePosn ( ParseState pstate,
int  varno,
int  sublevels_up 
)
extern

Definition at line 573 of file parse_relation.c.

576{
577 while (sublevels_up-- > 0)
578 {
579 pstate = pstate->parentParseState;
580 Assert(pstate != NULL);
581 }
582 Assert(varno > 0 && varno <= list_length(pstate->p_rtable));
583 return rt_fetch(varno, pstate->p_rtable);
584}
#define rt_fetch(rangetable_index, rangetable)
Definition parsetree.h:31

References Assert, fb(), list_length(), ParseState::p_rtable, ParseState::parentParseState, and rt_fetch.

Referenced by count_rowexpr_columns(), expandRecordVariable(), markTargetListOrigin(), and unknown_attribute().

◆ getRTEPermissionInfo()

RTEPermissionInfo * getRTEPermissionInfo ( List rteperminfos,
RangeTblEntry rte 
)
extern

Definition at line 4080 of file parse_relation.c.

4081{
4083
4084 if (rte->perminfoindex == 0 ||
4085 rte->perminfoindex > list_length(rteperminfos))
4086 elog(ERROR, "invalid perminfoindex %u in RTE with relid %u",
4087 rte->perminfoindex, rte->relid);
4089 rte->perminfoindex - 1);
4090 if (perminfo->relid != rte->relid)
4091 elog(ERROR, "permission info at index %u (with relid=%u) does not match provided RTE (with relid=%u)",
4092 rte->perminfoindex, perminfo->relid, rte->relid);
4093
4094 return perminfo;
4095}
#define list_nth_node(type, list, n)
Definition pg_list.h:359

References elog, ERROR, fb(), list_length(), and list_nth_node.

Referenced by add_rte_to_flat_rtable(), all_rows_selectable(), build_simple_rel(), ExecCheckPermissions(), expand_inherited_rtentry(), generate_query_for_graph_path(), get_rel_all_updated_cols(), get_row_security_policies(), GetResultRTEPermissionInfo(), markQueryForLocking(), markRTEForSelectPriv(), rewriteTargetView(), subquery_planner(), and transformLockingClause().

◆ isLockedRefname()

bool isLockedRefname ( ParseState pstate,
const char refname 
)
extern

Definition at line 2781 of file parse_relation.c.

2782{
2783 ListCell *l;
2784
2785 /*
2786 * If we are in a subquery specified as locked FOR UPDATE/SHARE from
2787 * parent level, then act as though there's a generic FOR UPDATE here.
2788 */
2789 if (pstate->p_locked_from_parent)
2790 return true;
2791
2792 foreach(l, pstate->p_locking_clause)
2793 {
2795
2796 if (lc->lockedRels == NIL)
2797 {
2798 /* all tables used in query */
2799 return true;
2800 }
2801 else if (refname != NULL)
2802 {
2803 /* just the named tables */
2804 ListCell *l2;
2805
2806 foreach(l2, lc->lockedRels)
2807 {
2808 RangeVar *thisrel = (RangeVar *) lfirst(l2);
2809
2810 if (strcmp(refname, thisrel->relname) == 0)
2811 return true;
2812 }
2813 }
2814 }
2815 return false;
2816}
bool p_locked_from_parent
Definition parse_node.h:236
List * p_locking_clause
Definition parse_node.h:235

References fb(), lfirst, NIL, ParseState::p_locked_from_parent, and ParseState::p_locking_clause.

Referenced by addRangeTableEntry(), and transformRangeSubselect().

◆ markNullableIfNeeded()

void markNullableIfNeeded ( ParseState pstate,
Var var 
)
extern

Definition at line 1078 of file parse_relation.c.

1079{
1080 int rtindex = var->varno;
1081 Bitmapset *relids;
1082
1083 /* Find the appropriate pstate */
1084 for (int lv = 0; lv < var->varlevelsup; lv++)
1085 pstate = pstate->parentParseState;
1086
1087 /* Find currently-relevant join relids for the Var's rel */
1088 if (rtindex > 0 && rtindex <= list_length(pstate->p_nullingrels))
1089 relids = (Bitmapset *) list_nth(pstate->p_nullingrels, rtindex - 1);
1090 else
1091 relids = NULL;
1092
1093 /*
1094 * Merge with any already-declared nulling rels. (Typically there won't
1095 * be any, but let's get it right if there are.)
1096 */
1097 if (relids != NULL)
1098 var->varnullingrels = bms_union(var->varnullingrels, relids);
1099}
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:251
List * p_nullingrels
Definition parse_node.h:219

References bms_union(), fb(), list_length(), list_nth(), ParseState::p_nullingrels, ParseState::parentParseState, Var::varlevelsup, and Var::varno.

Referenced by buildVarFromNSColumn(), expandNSItemVars(), scanNSItemForColumn(), and transformWholeRowRef().

◆ markVarForSelectPriv()

void markVarForSelectPriv ( ParseState pstate,
Var var 
)
extern

Definition at line 1193 of file parse_relation.c.

1194{
1195 Index lv;
1196
1197 Assert(IsA(var, Var));
1198 /* Find the appropriate pstate if it's an uplevel Var */
1199 for (lv = 0; lv < var->varlevelsup; lv++)
1200 pstate = pstate->parentParseState;
1201 markRTEForSelectPriv(pstate, var->varno, var->varattno);
1202}
static void markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col)
AttrNumber varattno
Definition primnodes.h:275

References Assert, fb(), IsA, markRTEForSelectPriv(), ParseState::parentParseState, Var::varattno, Var::varlevelsup, and Var::varno.

Referenced by expandNSItemAttrs(), ExpandSingleTable(), scanNSItemForColumn(), transformForPortionOfClause(), transformJoinUsingClause(), and transformWholeRowRef().

◆ parserOpenTable()

Relation parserOpenTable ( ParseState pstate,
const RangeVar relation,
LOCKMODE  lockmode 
)
extern

Definition at line 1459 of file parse_relation.c.

1460{
1461 Relation rel;
1463
1465 rel = table_openrv_extended(relation, lockmode, true);
1466 if (rel == NULL)
1467 {
1468 if (relation->schemaname)
1469 ereport(ERROR,
1471 errmsg("relation \"%s.%s\" does not exist",
1472 relation->schemaname, relation->relname)));
1473 else
1474 {
1475 /*
1476 * An unqualified name might have been meant as a reference to
1477 * some not-yet-in-scope CTE. The bare "does not exist" message
1478 * has proven remarkably unhelpful for figuring out such problems,
1479 * so we take pains to offer a specific hint.
1480 */
1481 if (isFutureCTE(pstate, relation->relname))
1482 ereport(ERROR,
1484 errmsg("relation \"%s\" does not exist",
1485 relation->relname),
1486 errdetail("There is a WITH item named \"%s\", but it cannot be referenced from this part of the query.",
1487 relation->relname),
1488 errhint("Use WITH RECURSIVE, or re-order the WITH items to remove forward references.")));
1489 else
1490 ereport(ERROR,
1492 errmsg("relation \"%s\" does not exist",
1493 relation->relname)));
1494 }
1495 }
1497 return rel;
1498}
void cancel_parser_errposition_callback(ParseCallbackState *pcbstate)
Definition parse_node.c:156
void setup_parser_errposition_callback(ParseCallbackState *pcbstate, ParseState *pstate, int location)
Definition parse_node.c:140
static bool isFutureCTE(ParseState *pstate, const char *refname)
char * schemaname
Definition primnodes.h:81
Relation table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok)
Definition table.c:103

References cancel_parser_errposition_callback(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errdetail(), errhint(), errmsg, ERROR, fb(), isFutureCTE(), RangeVar::location, RangeVar::relname, RangeVar::schemaname, setup_parser_errposition_callback(), and table_openrv_extended().

Referenced by addRangeTableEntry(), and setTargetTable().

◆ refnameNamespaceItem()

ParseNamespaceItem * refnameNamespaceItem ( ParseState pstate,
const char schemaname,
const char refname,
int  location,
int sublevels_up 
)
extern

Definition at line 130 of file parse_relation.c.

135{
136 Oid relId = InvalidOid;
137
138 if (sublevels_up)
139 *sublevels_up = 0;
140
141 if (schemaname != NULL)
142 {
144
145 /*
146 * We can use LookupNamespaceNoError() here because we are only
147 * interested in finding existing RTEs. Checking USAGE permission on
148 * the schema is unnecessary since it would have already been checked
149 * when the RTE was made. Furthermore, we want to report "RTE not
150 * found", not "no permissions for schema", if the name happens to
151 * match a schema name the user hasn't got access to.
152 */
155 return NULL;
156 relId = get_relname_relid(refname, namespaceId);
157 if (!OidIsValid(relId))
158 return NULL;
159 }
160
161 while (pstate != NULL)
162 {
164
165 if (OidIsValid(relId))
166 result = scanNameSpaceForRelid(pstate, relId, location);
167 else
168 result = scanNameSpaceForRefname(pstate, refname, location);
169
170 if (result)
171 return result;
172
173 if (sublevels_up)
174 (*sublevels_up)++;
175 else
176 break;
177
178 pstate = pstate->parentParseState;
179 }
180 return NULL;
181}
Oid get_relname_relid(const char *relname, Oid relnamespace)
Definition lsyscache.c:2191
Oid LookupNamespaceNoError(const char *nspname)
Definition namespace.c:3427
static ParseNamespaceItem * scanNameSpaceForRelid(ParseState *pstate, Oid relid, int location)
static ParseNamespaceItem * scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location)

References fb(), get_relname_relid(), InvalidOid, LookupNamespaceNoError(), OidIsValid, ParseState::parentParseState, result, scanNameSpaceForRefname(), and scanNameSpaceForRelid().

Referenced by errorMissingRTE(), ExpandColumnRefStar(), transformColumnRef(), and transformReturningClause().

◆ scanNameSpaceForCTE()

CommonTableExpr * scanNameSpaceForCTE ( ParseState pstate,
const char refname,
Index ctelevelsup 
)
extern

Definition at line 286 of file parse_relation.c.

288{
289 Index levelsup;
290
291 for (levelsup = 0;
292 pstate != NULL;
293 pstate = pstate->parentParseState, levelsup++)
294 {
295 ListCell *lc;
296
297 foreach(lc, pstate->p_ctenamespace)
298 {
300
301 if (strcmp(cte->ctename, refname) == 0)
302 {
303 *ctelevelsup = levelsup;
304 return cte;
305 }
306 }
307 }
308 return NULL;
309}

References CommonTableExpr::ctename, fb(), lfirst, ParseState::p_ctenamespace, and ParseState::parentParseState.

Referenced by getNSItemForSpecialRelationTypes(), and searchRangeTableForRel().

◆ scanNameSpaceForENR()

bool scanNameSpaceForENR ( ParseState pstate,
const char refname 
)
extern

Definition at line 339 of file parse_relation.c.

340{
341 return name_matches_visible_ENR(pstate, refname);
342}
bool name_matches_visible_ENR(ParseState *pstate, const char *refname)
Definition parse_enr.c:20

References name_matches_visible_ENR().

Referenced by getNSItemForSpecialRelationTypes(), searchRangeTableForRel(), and setTargetTable().

◆ scanNSItemForColumn()

Node * scanNSItemForColumn ( ParseState pstate,
ParseNamespaceItem nsitem,
int  sublevels_up,
const char colname,
int  location 
)
extern

Definition at line 716 of file parse_relation.c.

718{
719 RangeTblEntry *rte = nsitem->p_rte;
720 int attnum;
721 Var *var;
722
723 /*
724 * Scan the nsitem's column names (or aliases) for a match. Complain if
725 * multiple matches.
726 */
727 attnum = scanRTEForColumn(pstate, rte, nsitem->p_names,
728 colname, location,
729 0, NULL);
730
732 return NULL; /* Return NULL if no match */
733
734 /* In constraint check, no system column is allowed except tableOid */
739 errmsg("system column \"%s\" reference in check constraint is invalid",
740 colname),
741 parser_errposition(pstate, location)));
742
743 /*
744 * In generated column, no system column is allowed except tableOid.
745 * (Required for stored generated, but we also do it for virtual generated
746 * for now for consistency.)
747 */
752 errmsg("cannot use system column \"%s\" in column generation expression",
753 colname),
754 parser_errposition(pstate, location)));
755
756 /*
757 * In a MERGE WHEN condition, no system column is allowed except tableOid
758 */
759 if (pstate->p_expr_kind == EXPR_KIND_MERGE_WHEN &&
763 errmsg("cannot use system column \"%s\" in MERGE WHEN condition",
764 colname),
765 parser_errposition(pstate, location)));
766
767 /* Found a valid match, so build a Var */
769 {
770 /* Get attribute data from the ParseNamespaceColumn array */
771 ParseNamespaceColumn *nscol = &nsitem->p_nscolumns[attnum - 1];
772
773 /* Complain if dropped column. See notes in scanRTEForColumn. */
774 if (nscol->p_varno == 0)
777 errmsg("column \"%s\" of relation \"%s\" does not exist",
778 colname,
779 nsitem->p_names->aliasname)));
780
781 var = makeVar(nscol->p_varno,
782 nscol->p_varattno,
783 nscol->p_vartype,
784 nscol->p_vartypmod,
785 nscol->p_varcollid,
786 sublevels_up);
787 /* makeVar doesn't offer parameters for these, so set them by hand: */
788 var->varnosyn = nscol->p_varnosyn;
789 var->varattnosyn = nscol->p_varattnosyn;
790 }
791 else
792 {
793 /* System column, so use predetermined type data */
795
797 var = makeVar(nsitem->p_rtindex,
798 attnum,
799 sysatt->atttypid,
800 sysatt->atttypmod,
801 sysatt->attcollation,
802 sublevels_up);
803 }
804 var->location = location;
805
806 /* Mark Var for RETURNING OLD/NEW, as necessary */
807 var->varreturningtype = nsitem->p_returning_type;
808
809 /* Mark Var if it's nulled by any outer joins */
810 markNullableIfNeeded(pstate, var);
811
812 /* Require read access to the column */
813 markVarForSelectPriv(pstate, var);
814
815 return (Node *) var;
816}
@ EXPR_KIND_MERGE_WHEN
Definition parse_node.h:58
@ EXPR_KIND_GENERATED_COLUMN
Definition parse_node.h:84
@ EXPR_KIND_CHECK_CONSTRAINT
Definition parse_node.h:69
static int scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, Alias *eref, const char *colname, int location, int fuzzy_rte_penalty, FuzzyAttrMatchState *fuzzystate)
ParseExprKind p_expr_kind
Definition parse_node.h:232
#define TableOidAttributeNumber
Definition sysattr.h:26

References attnum, ereport, errcode(), errmsg, ERROR, EXPR_KIND_CHECK_CONSTRAINT, EXPR_KIND_GENERATED_COLUMN, EXPR_KIND_MERGE_WHEN, fb(), FormData_pg_attribute, InvalidAttrNumber, Var::location, makeVar(), markNullableIfNeeded(), markVarForSelectPriv(), ParseState::p_expr_kind, parser_errposition(), scanRTEForColumn(), SystemAttributeDefinition(), TableOidAttributeNumber, and Var::varreturningtype.

Referenced by colNameToVar(), ParseComplexProjection(), and transformColumnRef().