@@ -1577,7 +1577,11 @@ addRangeTableEntryForRelation(ParseState *pstate,
15771577 * Then, construct and return a ParseNamespaceItem for the new RTE.
15781578 *
15791579 * This is much like addRangeTableEntry() except that it makes a subquery RTE.
1580- * Note that an alias clause *must* be supplied.
1580+ *
1581+ * If the subquery does not have an alias, the auto-generated relation name in
1582+ * the returned ParseNamespaceItem will be marked as not visible, and so only
1583+ * unqualified references to the subquery columns will be allowed, and the
1584+ * relation name will not conflict with others in the pstate's namespace list.
15811585 */
15821586ParseNamespaceItem *
15831587addRangeTableEntryForSubquery (ParseState * pstate ,
@@ -1587,22 +1591,22 @@ addRangeTableEntryForSubquery(ParseState *pstate,
15871591 bool inFromCl )
15881592{
15891593 RangeTblEntry * rte = makeNode (RangeTblEntry );
1590- char * refname = alias -> aliasname ;
15911594 Alias * eref ;
15921595 int numaliases ;
15931596 List * coltypes ,
15941597 * coltypmods ,
15951598 * colcollations ;
15961599 int varattno ;
15971600 ListCell * tlistitem ;
1601+ ParseNamespaceItem * nsitem ;
15981602
15991603 Assert (pstate != NULL );
16001604
16011605 rte -> rtekind = RTE_SUBQUERY ;
16021606 rte -> subquery = subquery ;
16031607 rte -> alias = alias ;
16041608
1605- eref = copyObject (alias );
1609+ eref = alias ? copyObject (alias ) : makeAlias ( "unnamed_subquery" , NIL );
16061610 numaliases = list_length (eref -> colnames );
16071611
16081612 /* fill in any unspecified alias columns, and extract column type info */
@@ -1634,7 +1638,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
16341638 ereport (ERROR ,
16351639 (errcode (ERRCODE_INVALID_COLUMN_REFERENCE ),
16361640 errmsg ("table \"%s\" has %d columns available but %d columns specified" ,
1637- refname , varattno , numaliases )));
1641+ eref -> aliasname , varattno , numaliases )));
16381642
16391643 rte -> eref = eref ;
16401644
@@ -1665,8 +1669,15 @@ addRangeTableEntryForSubquery(ParseState *pstate,
16651669 * Build a ParseNamespaceItem, but don't add it to the pstate's namespace
16661670 * list --- caller must do that if appropriate.
16671671 */
1668- return buildNSItemFromLists (rte , list_length (pstate -> p_rtable ),
1669- coltypes , coltypmods , colcollations );
1672+ nsitem = buildNSItemFromLists (rte , list_length (pstate -> p_rtable ),
1673+ coltypes , coltypmods , colcollations );
1674+
1675+ /*
1676+ * Mark it visible as a relation name only if it had a user-written alias.
1677+ */
1678+ nsitem -> p_rel_visible = (alias != NULL );
1679+
1680+ return nsitem ;
16701681}
16711682
16721683/*
@@ -2520,6 +2531,10 @@ addRangeTableEntryForENR(ParseState *pstate,
25202531 * This is used when we have not yet done transformLockingClause, but need
25212532 * to know the correct lock to take during initial opening of relations.
25222533 *
2534+ * Note that refname may be NULL (for a subquery without an alias), in which
2535+ * case the relation can't be locked by name, but it might still be locked if
2536+ * a locking clause requests that all tables be locked.
2537+ *
25232538 * Note: we pay no attention to whether it's FOR UPDATE vs FOR SHARE,
25242539 * since the table-level lock is the same either way.
25252540 */
@@ -2544,7 +2559,7 @@ isLockedRefname(ParseState *pstate, const char *refname)
25442559 /* all tables used in query */
25452560 return true;
25462561 }
2547- else
2562+ else if ( refname != NULL )
25482563 {
25492564 /* just the named tables */
25502565 ListCell * l2 ;
0 commit comments