/*-------------------------------------------------------------------------
 *
 * parse_target.c
 *	  handle target lists
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/parser/parse_target.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "parser/parsetree.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/typcache.h"

static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
								 Var *var, int levelsup);
static Node *transformAssignmentSubscripts(ParseState *pstate,
										   Node *basenode,
										   const char *targetName,
										   Oid targetTypeId,
										   int32 targetTypMod,
										   Oid targetCollation,
										   List *subscripts,
										   List *indirection,
										   ListCell *next_indirection,
										   Node *rhs,
										   CoercionContext ccontext,
										   int location);
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
								 bool make_target_entry);
static List *ExpandAllTables(ParseState *pstate, int location);
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
								   bool make_target_entry, ParseExprKind exprKind);
static List *ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem,
							   int sublevels_up, int location,
							   bool make_target_entry);
static List *ExpandRowReference(ParseState *pstate, Node *expr,
								bool make_target_entry);
static int	FigureColnameInternal(Node *node, char **name);


/*
 * transformTargetEntry()
 *	Transform any ordinary "expression-type" node into a targetlist entry.
 *	This is exported so that parse_clause.c can generate targetlist entries
 *	for ORDER/GROUP BY items that are not already in the targetlist.
 *
 * node		the (untransformed) parse tree for the value expression.
 * expr		the transformed expression, or NULL if caller didn't do it yet.
 * exprKind expression kind (EXPR_KIND_SELECT_TARGET, etc)
 * colname	the column name to be assigned, or NULL if none yet set.
 * resjunk	true if the target should be marked resjunk, ie, it is not
 *			wanted in the final projected tuple.
 */
TargetEntry *
transformTargetEntry(ParseState *pstate,
					 Node *node,
					 Node *expr,
					 ParseExprKind exprKind,
					 char *colname,
					 bool resjunk)
{
	/* Transform the node if caller didn't do it already */
	if (expr == NULL)
	{
		/*
		 * If it's a SetToDefault node and we should allow that, pass it
		 * through unmodified.  (transformExpr will throw the appropriate
		 * error if we're disallowing it.)
		 */
		if (exprKind == EXPR_KIND_UPDATE_SOURCE && IsA(node, SetToDefault))
			expr = node;
		else
			expr = transformExpr(pstate, node, exprKind);
	}

	if (colname == NULL && !resjunk)
	{
		/*
		 * Generate a suitable column name for a column without any explicit
		 * 'AS ColumnName' clause.
		 */
		colname = FigureColname(node);
	}

	return makeTargetEntry((Expr *) expr,
						   (AttrNumber) pstate->p_next_resno++,
						   colname,
						   resjunk);
}


/*
 * transformTargetList()
 * Turns a list of ResTarget's into a list of TargetEntry's.
 *
 * This code acts mostly the same for SELECT, UPDATE, or RETURNING lists;
 * the main thing is to transform the given expressions (the "val" fields).
 * The exprKind parameter distinguishes these cases when necessary.
 */
List *
transformTargetList(ParseState *pstate, List *targetlist,
					ParseExprKind exprKind)
{
	List	   *p_target = NIL;
	bool		expand_star;
	ListCell   *o_target;

	/* Shouldn't have any leftover multiassign items at start */
	Assert(pstate->p_multiassign_exprs == NIL);

	/* Expand "something.*" in SELECT and RETURNING, but not UPDATE */
	expand_star = (exprKind != EXPR_KIND_UPDATE_SOURCE);

	foreach(o_target, targetlist)
	{
		ResTarget  *res = (ResTarget *) lfirst(o_target);

		/*
		 * Check for "something.*".  Depending on the complexity of the
		 * "something", the star could appear as the last field in ColumnRef,
		 * or as the last indirection item in A_Indirection.
		 */
		if (expand_star)
		{
			if (IsA(res->val, ColumnRef))
			{
				ColumnRef  *cref = (ColumnRef *) res->val;

				if (IsA(llast(cref->fields), A_Star))
				{
					/* It is something.*, expand into multiple items */
					p_target = list_concat(p_target,
										   ExpandColumnRefStar(pstate,
															   cref,
															   true));
					continue;
				}
			}
			else if (IsA(res->val, A_Indirection))
			{
				A_Indirection *ind = (A_Indirection *) res->val;

				if (IsA(llast(ind->indirection), A_Star))
				{
					/* It is something.*, expand into multiple items */
					p_target = list_concat(p_target,
										   ExpandIndirectionStar(pstate,
																 ind,
																 true,
																 exprKind));
					continue;
				}
			}
		}

		/*
		 * Not "something.*", or we want to treat that as a plain whole-row
		 * variable, so transform as a single expression
		 */
		p_target = lappend(p_target,
						   transformTargetEntry(pstate,
												res->val,
												NULL,
												exprKind,
												res->name,
												false));
	}

	/*
	 * If any multiassign resjunk items were created, attach them to the end
	 * of the targetlist.  This should only happen in an UPDATE tlist.  We
	 * don't need to worry about numbering of these items; transformUpdateStmt
	 * will set their resnos.
	 */
	if (pstate->p_multiassign_exprs)
	{
		Assert(exprKind == EXPR_KIND_UPDATE_SOURCE);
		p_target = list_concat(p_target, pstate->p_multiassign_exprs);
		pstate->p_multiassign_exprs = NIL;
	}

	return p_target;
}


/*
 * transformExpressionList()
 *
 * This is the identical transformation to transformTargetList, except that
 * the input list elements are bare expressions without ResTarget decoration,
 * and the output elements are likewise just expressions without TargetEntry
 * decoration.  Also, we don't expect any multiassign constructs within the
 * list, so there's nothing to do for that.  We use this for ROW() and
 * VALUES() constructs.
 *
 * exprKind is not enough to tell us whether to allow SetToDefault, so
 * an additional flag is needed for that.
 */
List *
transformExpressionList(ParseState *pstate, List *exprlist,
						ParseExprKind exprKind, bool allowDefault)
{
	List	   *result = NIL;
	ListCell   *lc;

	foreach(lc, exprlist)
	{
		Node	   *e = (Node *) lfirst(lc);

		/*
		 * Check for "something.*".  Depending on the complexity of the
		 * "something", the star could appear as the last field in ColumnRef,
		 * or as the last indirection item in A_Indirection.
		 */
		if (IsA(e, ColumnRef))
		{
			ColumnRef  *cref = (ColumnRef *) e;

			if (IsA(llast(cref->fields), A_Star))
			{
				/* It is something.*, expand into multiple items */
				result = list_concat(result,
									 ExpandColumnRefStar(pstate, cref,
														 false));
				continue;
			}
		}
		else if (IsA(e, A_Indirection))
		{
			A_Indirection *ind = (A_Indirection *) e;

			if (IsA(llast(ind->indirection), A_Star))
			{
				/* It is something.*, expand into multiple items */
				result = list_concat(result,
									 ExpandIndirectionStar(pstate, ind,
														   false, exprKind));
				continue;
			}
		}

		/*
		 * Not "something.*", so transform as a single expression.  If it's a
		 * SetToDefault node and we should allow that, pass it through
		 * unmodified.  (transformExpr will throw the appropriate error if
		 * we're disallowing it.)
		 */
		if (allowDefault && IsA(e, SetToDefault))
			 /* do nothing */ ;
		else
			e = transformExpr(pstate, e, exprKind);

		result = lappend(result, e);
	}

	return result;
}


/*
 * resolveTargetListUnknowns()
 *		Convert any unknown-type targetlist entries to type TEXT.
 *
 * We do this after we've exhausted all other ways of identifying the output
 * column types of a query.
 */
void
resolveTargetListUnknowns(ParseState *pstate, List *targetlist)
{
	ListCell   *l;

	foreach(l, targetlist)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(l);
		Oid			restype = exprType((Node *) tle->expr);

		if (restype == UNKNOWNOID)
		{
			tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
											 restype, TEXTOID, -1,
											 COERCION_IMPLICIT,
											 COERCE_IMPLICIT_CAST,
											 -1);
		}
	}
}


/*
 * markTargetListOrigins()
 *		Mark targetlist columns that are simple Vars with the source
 *		table's OID and column number.
 *
 * Currently, this is done only for SELECT targetlists and RETURNING lists,
 * since we only need the info if we are going to send it to the frontend.
 */
void
markTargetListOrigins(ParseState *pstate, List *targetlist)
{
	ListCell   *l;

	foreach(l, targetlist)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(l);

		markTargetListOrigin(pstate, tle, (Var *) tle->expr, 0);
	}
}

/*
 * markTargetListOrigin()
 *		If 'var' is a Var of a plain relation, mark 'tle' with its origin
 *
 * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
 *
 * Note that we do not drill down into views, but report the view as the
 * column owner.  There's also no need to drill down into joins: if we see
 * a join alias Var, it must be a merged JOIN USING column (or possibly a
 * whole-row Var); that is not a direct reference to any plain table column,
 * so we don't report it.
 */
static void
markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
					 Var *var, int levelsup)
{
	int			netlevelsup;
	RangeTblEntry *rte;
	AttrNumber	attnum;

	if (var == NULL || !IsA(var, Var))
		return;
	netlevelsup = var->varlevelsup + levelsup;
	rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
	attnum = var->varattno;

	switch (rte->rtekind)
	{
		case RTE_RELATION:
			/* It's a table or view, report it */
			tle->resorigtbl = rte->relid;
			tle->resorigcol = attnum;
			break;
		case RTE_SUBQUERY:
			/* Subselect-in-FROM: copy up from the subselect */
			if (attnum != InvalidAttrNumber)
			{
				TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
													attnum);

				if (ste == NULL || ste->resjunk)
					elog(ERROR, "subquery %s does not have attribute %d",
						 rte->eref->aliasname, attnum);
				tle->resorigtbl = ste->resorigtbl;
				tle->resorigcol = ste->resorigcol;
			}
			break;
		case RTE_JOIN:
		case RTE_FUNCTION:
		case RTE_VALUES:
		case RTE_TABLEFUNC:
		case RTE_NAMEDTUPLESTORE:
		case RTE_RESULT:
		case RTE_VOID:
		case RTE_TABLEFUNCTION:
			/* not a simple relation, leave it unmarked */
			break;
		case RTE_CTE:

			/*
			 * CTE reference: copy up from the subquery, if possible. If the
			 * RTE is a recursive self-reference then we can't do anything
			 * because we haven't finished analyzing it yet. However, it's no
			 * big loss because we must be down inside the recursive term of a
			 * recursive CTE, and so any markings on the current targetlist
			 * are not going to affect the results anyway.
			 */
			if (attnum != InvalidAttrNumber && !rte->self_reference)
			{
				CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
				TargetEntry *ste;
				List	   *tl = GetCTETargetList(cte);
				int			extra_cols = 0;

				/*
				 * RTE for CTE will already have the search and cycle columns
				 * added, but the subquery won't, so skip looking those up.
				 */
				if (cte->search_clause)
					extra_cols += 1;
				if (cte->cycle_clause)
					extra_cols += 2;
				if (extra_cols &&
					attnum > list_length(tl) &&
					attnum <= list_length(tl) + extra_cols)
					break;

				ste = get_tle_by_resno(tl, attnum);
				if (ste == NULL || ste->resjunk)
					elog(ERROR, "CTE %s does not have attribute %d",
						 rte->eref->aliasname, attnum);
				tle->resorigtbl = ste->resorigtbl;
				tle->resorigcol = ste->resorigcol;
			}
			break;
	}
}


/*
 * transformAssignedExpr()
 *	This is used in INSERT and UPDATE statements only.  It prepares an
 *	expression for assignment to a column of the target table.
 *	This includes coercing the given value to the target column's type
 *	(if necessary), and dealing with any subfield names or subscripts
 *	attached to the target column itself.  The input expression has
 *	already been through transformExpr().
 *
 * pstate		parse state
 * expr			expression to be modified
 * exprKind		indicates which type of statement we're dealing with
 * colname		target column name (ie, name of attribute to be assigned to)
 * attrno		target attribute number
 * indirection	subscripts/field names for target column, if any
 * location		error cursor position for the target column, or -1
 *
 * Returns the modified expression.
 *
 * Note: location points at the target column name (SET target or INSERT
 * column name list entry), and must therefore be -1 in an INSERT that
 * omits the column name list.  So we should usually prefer to use
 * exprLocation(expr) for errors that can happen in a default INSERT.
 */
Expr *
transformAssignedExpr(ParseState *pstate,
					  Expr *expr,
					  ParseExprKind exprKind,
					  const char *colname,
					  int attrno,
					  List *indirection,
					  int location)
{
	Relation	rd = pstate->p_target_relation;
	Oid			type_id;		/* type of value provided */
	Oid			attrtype;		/* type of target column */
	int32		attrtypmod;
	Oid			attrcollation;	/* collation of target column */
	ParseExprKind sv_expr_kind;

	/*
	 * Save and restore identity of expression type we're parsing.  We must
	 * set p_expr_kind here because we can parse subscripts without going
	 * through transformExpr().
	 */
	Assert(exprKind != EXPR_KIND_NONE);
	sv_expr_kind = pstate->p_expr_kind;
	pstate->p_expr_kind = exprKind;

	Assert(rd != NULL);
	if (attrno <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot assign to system column \"%s\"",
						colname),
				 parser_errposition(pstate, location)));
	attrtype = attnumTypeId(rd, attrno);
	attrtypmod = TupleDescAttr(rd->rd_att, attrno - 1)->atttypmod;
	attrcollation = TupleDescAttr(rd->rd_att, attrno - 1)->attcollation;

	/*
	 * If the expression is a DEFAULT placeholder, insert the attribute's
	 * type/typmod/collation into it so that exprType etc will report the
	 * right things.  (We expect that the eventually substituted default
	 * expression will in fact have this type and typmod.  The collation
	 * likely doesn't matter, but let's set it correctly anyway.)  Also,
	 * reject trying to update a subfield or array element with DEFAULT, since
	 * there can't be any default for portions of a column.
	 */
	if (expr && IsA(expr, SetToDefault))
	{
		SetToDefault *def = (SetToDefault *) expr;

		def->typeId = attrtype;
		def->typeMod = attrtypmod;
		def->collation = attrcollation;
		if (indirection)
		{
			if (IsA(linitial(indirection), A_Indices))
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot set an array element to DEFAULT"),
						 parser_errposition(pstate, location)));
			else
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot set a subfield to DEFAULT"),
						 parser_errposition(pstate, location)));
		}
	}

	/* Now we can use exprType() safely. */
	type_id = exprType((Node *) expr);

	/*
	 * If there is indirection on the target column, prepare an array or
	 * subfield assignment expression.  This will generate a new column value
	 * that the source value has been inserted into, which can then be placed
	 * in the new tuple constructed by INSERT or UPDATE.
	 */
	if (indirection)
	{
		Node	   *colVar;

		if (pstate->p_is_insert)
		{
			/*
			 * The command is INSERT INTO table (col.something) ... so there
			 * is not really a source value to work with. Insert a NULL
			 * constant as the source value.
			 */
			colVar = (Node *) makeNullConst(attrtype, attrtypmod,
											attrcollation);
		}
		else
		{
			/*
			 * Build a Var for the column to be updated.
			 */
			Var		   *var;

			var = makeVar(pstate->p_target_nsitem->p_rtindex, attrno,
						  attrtype, attrtypmod, attrcollation, 0);
			var->location = location;

			colVar = (Node *) var;
		}

		expr = (Expr *)
			transformAssignmentIndirection(pstate,
										   colVar,
										   colname,
										   false,
										   attrtype,
										   attrtypmod,
										   attrcollation,
										   indirection,
										   list_head(indirection),
										   (Node *) expr,
										   COERCION_ASSIGNMENT,
										   location);
	}
	else
	{
		/*
		 * For normal non-qualified target column, do type checking and
		 * coercion.
		 */
		Node	   *orig_expr = (Node *) expr;

		expr = (Expr *)
			coerce_to_target_type(pstate,
								  orig_expr, type_id,
								  attrtype, attrtypmod,
								  COERCION_ASSIGNMENT,
								  COERCE_IMPLICIT_CAST,
								  -1);
		if (expr == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("column \"%s\" is of type %s"
							" but expression is of type %s",
							colname,
							format_type_be(attrtype),
							format_type_be(type_id)),
					 errhint("You will need to rewrite or cast the expression."),
					 parser_errposition(pstate, exprLocation(orig_expr))));
	}

	pstate->p_expr_kind = sv_expr_kind;

	return expr;
}


/*
 * updateTargetListEntry()
 *	This is used in UPDATE statements (and ON CONFLICT DO UPDATE)
 *	only.  It prepares an UPDATE TargetEntry for assignment to a
 *	column of the target table.  This includes coercing the given
 *	value to the target column's type (if necessary), and dealing with
 *	any subfield names or subscripts attached to the target column
 *	itself.
 *
 * pstate		parse state
 * tle			target list entry to be modified
 * colname		target column name (ie, name of attribute to be assigned to)
 * attrno		target attribute number
 * indirection	subscripts/field names for target column, if any
 * location		error cursor position (should point at column name), or -1
 */
void
updateTargetListEntry(ParseState *pstate,
					  TargetEntry *tle,
					  char *colname,
					  int attrno,
					  List *indirection,
					  int location)
{
	/* Fix up expression as needed */
	tle->expr = transformAssignedExpr(pstate,
									  tle->expr,
									  EXPR_KIND_UPDATE_TARGET,
									  colname,
									  attrno,
									  indirection,
									  location);

	/*
	 * Set the resno to identify the target column --- the rewriter and
	 * planner depend on this.  We also set the resname to identify the target
	 * column, but this is only for debugging purposes; it should not be
	 * relied on.  (In particular, it might be out of date in a stored rule.)
	 */
	tle->resno = (AttrNumber) attrno;
	tle->resname = colname;
}


/*
 * Process indirection (field selection or subscripting) of the target
 * column in INSERT/UPDATE/assignment.  This routine recurses for multiple
 * levels of indirection --- but note that several adjacent A_Indices nodes
 * in the indirection list are treated as a single multidimensional subscript
 * operation.
 *
 * In the initial call, basenode is a Var for the target column in UPDATE,
 * or a null Const of the target's type in INSERT, or a Param for the target
 * variable in PL/pgSQL assignment.  In recursive calls, basenode is NULL,
 * indicating that a substitute node should be consed up if needed.
 *
 * targetName is the name of the field or subfield we're assigning to, and
 * targetIsSubscripting is true if we're subscripting it.  These are just for
 * error reporting.
 *
 * targetTypeId, targetTypMod, targetCollation indicate the datatype and
 * collation of the object to be assigned to (initially the target column,
 * later some subobject).
 *
 * indirection is the list of indirection nodes, and indirection_cell is the
 * start of the sublist remaining to process.  When it's NULL, we're done
 * recursing and can just coerce and return the RHS.
 *
 * rhs is the already-transformed value to be assigned; note it has not been
 * coerced to any particular type.
 *
 * ccontext is the coercion level to use while coercing the rhs.  For
 * normal statements it'll be COERCION_ASSIGNMENT, but PL/pgSQL uses
 * a special value.
 *
 * location is the cursor error position for any errors.  (Note: this points
 * to the head of the target clause, eg "foo" in "foo.bar[baz]".  Later we
 * might want to decorate indirection cells with their own location info,
 * in which case the location argument could probably be dropped.)
 */
Node *
transformAssignmentIndirection(ParseState *pstate,
							   Node *basenode,
							   const char *targetName,
							   bool targetIsSubscripting,
							   Oid targetTypeId,
							   int32 targetTypMod,
							   Oid targetCollation,
							   List *indirection,
							   ListCell *indirection_cell,
							   Node *rhs,
							   CoercionContext ccontext,
							   int location)
{
	Node	   *result;
	List	   *subscripts = NIL;
	ListCell   *i;

	if (indirection_cell && !basenode)
	{
		/*
		 * Set up a substitution.  We abuse CaseTestExpr for this.  It's safe
		 * to do so because the only nodes that will be above the CaseTestExpr
		 * in the finished expression will be FieldStore and SubscriptingRef
		 * nodes. (There could be other stuff in the tree, but it will be
		 * within other child fields of those node types.)
		 */
		CaseTestExpr *ctest = makeNode(CaseTestExpr);

		ctest->typeId = targetTypeId;
		ctest->typeMod = targetTypMod;
		ctest->collation = targetCollation;
		basenode = (Node *) ctest;
	}

	/*
	 * We have to split any field-selection operations apart from
	 * subscripting.  Adjacent A_Indices nodes have to be treated as a single
	 * multidimensional subscript operation.
	 */
	for_each_cell(i, indirection, indirection_cell)
	{
		Node	   *n = lfirst(i);

		if (IsA(n, A_Indices))
			subscripts = lappend(subscripts, n);
		else if (IsA(n, A_Star))
		{
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("row expansion via \"*\" is not supported here"),
					 parser_errposition(pstate, location)));
		}
		else
		{
			FieldStore *fstore;
			Oid			baseTypeId;
			int32		baseTypeMod;
			Oid			typrelid;
			AttrNumber	attnum;
			Oid			fieldTypeId;
			int32		fieldTypMod;
			Oid			fieldCollation;

			Assert(IsA(n, String));

			/* process subscripts before this field selection */
			if (subscripts)
			{
				/* recurse, and then return because we're done */
				return transformAssignmentSubscripts(pstate,
													 basenode,
													 targetName,
													 targetTypeId,
													 targetTypMod,
													 targetCollation,
													 subscripts,
													 indirection,
													 i,
													 rhs,
													 ccontext,
													 location);
			}

			/* No subscripts, so can process field selection here */

			/*
			 * Look up the composite type, accounting for possibility that
			 * what we are given is a domain over composite.
			 */
			baseTypeMod = targetTypMod;
			baseTypeId = getBaseTypeAndTypmod(targetTypeId, &baseTypeMod);

			typrelid = typeidTypeRelid(baseTypeId);
			if (!typrelid)
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type",
								strVal(n), targetName,
								format_type_be(targetTypeId)),
						 parser_errposition(pstate, location)));

			attnum = get_attnum(typrelid, strVal(n));
			if (attnum == InvalidAttrNumber)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_COLUMN),
						 errmsg("cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s",
								strVal(n), targetName,
								format_type_be(targetTypeId)),
						 parser_errposition(pstate, location)));
			if (attnum < 0)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_COLUMN),
						 errmsg("cannot assign to system column \"%s\"",
								strVal(n)),
						 parser_errposition(pstate, location)));

			get_atttypetypmodcoll(typrelid, attnum,
								  &fieldTypeId, &fieldTypMod, &fieldCollation);

			/* recurse to create appropriate RHS for field assign */
			rhs = transformAssignmentIndirection(pstate,
												 NULL,
												 strVal(n),
												 false,
												 fieldTypeId,
												 fieldTypMod,
												 fieldCollation,
												 indirection,
												 lnext(indirection, i),
												 rhs,
												 ccontext,
												 location);

			/* and build a FieldStore node */
			fstore = makeNode(FieldStore);
			fstore->arg = (Expr *) basenode;
			fstore->newvals = list_make1(rhs);
			fstore->fieldnums = list_make1_int(attnum);
			fstore->resulttype = baseTypeId;

			/*
			 * If target is a domain, apply constraints.  Notice that this
			 * isn't totally right: the expression tree we build would check
			 * the domain's constraints on a composite value with only this
			 * one field populated or updated, possibly leading to an unwanted
			 * failure.  The rewriter will merge together any subfield
			 * assignments to the same table column, resulting in the domain's
			 * constraints being checked only once after we've assigned to all
			 * the fields that the INSERT or UPDATE means to.
			 */
			if (baseTypeId != targetTypeId)
				return coerce_to_domain((Node *) fstore,
										baseTypeId, baseTypeMod,
										targetTypeId,
										COERCION_IMPLICIT,
										COERCE_IMPLICIT_CAST,
										location,
										false);

			return (Node *) fstore;
		}
	}

	/* process trailing subscripts, if any */
	if (subscripts)
	{
		/* recurse, and then return because we're done */
		return transformAssignmentSubscripts(pstate,
											 basenode,
											 targetName,
											 targetTypeId,
											 targetTypMod,
											 targetCollation,
											 subscripts,
											 indirection,
											 NULL,
											 rhs,
											 ccontext,
											 location);
	}

	/* base case: just coerce RHS to match target type ID */

	result = coerce_to_target_type(pstate,
								   rhs, exprType(rhs),
								   targetTypeId, targetTypMod,
								   ccontext,
								   COERCE_IMPLICIT_CAST,
								   -1);
	if (result == NULL)
	{
		if (targetIsSubscripting)
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("subscripted assignment to \"%s\" requires type %s"
							" but expression is of type %s",
							targetName,
							format_type_be(targetTypeId),
							format_type_be(exprType(rhs))),
					 errhint("You will need to rewrite or cast the expression."),
					 parser_errposition(pstate, location)));
		else
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("subfield \"%s\" is of type %s"
							" but expression is of type %s",
							targetName,
							format_type_be(targetTypeId),
							format_type_be(exprType(rhs))),
					 errhint("You will need to rewrite or cast the expression."),
					 parser_errposition(pstate, location)));
	}

	return result;
}

/*
 * helper for transformAssignmentIndirection: process container assignment
 */
static Node *
transformAssignmentSubscripts(ParseState *pstate,
							  Node *basenode,
							  const char *targetName,
							  Oid targetTypeId,
							  int32 targetTypMod,
							  Oid targetCollation,
							  List *subscripts,
							  List *indirection,
							  ListCell *next_indirection,
							  Node *rhs,
							  CoercionContext ccontext,
							  int location)
{
	Node	   *result;
	SubscriptingRef *sbsref;
	Oid			containerType;
	int32		containerTypMod;
	Oid			typeNeeded;
	int32		typmodNeeded;
	Oid			collationNeeded;

	Assert(subscripts != NIL);

	/* Identify the actual container type involved */
	containerType = targetTypeId;
	containerTypMod = targetTypMod;
	transformContainerType(&containerType, &containerTypMod);

	/* Process subscripts and identify required type for RHS */
	sbsref = transformContainerSubscripts(pstate,
										  basenode,
										  containerType,
										  containerTypMod,
										  subscripts,
										  true);

	typeNeeded = sbsref->refrestype;
	typmodNeeded = sbsref->reftypmod;

	/*
	 * Container normally has same collation as its elements, but there's an
	 * exception: we might be subscripting a domain over a container type.  In
	 * that case use collation of the base type.  (This is shaky for arbitrary
	 * subscripting semantics, but it doesn't matter all that much since we
	 * only use this to label the collation of a possible CaseTestExpr.)
	 */
	if (containerType == targetTypeId)
		collationNeeded = targetCollation;
	else
		collationNeeded = get_typcollation(containerType);

	/* recurse to create appropriate RHS for container assign */
	rhs = transformAssignmentIndirection(pstate,
										 NULL,
										 targetName,
										 true,
										 typeNeeded,
										 typmodNeeded,
										 collationNeeded,
										 indirection,
										 next_indirection,
										 rhs,
										 ccontext,
										 location);

	/*
	 * Insert the already-properly-coerced RHS into the SubscriptingRef.  Then
	 * set refrestype and reftypmod back to the container type's values.
	 */
	sbsref->refassgnexpr = (Expr *) rhs;
	sbsref->refrestype = containerType;
	sbsref->reftypmod = containerTypMod;

	result = (Node *) sbsref;

	/*
	 * If target was a domain over container, need to coerce up to the domain.
	 * As in transformAssignmentIndirection, this coercion is premature if the
	 * query assigns to multiple elements of the container; but we'll fix that
	 * during query rewrite.
	 */
	if (containerType != targetTypeId)
	{
		Oid			resulttype = exprType(result);

		result = coerce_to_target_type(pstate,
									   result, resulttype,
									   targetTypeId, targetTypMod,
									   ccontext,
									   COERCE_IMPLICIT_CAST,
									   -1);
		/* can fail if we had int2vector/oidvector, but not for true domains */
		if (result == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_CANNOT_COERCE),
					 errmsg("cannot cast type %s to %s",
							format_type_be(resulttype),
							format_type_be(targetTypeId)),
					 parser_errposition(pstate, location)));
	}

	return result;
}


/*
 * checkInsertTargets -
 *	  generate a list of INSERT column targets if not supplied, or
 *	  test supplied column names to make sure they are in target table.
 *	  Also return an integer list of the columns' attribute numbers.
 */
List *
checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
{
	*attrnos = NIL;

	if (cols == NIL)
	{
		/*
		 * Generate default column list for INSERT.
		 */
		int			numcol = RelationGetNumberOfAttributes(pstate->p_target_relation);

		int			i;

		for (i = 0; i < numcol; i++)
		{
			ResTarget  *col;
			Form_pg_attribute attr;

			attr = TupleDescAttr(pstate->p_target_relation->rd_att, i);

			if (attr->attisdropped)
				continue;

			col = makeNode(ResTarget);
			col->name = pstrdup(NameStr(attr->attname));
			col->indirection = NIL;
			col->val = NULL;
			col->location = -1;
			cols = lappend(cols, col);
			*attrnos = lappend_int(*attrnos, i + 1);
		}
	}
	else
	{
		/*
		 * Do initial validation of user-supplied INSERT column list.
		 */
		Bitmapset  *wholecols = NULL;
		Bitmapset  *partialcols = NULL;
		ListCell   *tl;

		foreach(tl, cols)
		{
			ResTarget  *col = (ResTarget *) lfirst(tl);
			char	   *name = col->name;
			int			attrno;

			/* Lookup column name, ereport on failure */
			attrno = attnameAttNum(pstate->p_target_relation, name, false);
			if (attrno == InvalidAttrNumber)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_COLUMN),
						 errmsg("column \"%s\" of relation \"%s\" does not exist",
								name,
								RelationGetRelationName(pstate->p_target_relation)),
						 parser_errposition(pstate, col->location)));

			/*
			 * Check for duplicates, but only of whole columns --- we allow
			 * INSERT INTO foo (col.subcol1, col.subcol2)
			 */
			if (col->indirection == NIL)
			{
				/* whole column; must not have any other assignment */
				if (bms_is_member(attrno, wholecols) ||
					bms_is_member(attrno, partialcols))
					ereport(ERROR,
							(errcode(ERRCODE_DUPLICATE_COLUMN),
							 errmsg("column \"%s\" specified more than once",
									name),
							 parser_errposition(pstate, col->location)));
				wholecols = bms_add_member(wholecols, attrno);
			}
			else
			{
				/* partial column; must not have any whole assignment */
				if (bms_is_member(attrno, wholecols))
					ereport(ERROR,
							(errcode(ERRCODE_DUPLICATE_COLUMN),
							 errmsg("column \"%s\" specified more than once",
									name),
							 parser_errposition(pstate, col->location)));
				partialcols = bms_add_member(partialcols, attrno);
			}

			*attrnos = lappend_int(*attrnos, attrno);
		}
	}

	return cols;
}

/*
 * ExpandColumnRefStar()
 *		Transforms foo.* into a list of expressions or targetlist entries.
 *
 * This handles the case where '*' appears as the last or only item in a
 * ColumnRef.  The code is shared between the case of foo.* at the top level
 * in a SELECT target list (where we want TargetEntry nodes in the result)
 * and foo.* in a ROW() or VALUES() construct (where we want just bare
 * expressions).
 *
 * The referenced columns are marked as requiring SELECT access.
 */
static List *
ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
					bool make_target_entry)
{
	List	   *fields = cref->fields;
	int			numnames = list_length(fields);

	if (numnames == 1)
	{
		/*
		 * Target item is a bare '*', expand all tables
		 *
		 * (e.g., SELECT * FROM emp, dept)
		 *
		 * Since the grammar only accepts bare '*' at top level of SELECT, we
		 * need not handle the make_target_entry==false case here.
		 */
		if (!make_target_entry)
			elog(ERROR, "invalid use of *");

		return ExpandAllTables(pstate, cref->location);
	}
	else
	{
		/*
		 * Target item is relation.*, expand that table
		 *
		 * (e.g., SELECT emp.*, dname FROM emp, dept)
		 *
		 * Note: this code is a lot like transformColumnRef; it's tempting to
		 * call that instead and then replace the resulting whole-row Var with
		 * a list of Vars.  However, that would leave us with the relation's
		 * selectedCols bitmap showing the whole row as needing select
		 * permission, as well as the individual columns.  That would be
		 * incorrect (since columns added later shouldn't need select
		 * permissions).  We could try to remove the whole-row permission bit
		 * after the fact, but duplicating code is less messy.
		 */
		char	   *nspname = NULL;
		char	   *relname = NULL;
		ParseNamespaceItem *nsitem = NULL;
		int			levels_up;
		enum
		{
			CRSERR_NO_RTE,
			CRSERR_WRONG_DB,
			CRSERR_TOO_MANY
		}			crserr = CRSERR_NO_RTE;

		/*
		 * Give the PreParseColumnRefHook, if any, first shot.  If it returns
		 * non-null then we should use that expression.
		 */
		if (pstate->p_pre_columnref_hook != NULL)
		{
			Node	   *node;

			node = pstate->p_pre_columnref_hook(pstate, cref);
			if (node != NULL)
				return ExpandRowReference(pstate, node, make_target_entry);
		}

		switch (numnames)
		{
			case 2:
				relname = strVal(linitial(fields));
				nsitem = refnameNamespaceItem(pstate, nspname, relname,
											  cref->location,
											  &levels_up);
				break;
			case 3:
				nspname = strVal(linitial(fields));
				relname = strVal(lsecond(fields));
				nsitem = refnameNamespaceItem(pstate, nspname, relname,
											  cref->location,
											  &levels_up);
				break;
			case 4:
				{
					char	   *catname = strVal(linitial(fields));

					/*
					 * We check the catalog name and then ignore it.
					 */
					if (strcmp(catname, get_database_name(MyDatabaseId)) != 0)
					{
						crserr = CRSERR_WRONG_DB;
						break;
					}
					nspname = strVal(lsecond(fields));
					relname = strVal(lthird(fields));
					nsitem = refnameNamespaceItem(pstate, nspname, relname,
												  cref->location,
												  &levels_up);
					break;
				}
			default:
				crserr = CRSERR_TOO_MANY;
				break;
		}

		/*
		 * Now give the PostParseColumnRefHook, if any, a chance. We cheat a
		 * bit by passing the RangeTblEntry, not a Var, as the planned
		 * translation.  (A single Var wouldn't be strictly correct anyway.
		 * This convention allows hooks that really care to know what is
		 * happening.  It might be better to pass the nsitem, but we'd have to
		 * promote that struct to a full-fledged Node type so that callees
		 * could identify its type.)
		 */
		if (pstate->p_post_columnref_hook != NULL)
		{
			Node	   *node;

			node = pstate->p_post_columnref_hook(pstate, cref,
												 (Node *) (nsitem ? nsitem->p_rte : NULL));
			if (node != NULL)
			{
				if (nsitem != NULL)
					ereport(ERROR,
							(errcode(ERRCODE_AMBIGUOUS_COLUMN),
							 errmsg("column reference \"%s\" is ambiguous",
									NameListToString(cref->fields)),
							 parser_errposition(pstate, cref->location)));
				return ExpandRowReference(pstate, node, make_target_entry);
			}
		}

		/*
		 * Throw error if no translation found.
		 */
		if (nsitem == NULL)
		{
			switch (crserr)
			{
				case CRSERR_NO_RTE:
					errorMissingRTE(pstate, makeRangeVar(nspname, relname,
														 cref->location));
					break;
				case CRSERR_WRONG_DB:
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("cross-database references are not implemented: %s",
									NameListToString(cref->fields)),
							 parser_errposition(pstate, cref->location)));
					break;
				case CRSERR_TOO_MANY:
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("improper qualified name (too many dotted names): %s",
									NameListToString(cref->fields)),
							 parser_errposition(pstate, cref->location)));
					break;
			}
		}

		/*
		 * OK, expand the nsitem into fields.
		 */
		return ExpandSingleTable(pstate, nsitem, levels_up, cref->location,
								 make_target_entry);
	}
}

/*
 * ExpandAllTables()
 *		Transforms '*' (in the target list) into a list of targetlist entries.
 *
 * tlist entries are generated for each relation visible for unqualified
 * column name access.  We do not consider qualified-name-only entries because
 * that would include input tables of aliasless JOINs, NEW/OLD pseudo-entries,
 * etc.
 *
 * The referenced relations/columns are marked as requiring SELECT access.
 */
static List *
ExpandAllTables(ParseState *pstate, int location)
{
	List	   *target = NIL;
	bool		found_table = false;
	ListCell   *l;

	foreach(l, pstate->p_namespace)
	{
		ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l);

		/* Ignore table-only items */
		if (!nsitem->p_cols_visible)
			continue;
		/* Should not have any lateral-only items when parsing targetlist */
		Assert(!nsitem->p_lateral_only);
		/* Remember we found a p_cols_visible item */
		found_table = true;

		target = list_concat(target,
							 expandNSItemAttrs(pstate,
											   nsitem,
											   0,
											   true,
											   location));
	}

	/*
	 * Check for "SELECT *;".  We do it this way, rather than checking for
	 * target == NIL, because we want to allow SELECT * FROM a zero_column
	 * table.
	 */
	if (!found_table)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("SELECT * with no tables specified is not valid"),
				 parser_errposition(pstate, location)));

	return target;
}

/*
 * ExpandIndirectionStar()
 *		Transforms foo.* into a list of expressions or targetlist entries.
 *
 * This handles the case where '*' appears as the last item in A_Indirection.
 * The code is shared between the case of foo.* at the top level in a SELECT
 * target list (where we want TargetEntry nodes in the result) and foo.* in
 * a ROW() or VALUES() construct (where we want just bare expressions).
 * For robustness, we use a separate "make_target_entry" flag to control
 * this rather than relying on exprKind.
 */
static List *
ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
					  bool make_target_entry, ParseExprKind exprKind)
{
	Node	   *expr;

	/* Strip off the '*' to create a reference to the rowtype object */
	ind = copyObject(ind);
	ind->indirection = list_truncate(ind->indirection,
									 list_length(ind->indirection) - 1);

	/* And transform that */
	expr = transformExpr(pstate, (Node *) ind, exprKind);

	/* Expand the rowtype expression into individual fields */
	return ExpandRowReference(pstate, expr, make_target_entry);
}

/*
 * ExpandSingleTable()
 *		Transforms foo.* into a list of expressions or targetlist entries.
 *
 * This handles the case where foo has been determined to be a simple
 * reference to an RTE, so we can just generate Vars for the expressions.
 *
 * The referenced columns are marked as requiring SELECT access.
 */
static List *
ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem,
				  int sublevels_up, int location, bool make_target_entry)
{
	if (make_target_entry)
	{
		/* expandNSItemAttrs handles permissions marking */
		return expandNSItemAttrs(pstate, nsitem, sublevels_up, true, location);
	}
	else
	{
		RangeTblEntry *rte = nsitem->p_rte;
		RTEPermissionInfo *perminfo = nsitem->p_perminfo;
		List	   *vars;
		ListCell   *l;

		vars = expandNSItemVars(pstate, nsitem, sublevels_up, location, NULL);

		/*
		 * Require read access to the table.  This is normally redundant with
		 * the markVarForSelectPriv calls below, but not if the table has zero
		 * columns.  We need not do anything if the nsitem is for a join: its
		 * component tables will have been marked ACL_SELECT when they were
		 * added to the rangetable.  (This step changes things only for the
		 * target relation of UPDATE/DELETE, which cannot be under a join.)
		 */
		if (rte->rtekind == RTE_RELATION)
		{
			Assert(perminfo != NULL);
			perminfo->requiredPerms |= ACL_SELECT;
		}

		/* Require read access to each column */
		foreach(l, vars)
		{
			Var		   *var = (Var *) lfirst(l);

			markVarForSelectPriv(pstate, var);
		}

		return vars;
	}
}

/*
 * ExpandRowReference()
 *		Transforms foo.* into a list of expressions or targetlist entries.
 *
 * This handles the case where foo is an arbitrary expression of composite
 * type.
 */
static List *
ExpandRowReference(ParseState *pstate, Node *expr,
				   bool make_target_entry)
{
	List	   *result = NIL;
	TupleDesc	tupleDesc;
	int			numAttrs;
	int			i;

	/*
	 * If the rowtype expression is a whole-row Var, we can expand the fields
	 * as simple Vars.  Note: if the RTE is a relation, this case leaves us
	 * with its RTEPermissionInfo's selectedCols bitmap showing the whole row
	 * as needing select permission, as well as the individual columns.
	 * However, we can only get here for weird notations like (table.*).*, so
	 * it's not worth trying to clean up --- arguably, the permissions marking
	 * is correct anyway for such cases.
	 */
	if (IsA(expr, Var) &&
		((Var *) expr)->varattno == InvalidAttrNumber)
	{
		Var		   *var = (Var *) expr;
		ParseNamespaceItem *nsitem;

		nsitem = GetNSItemByRangeTablePosn(pstate, var->varno, var->varlevelsup);
		return ExpandSingleTable(pstate, nsitem, var->varlevelsup, var->location, make_target_entry);
	}

	/*
	 * Otherwise we have to do it the hard way.  Our current implementation is
	 * to generate multiple copies of the expression and do FieldSelects.
	 * (This can be pretty inefficient if the expression involves nontrivial
	 * computation :-(.)
	 *
	 * Verify it's a composite type, and get the tupdesc.
	 * get_expr_result_tupdesc() handles this conveniently.
	 *
	 * If it's a Var of type RECORD, we have to work even harder: we have to
	 * find what the Var refers to, and pass that to get_expr_result_tupdesc.
	 * That task is handled by expandRecordVariable().
	 */
	if (IsA(expr, Var) &&
		((Var *) expr)->vartype == RECORDOID)
		tupleDesc = expandRecordVariable(pstate, (Var *) expr, 0);
	else
		tupleDesc = get_expr_result_tupdesc(expr, false);
	Assert(tupleDesc);

	/* Generate a list of references to the individual fields */
	numAttrs = tupleDesc->natts;
	for (i = 0; i < numAttrs; i++)
	{
		Form_pg_attribute att = TupleDescAttr(tupleDesc, i);
		FieldSelect *fselect;

		if (att->attisdropped)
			continue;

		fselect = makeNode(FieldSelect);
		fselect->arg = (Expr *) copyObject(expr);
		fselect->fieldnum = i + 1;
		fselect->resulttype = att->atttypid;
		fselect->resulttypmod = att->atttypmod;
		/* save attribute's collation for parse_collate.c */
		fselect->resultcollid = att->attcollation;

		if (make_target_entry)
		{
			/* add TargetEntry decoration */
			TargetEntry *te;

			te = makeTargetEntry((Expr *) fselect,
								 (AttrNumber) pstate->p_next_resno++,
								 pstrdup(NameStr(att->attname)),
								 false);
			result = lappend(result, te);
		}
		else
			result = lappend(result, fselect);
	}

	return result;
}

/*
 * expandRecordVariable
 *		Get the tuple descriptor for a Var of type RECORD, if possible.
 *
 * Since no actual table or view column is allowed to have type RECORD, such
 * a Var must refer to a JOIN or FUNCTION RTE or to a subquery output.  We
 * drill down to find the ultimate defining expression and attempt to infer
 * the tupdesc from it.  We ereport if we can't determine the tupdesc.
 *
 * levelsup is an extra offset to interpret the Var's varlevelsup correctly
 * when recursing.  Outside callers should pass zero.
 */
TupleDesc
expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
{
	TupleDesc	tupleDesc;
	int			netlevelsup;
	RangeTblEntry *rte;
	AttrNumber	attnum;
	Node	   *expr;

	/* Check my caller didn't mess up */
	Assert(IsA(var, Var));
	Assert(var->vartype == RECORDOID);

	/*
	 * Note: it's tempting to use GetNSItemByRangeTablePosn here so that we
	 * can use expandNSItemVars instead of expandRTE; but that does not work
	 * for some of the recursion cases below, where we have consed up a
	 * ParseState that lacks p_namespace data.
	 */
	netlevelsup = var->varlevelsup + levelsup;
	rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
	attnum = var->varattno;

	if (attnum == InvalidAttrNumber)
	{
		/* Whole-row reference to an RTE, so expand the known fields */
		List	   *names,
				   *vars;
		ListCell   *lname,
				   *lvar;
		int			i;

		expandRTE(rte, var->varno, 0, var->location, false,
				  &names, &vars);

		tupleDesc = CreateTemplateTupleDesc(list_length(vars));
		i = 1;
		forboth(lname, names, lvar, vars)
		{
			char	   *label = strVal(lfirst(lname));
			Node	   *varnode = (Node *) lfirst(lvar);

			TupleDescInitEntry(tupleDesc, i,
							   label,
							   exprType(varnode),
							   exprTypmod(varnode),
							   0);
			TupleDescInitEntryCollation(tupleDesc, i,
										exprCollation(varnode));
			i++;
		}
		Assert(lname == NULL && lvar == NULL);	/* lists same length? */

		return tupleDesc;
	}

	expr = (Node *) var;		/* default if we can't drill down */

	switch (rte->rtekind)
	{
		case RTE_RELATION:
		case RTE_VALUES:
		case RTE_NAMEDTUPLESTORE:
		case RTE_RESULT:

			/*
			 * This case should not occur: a column of a table, values list,
			 * or ENR shouldn't have type RECORD.  Fall through and fail (most
			 * likely) at the bottom.
			 */
			break;
		case RTE_SUBQUERY:
			{
				/* Subselect-in-FROM: examine sub-select's output expr */
				TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
													attnum);

				if (ste == NULL || ste->resjunk)
					elog(ERROR, "subquery %s does not have attribute %d",
						 rte->eref->aliasname, attnum);
				expr = (Node *) ste->expr;
				if (IsA(expr, Var))
				{
					/*
					 * Recurse into the sub-select to see what its Var refers
					 * to.  We have to build an additional level of ParseState
					 * to keep in step with varlevelsup in the subselect;
					 * furthermore, the subquery RTE might be from an outer
					 * query level, in which case the ParseState for the
					 * subselect must have that outer level as parent.
					 */
					ParseState	mypstate = {0};
					Index		levelsup;

					/* this loop must work, since GetRTEByRangeTablePosn did */
					for (levelsup = 0; levelsup < netlevelsup; levelsup++)
						pstate = pstate->parentParseState;
					mypstate.parentParseState = pstate;
					mypstate.p_rtable = rte->subquery->rtable;
					/* don't bother filling the rest of the fake pstate */

					return expandRecordVariable(&mypstate, (Var *) expr, 0);
				}
				/* else fall through to inspect the expression */
			}
			break;
		case RTE_JOIN:
			/* Join RTE --- recursively inspect the alias variable */
			Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
			expr = (Node *) list_nth(rte->joinaliasvars, attnum - 1);
			Assert(expr != NULL);
			/* We intentionally don't strip implicit coercions here */
			if (IsA(expr, Var))
				return expandRecordVariable(pstate, (Var *) expr, netlevelsup);
			/* else fall through to inspect the expression */
			break;
		case RTE_TABLEFUNCTION:
		case RTE_FUNCTION:

			/*
			 * We couldn't get here unless a function is declared with one of
			 * its result columns as RECORD, which is not allowed.
			 */
			break;
		case RTE_TABLEFUNC:

			/*
			 * Table function cannot have columns with RECORD type.
			 */
			break;
		case RTE_CTE:
			/* CTE reference: examine subquery's output expr */
			if (!rte->self_reference)
			{
				CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup);
				TargetEntry *ste;

				ste = get_tle_by_resno(GetCTETargetList(cte), attnum);
				if (ste == NULL || ste->resjunk)
					elog(ERROR, "CTE %s does not have attribute %d",
						 rte->eref->aliasname, attnum);
				expr = (Node *) ste->expr;
				if (IsA(expr, Var))
				{
					/*
					 * Recurse into the CTE to see what its Var refers to. We
					 * have to build an additional level of ParseState to keep
					 * in step with varlevelsup in the CTE; furthermore it
					 * could be an outer CTE (compare SUBQUERY case above).
					 */
					ParseState	mypstate = {0};
					Index		levelsup;

					/* this loop must work, since GetCTEForRTE did */
					for (levelsup = 0;
						 levelsup < rte->ctelevelsup + netlevelsup;
						 levelsup++)
						pstate = pstate->parentParseState;
					mypstate.parentParseState = pstate;
					mypstate.p_rtable = ((Query *) cte->ctequery)->rtable;
					/* don't bother filling the rest of the fake pstate */

					return expandRecordVariable(&mypstate, (Var *) expr, 0);
				}
				/* else fall through to inspect the expression */
			}
			break;
		case RTE_VOID:
			elog(ERROR, "unexpected RTE type RTE_VOID");
			break;
	}

	/*
	 * We now have an expression we can't expand any more, so see if
	 * get_expr_result_tupdesc() can do anything with it.
	 */
	return get_expr_result_tupdesc(expr, false);
}


/*
 * FigureColname -
 *	  if the name of the resulting column is not specified in the target
 *	  list, we have to guess a suitable name.  The SQL spec provides some
 *	  guidance, but not much...
 *
 * Note that the argument is the *untransformed* parse tree for the target
 * item.  This is a shade easier to work with than the transformed tree.
 */
char *
FigureColname(Node *node)
{
	char	   *name = NULL;

	(void) FigureColnameInternal(node, &name);
	if (name != NULL)
		return name;
	/* default result if we can't guess anything */
	return "?column?";
}

/*
 * FigureIndexColname -
 *	  choose the name for an expression column in an index
 *
 * This is actually just like FigureColname, except we return NULL if
 * we can't pick a good name.
 */
char *
FigureIndexColname(Node *node)
{
	char	   *name = NULL;

	(void) FigureColnameInternal(node, &name);
	return name;
}

/*
 * FigureColnameInternal -
 *	  internal workhorse for FigureColname
 *
 * Return value indicates strength of confidence in result:
 *		0 - no information
 *		1 - second-best name choice
 *		2 - good name choice
 * The return value is actually only used internally.
 * If the result isn't zero, *name is set to the chosen name.
 */
static int
FigureColnameInternal(Node *node, char **name)
{
	int			strength = 0;

	if (node == NULL)
		return strength;

	switch (nodeTag(node))
	{
		case T_ColumnRef:
			{
				char	   *fname = NULL;
				ListCell   *l;

				/* find last field name, if any, ignoring "*" */
				foreach(l, ((ColumnRef *) node)->fields)
				{
					Node	   *i = lfirst(l);

					if (IsA(i, String))
						fname = strVal(i);
				}
				if (fname)
				{
					*name = fname;
					return 2;
				}
			}
			break;
		case T_A_Indirection:
			{
				A_Indirection *ind = (A_Indirection *) node;
				char	   *fname = NULL;
				ListCell   *l;

				/* find last field name, if any, ignoring "*" and subscripts */
				foreach(l, ind->indirection)
				{
					Node	   *i = lfirst(l);

					if (IsA(i, String))
						fname = strVal(i);
				}
				if (fname)
				{
					*name = fname;
					return 2;
				}
				return FigureColnameInternal(ind->arg, name);
			}
			break;
		case T_FuncCall:
			*name = strVal(llast(((FuncCall *) node)->funcname));
			return 2;
		case T_A_Expr:
			if (((A_Expr *) node)->kind == AEXPR_NULLIF)
			{
				/* make nullif() act like a regular function */
				*name = "nullif";
				return 2;
			}
			break;
		case T_TypeCast:
			strength = FigureColnameInternal(((TypeCast *) node)->arg,
											 name);
			if (strength <= 1)
			{
				if (((TypeCast *) node)->typeName != NULL)
				{
					*name = strVal(llast(((TypeCast *) node)->typeName->names));
					return 1;
				}
			}
			break;
		case T_CollateClause:
			return FigureColnameInternal(((CollateClause *) node)->arg, name);
		case T_GroupingFunc:
			/* make GROUPING() act like a regular function */
			*name = "grouping";
			return 2;
		case T_GroupId:
			/* make GROUP_ID() act like a regular function */
			*name = "group_id";
			return 2;
		case T_SubLink:
			switch (((SubLink *) node)->subLinkType)
			{
				case EXISTS_SUBLINK:
					*name = "exists";
					return 2;
				case ARRAY_SUBLINK:
					*name = "array";
					return 2;
				case EXPR_SUBLINK:
					{
						/* Get column name of the subquery's single target */
						SubLink    *sublink = (SubLink *) node;
						Query	   *query = (Query *) sublink->subselect;

						/*
						 * The subquery has probably already been transformed,
						 * but let's be careful and check that.  (The reason
						 * we can see a transformed subquery here is that
						 * transformSubLink is lazy and modifies the SubLink
						 * node in-place.)
						 */
						if (IsA(query, Query))
						{
							TargetEntry *te = (TargetEntry *) linitial(query->targetList);

							if (te->resname)
							{
								*name = te->resname;
								return 2;
							}
						}
					}
					break;

					/* As with other operator-like nodes, these have no names */
				case MULTIEXPR_SUBLINK:
				case ALL_SUBLINK:
				case ANY_SUBLINK:
				case ROWCOMPARE_SUBLINK:
				case CTE_SUBLINK:
				case INITPLAN_FUNC_SUBLINK:
				case NOT_EXISTS_SUBLINK:
					break;
			}
			break;
		case T_CaseExpr:
			strength = FigureColnameInternal((Node *) ((CaseExpr *) node)->defresult,
											 name);
			if (strength <= 1)
			{
				*name = "case";
				return 1;
			}
			break;
		case T_A_ArrayExpr:
			/* make ARRAY[] act like a function */
			*name = "array";
			return 2;
		case T_RowExpr:
			/* make ROW() act like a function */
			*name = "row";
			return 2;
		case T_CoalesceExpr:
			/* make coalesce() act like a regular function */
			*name = "coalesce";
			return 2;
		case T_MinMaxExpr:
			/* make greatest/least act like a regular function */
			switch (((MinMaxExpr *) node)->op)
			{
				case IS_GREATEST:
					*name = "greatest";
					return 2;
				case IS_LEAST:
					*name = "least";
					return 2;
			}
			break;
		case T_SQLValueFunction:
			/* make these act like a function or variable */
			switch (((SQLValueFunction *) node)->op)
			{
				case SVFOP_CURRENT_DATE:
					*name = "current_date";
					return 2;
				case SVFOP_CURRENT_TIME:
				case SVFOP_CURRENT_TIME_N:
					*name = "current_time";
					return 2;
				case SVFOP_CURRENT_TIMESTAMP:
				case SVFOP_CURRENT_TIMESTAMP_N:
					*name = "current_timestamp";
					return 2;
				case SVFOP_LOCALTIME:
				case SVFOP_LOCALTIME_N:
					*name = "localtime";
					return 2;
				case SVFOP_LOCALTIMESTAMP:
				case SVFOP_LOCALTIMESTAMP_N:
					*name = "localtimestamp";
					return 2;
				case SVFOP_CURRENT_ROLE:
					*name = "current_role";
					return 2;
				case SVFOP_CURRENT_USER:
					*name = "current_user";
					return 2;
				case SVFOP_USER:
					*name = "user";
					return 2;
				case SVFOP_SESSION_USER:
					*name = "session_user";
					return 2;
				case SVFOP_CURRENT_CATALOG:
					*name = "current_catalog";
					return 2;
				case SVFOP_CURRENT_SCHEMA:
					*name = "current_schema";
					return 2;
			}
			break;
		case T_XmlExpr:
			/* make SQL/XML functions act like a regular function */
			switch (((XmlExpr *) node)->op)
			{
				case IS_XMLCONCAT:
					*name = "xmlconcat";
					return 2;
				case IS_XMLELEMENT:
					*name = "xmlelement";
					return 2;
				case IS_XMLFOREST:
					*name = "xmlforest";
					return 2;
				case IS_XMLPARSE:
					*name = "xmlparse";
					return 2;
				case IS_XMLPI:
					*name = "xmlpi";
					return 2;
				case IS_XMLROOT:
					*name = "xmlroot";
					return 2;
				case IS_XMLSERIALIZE:
					*name = "xmlserialize";
					return 2;
				case IS_DOCUMENT:
					/* nothing */
					break;
			}
			break;
		case T_XmlSerialize:
			/* make XMLSERIALIZE act like a regular function */
			*name = "xmlserialize";
			return 2;
		case T_JsonObjectConstructor:
			/* make JSON_OBJECT act like a regular function */
			*name = "json_object";
			return 2;
		case T_JsonArrayConstructor:
		case T_JsonArrayQueryConstructor:
			/* make JSON_ARRAY act like a regular function */
			*name = "json_array";
			return 2;
		case T_JsonObjectAgg:
			/* make JSON_OBJECTAGG act like a regular function */
			*name = "json_objectagg";
			return 2;
		case T_JsonArrayAgg:
			/* make JSON_ARRAYAGG act like a regular function */
			*name = "json_arrayagg";
			return 2;
		default:
			break;
	}

	return strength;
}
