/*-------------------------------------------------------------------------
 *
 * parse_clause.c
 *	  handle clauses in parser
 *
 * Portions Copyright (c) 2006-2008, Greenplum inc
 * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates.
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/parser/parse_clause.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/htup_details.h"
#include "access/nbtree.h"
#include "access/table.h"
#include "access/tsmapi.h"
#include "catalog/catalog.h"
#include "catalog/heap.h"
#include "catalog/pg_am.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "parser/analyze.h"
#include "parser/parse_clause.h"
#include "parser/parse_coerce.h"
#include "parser/parse_collate.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parse_relation.h"
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "parser/parser.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteManip.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"

#include "catalog/pg_operator.h"
#include "cdb/cdbvars.h"
#include "utils/builtins.h"
#include "utils/regproc.h"
#include "utils/syscache.h"

static int	extractRemainingColumns(ParseState *pstate,
									ParseNamespaceColumn *src_nscolumns,
									List *src_colnames,
									List **src_colnos,
									List **res_colnames, List **res_colvars,
									ParseNamespaceColumn *res_nscolumns);
static Node *transformJoinUsingClause(ParseState *pstate,
									  List *leftVars, List *rightVars);
static Node *transformJoinOnClause(ParseState *pstate, JoinExpr *j,
								   List *namespace);
static ParseNamespaceItem *transformTableEntry(ParseState *pstate, RangeVar *r);
static ParseNamespaceItem *transformRangeSubselect(ParseState *pstate,
												   RangeSubselect *r);
static ParseNamespaceItem *transformRangeFunction(ParseState *pstate,
												  RangeFunction *r);
static ParseNamespaceItem *transformRangeTableFunc(ParseState *pstate,
												   RangeTableFunc *rtf);
static TableSampleClause *transformRangeTableSample(ParseState *pstate,
													RangeTableSample *rts);
static ParseNamespaceItem *getNSItemForSpecialRelationTypes(ParseState *pstate,
															RangeVar *rv);
static Node *transformFromClauseItem(ParseState *pstate, Node *n,
									 ParseNamespaceItem **top_nsitem,
									 List **namespace);
static Var *buildVarFromNSColumn(ParseState *pstate,
								 ParseNamespaceColumn *nscol);
static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype,
								Var *l_colvar, Var *r_colvar);
static void markRelsAsNulledBy(ParseState *pstate, Node *n, int jindex);
static void setNamespaceColumnVisibility(List *namespace, bool cols_visible);
static void setNamespaceLateralState(List *namespace,
									 bool lateral_only, bool lateral_ok);
static void checkExprIsVarFree(ParseState *pstate, Node *n,
							   const char *constructName);
static TargetEntry *findTargetlistEntrySQL92(ParseState *pstate, Node *node,
											 List **tlist, ParseExprKind exprKind);
static TargetEntry *findTargetlistEntrySQL99(ParseState *pstate, Node *node,
											 List **tlist, ParseExprKind exprKind);
static int	get_matching_location(int sortgroupref,
								  List *sortgrouprefs, List *exprs);
static List *resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
									   Relation heapRel);
static List *addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
								  List *grouplist, List *targetlist, int location);
static WindowClause *findWindowClause(List *wclist, const char *name);
static Node *transformFrameOffset(ParseState *pstate, int frameOptions,
								  Oid rangeopfamily, Oid rangeopcintype, Oid *inRangeFunc,
								  Node *clause);

typedef struct grouping_rewrite_ctx
{
	List *grp_tles;
	ParseState *pstate;
} grouping_rewrite_ctx;

typedef struct winref_check_ctx
{
	ParseState *pstate;
	Index winref;
	bool has_order;
	bool has_frame;
} winref_check_ctx;

/*
 * transformFromClause -
 *	  Process the FROM clause and add items to the query's range table,
 *	  joinlist, and namespace.
 *
 * Note: we assume that the pstate's p_rtable, p_joinlist, and p_namespace
 * lists were initialized to NIL when the pstate was created.
 * We will add onto any entries already present --- this is needed for rule
 * processing, as well as for UPDATE and DELETE.
 */
void
transformFromClause(ParseState *pstate, List *frmList)
{
	ListCell   *fl;

	/*
	 * The grammar will have produced a list of RangeVars, RangeSubselects,
	 * RangeFunctions, and/or JoinExprs. Transform each one (possibly adding
	 * entries to the rtable), check for duplicate refnames, and then add it
	 * to the joinlist and namespace.
	 *
	 * Note we must process the items left-to-right for proper handling of
	 * LATERAL references.
	 */
	foreach(fl, frmList)
	{
		Node	   *n = lfirst(fl);
		ParseNamespaceItem *nsitem;
		List	   *namespace;

		n = transformFromClauseItem(pstate, n,
									&nsitem,
									&namespace);

		checkNameSpaceConflicts(pstate, pstate->p_namespace, namespace);

		/* Mark the new namespace items as visible only to LATERAL */
		setNamespaceLateralState(namespace, true, true);

		pstate->p_joinlist = lappend(pstate->p_joinlist, n);
		pstate->p_namespace = list_concat(pstate->p_namespace, namespace);
	}

	/*
	 * We're done parsing the FROM list, so make all namespace items
	 * unconditionally visible.  Note that this will also reset lateral_only
	 * for any namespace items that were already present when we were called;
	 * but those should have been that way already.
	 */
	setNamespaceLateralState(pstate->p_namespace, false, true);
}

/*
 * winref_checkspec_walker
 */
static bool
winref_checkspec_walker(Node *node, void *ctx)
{
	winref_check_ctx *ref = (winref_check_ctx *)ctx;

	if (!node)
		return false;
	else if (IsA(node, WindowFunc))
	{
		WindowFunc *winref = (WindowFunc *) node;

		/*
		 * Look at functions pointing to the interesting spec only.
		 */
		if (winref->winref != ref->winref)
			return false;

		if (winref->windistinct)
		{
			if (ref->has_order)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("DISTINCT cannot be used with window specification containing an ORDER BY clause"),
						 parser_errposition(ref->pstate, winref->location)));

			if (ref->has_frame)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("DISTINCT cannot be used with window specification containing a framing clause"),
						 parser_errposition(ref->pstate, winref->location)));
		}
	}

	return expression_tree_walker(node, winref_checkspec_walker, ctx);
}

/*
 * winref_checkspec
 *
 * See if any WindowFuncss using this spec are DISTINCT qualified.
 *
 * In addition, we're going to check winrequireorder / winallowframe.
 * You might want to do it in ParseFuncOrColumn,
 * but we need to do this here after all the transformations
 * (especially parent inheritance) was done.
 */
static bool
winref_checkspec(ParseState *pstate, List *targetlist, Index winref,
				 bool has_order, bool has_frame)
{
	winref_check_ctx ctx;

	ctx.pstate = pstate;
	ctx.winref = winref;
	ctx.has_order = has_order;
	ctx.has_frame = has_frame;

	return expression_tree_walker((Node *) targetlist,
								  winref_checkspec_walker, (void *) &ctx);
}

/*
 * setTargetTable
 *	  Add the target relation of INSERT/UPDATE/DELETE/MERGE to the range table,
 *	  and make the special links to it in the ParseState.
 *
 *	  We also open the target relation and acquire a write lock on it.
 *	  This must be done before processing the FROM list, in case the target
 *	  is also mentioned as a source relation --- we want to be sure to grab
 *	  the write lock before any read lock.
 *
 *	  If alsoSource is true, add the target to the query's joinlist and
 *	  namespace.  For INSERT, we don't want the target to be joined to;
 *	  it's a destination of tuples, not a source.  MERGE is actually
 *	  both, but we'll add it separately to joinlist and namespace, so
 *	  doing nothing (like INSERT) is correct here.  For UPDATE/DELETE,
 *	  we do need to scan or join the target.  (NOTE: we do not bother
 *	  to check for namespace conflict; we assume that the namespace was
 *	  initially empty in these cases.)
 *
 *	  Finally, we mark the relation as requiring the permissions specified
 *	  by requiredPerms.
 *
 *	  Returns the rangetable index of the target relation.
 */
int
setTargetTable(ParseState *pstate, RangeVar *relation,
			   bool inh, bool alsoSource, AclMode requiredPerms)
{
	ParseCallbackState pcbstate;
	ParseNamespaceItem *nsitem;
	bool lockUpgraded = false;
	LOCKMODE    lockmode;

	/*
	 * ENRs hide tables of the same name, so we need to check for them first.
	 * In contrast, CTEs don't hide tables (for this purpose).
	 */
	if (relation->schemaname == NULL &&
		scanNameSpaceForENR(pstate, relation->relname))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("relation \"%s\" cannot be the target of a modifying statement",
						relation->relname)));

	/* Close old target; this could only happen for multi-action rules */
	if (pstate->p_target_relation != NULL)
		table_close(pstate->p_target_relation, NoLock);

	/*
	 * Open target rel and grab suitable lock (which we will hold till end of
	 * transaction).
	 *
	 * free_parsestate() will eventually do the corresponding table_close(),
	 * but *not* release the lock.
     *
	 * CDB: Acquire ExclusiveLock if it is a distributed relation and we are
	 * doing UPDATE or DELETE activity or `insert on conflict do update`.
	 *
	 * We should use heap_openrv instead of parserOpenTable for inserts because
	 * parserOpenTable upgrades the lock to Exclusive mode for distributed
	 * tables.
	 *
	 * Cloudberry specific behavior:
	 * Statement `insert on conflict do update` should be considered
	 * like update when deducting lockmode. See github issue:
	 * https://github.com/greenplum-db/gpdb/issues/9449
	 */
	if (pstate->p_is_insert && !pstate->p_is_on_conflict_update)
	{
		setup_parser_errposition_callback(&pcbstate, pstate, relation->location);
		pstate->p_target_relation = heap_openrv(relation, RowExclusiveLock);
		cancel_parser_errposition_callback(&pcbstate);
	}
	else
	{
		pstate->p_target_relation = parserOpenTable(pstate, relation, RowExclusiveLock, &lockUpgraded);
	}

	lockmode = lockUpgraded ? ExclusiveLock : RowExclusiveLock;

	if (Gp_role == GP_ROLE_DISPATCH &&
		pstate->p_is_insert &&
		!gp_enable_global_deadlock_detector &&
		pstate->p_target_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
	{
		/*
		 * Greenplum specific code:
		 * When GDD is disabled, and we are inserting into a partition table,
		 * then we need to lock all leaf partitions. The reason is:
		 *    1. we cannot predict which leaf partitions will be inserted
		 *    2. if we do not hold lock on leaf partitions on QD, then this
		 *       insert statement will be dispatched to QEs, and not dispatch
		 *       is async, so on some segments, this session's insert will
		 *       first hold locks on leaf partition and block others; however,
		 *       on some segments, this session's insert will be blocked by
		 *       others. Thus we have risk to have global deadlock.
		 * See issue https://github.com/greenplum-db/gpdb/issues/13652 for details.
		 */
		(void) find_all_inheritors(RelationGetRelid(pstate->p_target_relation),
								   lockmode, NULL);
	}

	/*
	 * Now build an RTE and a ParseNamespaceItem.
	 */
	nsitem = addRangeTableEntryForRelation(pstate, pstate->p_target_relation,
											lockmode, /* CDB */
										   relation->alias, inh, false);

	/* remember the RTE/nsitem as being the query target */
	pstate->p_target_nsitem = nsitem;

	/*
	 * Special check for DML on system relations,
	 * allow DML when:
	 * 	- in single user mode: initdb insert PIN entries to pg_depend,...
	 * 	- in maintenance mode, upgrade mode or
	 *  - allow_system_table_mods = true
	 */
	if (IsUnderPostmaster && !allowSystemTableMods
		&& IsSystemRelation(pstate->p_target_relation))
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("permission denied: \"%s\" is a system catalog",
						 RelationGetRelationName(pstate->p_target_relation))));

	/*
	 * Override addRangeTableEntry's default ACL_SELECT permissions check, and
	 * instead mark target table as requiring exactly the specified
	 * permissions.
	 *
	 * If we find an explicit reference to the rel later during parse
	 * analysis, we will add the ACL_SELECT bit back again; see
	 * markVarForSelectPriv and its callers.
	 */
	nsitem->p_perminfo->requiredPerms = requiredPerms;

	/*
	 * If UPDATE/DELETE, add table to joinlist and namespace.
	 */
	if (alsoSource)
		addNSItemToQuery(pstate, nsitem, true, true, true);

	return nsitem->p_rtindex;
}

/*
 * Extract all not-in-common columns from column lists of a source table
 *
 * src_nscolumns and src_colnames describe the source table.
 *
 * *src_colnos initially contains the column numbers of the already-merged
 * columns.  We add to it the column number of each additional column.
 * Also append to *res_colnames the name of each additional column,
 * append to *res_colvars a Var for each additional column, and copy the
 * columns' nscolumns data into res_nscolumns[] (which is caller-allocated
 * space that had better be big enough).
 *
 * Returns the number of columns added.
 */
static int
extractRemainingColumns(ParseState *pstate,
						ParseNamespaceColumn *src_nscolumns,
						List *src_colnames,
						List **src_colnos,
						List **res_colnames, List **res_colvars,
						ParseNamespaceColumn *res_nscolumns)
{
	int			colcount = 0;
	Bitmapset  *prevcols;
	int			attnum;
	ListCell   *lc;

	/*
	 * While we could just test "list_member_int(*src_colnos, attnum)" to
	 * detect already-merged columns in the loop below, that would be O(N^2)
	 * for a wide input table.  Instead build a bitmapset of just the merged
	 * USING columns, which we won't add to within the main loop.
	 */
	prevcols = NULL;
	foreach(lc, *src_colnos)
	{
		prevcols = bms_add_member(prevcols, lfirst_int(lc));
	}

	attnum = 0;
	foreach(lc, src_colnames)
	{
		char	   *colname = strVal(lfirst(lc));

		attnum++;
		/* Non-dropped and not already merged? */
		if (colname[0] != '\0' && !bms_is_member(attnum, prevcols))
		{
			/* Yes, so emit it as next output column */
			*src_colnos = lappend_int(*src_colnos, attnum);
			*res_colnames = lappend(*res_colnames, lfirst(lc));
			*res_colvars = lappend(*res_colvars,
								   buildVarFromNSColumn(pstate,
														src_nscolumns + attnum - 1));
			/* Copy the input relation's nscolumn data for this column */
			res_nscolumns[colcount] = src_nscolumns[attnum - 1];
			colcount++;
		}
	}
	return colcount;
}

/* transformJoinUsingClause()
 *	  Build a complete ON clause from a partially-transformed USING list.
 *	  We are given lists of nodes representing left and right match columns.
 *	  Result is a transformed qualification expression.
 */
static Node *
transformJoinUsingClause(ParseState *pstate,
						 List *leftVars, List *rightVars)
{
	Node	   *result;
	List	   *andargs = NIL;
	ListCell   *lvars,
			   *rvars;

	/*
	 * We cheat a little bit here by building an untransformed operator tree
	 * whose leaves are the already-transformed Vars.  This requires collusion
	 * from transformExpr(), which normally could be expected to complain
	 * about already-transformed subnodes.  However, this does mean that we
	 * have to mark the columns as requiring SELECT privilege for ourselves;
	 * transformExpr() won't do it.
	 */
	forboth(lvars, leftVars, rvars, rightVars)
	{
		Var		   *lvar = (Var *) lfirst(lvars);
		Var		   *rvar = (Var *) lfirst(rvars);
		A_Expr	   *e;

		/* Require read access to the join variables */
		markVarForSelectPriv(pstate, lvar);
		markVarForSelectPriv(pstate, rvar);

		/* Now create the lvar = rvar join condition */
		e = makeSimpleA_Expr(AEXPR_OP, "=",
							 (Node *) copyObject(lvar), (Node *) copyObject(rvar),
							 -1);

		/* Prepare to combine into an AND clause, if multiple join columns */
		andargs = lappend(andargs, e);
	}

	/* Only need an AND if there's more than one join column */
	if (list_length(andargs) == 1)
		result = (Node *) linitial(andargs);
	else
		result = (Node *) makeBoolExpr(AND_EXPR, andargs, -1);

	/*
	 * Since the references are already Vars, and are certainly from the input
	 * relations, we don't have to go through the same pushups that
	 * transformJoinOnClause() does.  Just invoke transformExpr() to fix up
	 * the operators, and we're done.
	 */
	result = transformExpr(pstate, result, EXPR_KIND_JOIN_USING);

	result = coerce_to_boolean(pstate, result, "JOIN/USING");

	return result;
}

/* transformJoinOnClause()
 *	  Transform the qual conditions for JOIN/ON.
 *	  Result is a transformed qualification expression.
 */
static Node *
transformJoinOnClause(ParseState *pstate, JoinExpr *j, List *namespace)
{
	Node	   *result;
	List	   *save_namespace;

	/*
	 * The namespace that the join expression should see is just the two
	 * subtrees of the JOIN plus any outer references from upper pstate
	 * levels.  Temporarily set this pstate's namespace accordingly.  (We need
	 * not check for refname conflicts, because transformFromClauseItem()
	 * already did.)  All namespace items are marked visible regardless of
	 * LATERAL state.
	 */
	setNamespaceLateralState(namespace, false, true);

	save_namespace = pstate->p_namespace;
	pstate->p_namespace = namespace;

	result = transformWhereClause(pstate, j->quals,
								  EXPR_KIND_JOIN_ON, "JOIN/ON");

	pstate->p_namespace = save_namespace;

	return result;
}

/*
 * transformTableEntry --- transform a RangeVar (simple relation reference)
 */
static ParseNamespaceItem *
transformTableEntry(ParseState *pstate, RangeVar *r)
{
	/* addRangeTableEntry does all the work */
	return addRangeTableEntry(pstate, r, r->alias, r->inh, true);
}

/*
 * transformRangeSubselect --- transform a sub-SELECT appearing in FROM
 */
static ParseNamespaceItem *
transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
{
	Query	   *query;

	/*
	 * Set p_expr_kind to show this parse level is recursing to a subselect.
	 * We can't be nested within any expression, so don't need save-restore
	 * logic here.
	 */
	Assert(pstate->p_expr_kind == EXPR_KIND_NONE);
	pstate->p_expr_kind = EXPR_KIND_FROM_SUBSELECT;

	/*
	 * If the subselect is LATERAL, make lateral_only names of this level
	 * visible to it.  (LATERAL can't nest within a single pstate level, so we
	 * don't need save/restore logic here.)
	 */
	Assert(!pstate->p_lateral_active);
	pstate->p_lateral_active = r->lateral;

	/*
	 * Analyze and transform the subquery.  Note that if the subquery doesn't
	 * have an alias, it can't be explicitly selected for locking, but locking
	 * might still be required (if there is an all-tables locking clause).
	 */
	query = parse_sub_analyze(r->subquery, pstate, NULL,
							  getLockedRefname(pstate,
											   r->alias == NULL ? NULL :
											   r->alias->aliasname),
							  true);

	/* Restore state */
	pstate->p_lateral_active = false;
	pstate->p_expr_kind = EXPR_KIND_NONE;

	/*
	 * Check that we got a SELECT.  Anything else should be impossible given
	 * restrictions of the grammar, but check anyway.
	 */
	if (!IsA(query, Query) ||
		query->commandType != CMD_SELECT)
		elog(ERROR, "unexpected non-SELECT command in subquery in FROM");

	/*
	 * OK, build an RTE and nsitem for the subquery.
	 */
	return addRangeTableEntryForSubquery(pstate,
										 query,
										 r->alias,
										 r->lateral,
										 true);
}


/*
 * transformRangeFunction --- transform a function call appearing in FROM
 */
static ParseNamespaceItem *
transformRangeFunction(ParseState *pstate, RangeFunction *r)
{
	List	   *funcexprs = NIL;
	List	   *funcnames = NIL;
	List	   *coldeflists = NIL;
	bool		is_lateral;
	ListCell   *lc;

	if (!r->is_rowsfrom && list_length(r->functions) == 1)
	{
		List	   *pair = (List *) linitial(r->functions);
		Node	   *fexpr;
		List	   *coldeflist;
		
		/* Disassemble the function-call/column-def-list pairs */
		Assert(list_length(pair) == 2);
		fexpr = (Node *) linitial(pair);
		coldeflist = (List *) lsecond(pair);

		/* If we see a gp_dist_random('name') call with no special decoration, it actually
		 * refers to a table.
		 */
		if (IsA(fexpr, FuncCall))
		{
			FuncCall   *fc = (FuncCall *) fexpr;

			if (list_length(fc->funcname) == 1 &&
				pg_strcasecmp(strVal(linitial(fc->funcname)), GP_DIST_RANDOM_NAME) == 0 &&
				fc->agg_order == NIL &&
				fc->agg_filter == NULL &&
				!fc->agg_star &&
				!fc->agg_distinct &&
				!fc->func_variadic &&
				fc->over == NULL &&
				coldeflist == NIL)
			{
				/* OK, now we need to check the arguments and generate a RTE */

				if (list_length(fc->args) != 1)
					elog(ERROR, "Invalid %s syntax.", GP_DIST_RANDOM_NAME);

				if (IsA(linitial(fc->args), A_Const))
				{
					A_Const *arg_val;
					List *qualified_name_list;
					RangeVar *rel;
					ParseNamespaceItem *rte;

					arg_val = linitial(fc->args);
					if (!IsA(&arg_val->val, String))
					{
						elog(ERROR, "%s: invalid argument type, non-string in value", GP_DIST_RANDOM_NAME);
					}

					/* Build the RTE for the table. */
					qualified_name_list = stringToQualifiedNameList(strVal(&arg_val->val), NULL);
					rel = makeRangeVarFromNameList(qualified_name_list);
					rel->location = arg_val->location;

					rte = addRangeTableEntry(pstate, rel, r->alias, false, true);

					/* Now we set our special attribute in the rte. */
					/*
					 * However, in singlenode mode distribution is meaningless and might introduce unexpected
					 * motions in the plan, which will lead to some assert failures.
					 */
					rte->p_rte->forceDistRandom = !IS_SINGLENODE();

					return rte;
				}
				else
				{
					elog(ERROR, "%s: invalid argument type", GP_DIST_RANDOM_NAME);
				}
			}
		}
	}

	/*
	 * We make lateral_only names of this level visible, whether or not the
	 * RangeFunction is explicitly marked LATERAL.  This is needed for SQL
	 * spec compliance in the case of UNNEST(), and seems useful on
	 * convenience grounds for all functions in FROM.
	 *
	 * (LATERAL can't nest within a single pstate level, so we don't need
	 * save/restore logic here.)
	 */
	Assert(!pstate->p_lateral_active);
	pstate->p_lateral_active = true;

	/*
	 * Transform the raw expressions.
	 *
	 * While transforming, also save function names for possible use as alias
	 * and column names.  We use the same transformation rules as for a SELECT
	 * output expression.  For a FuncCall node, the result will be the
	 * function name, but it is possible for the grammar to hand back other
	 * node types.
	 *
	 * We have to get this info now, because FigureColname only works on raw
	 * parsetrees.  Actually deciding what to do with the names is left up to
	 * addRangeTableEntryForFunction.
	 *
	 * Likewise, collect column definition lists if there were any.  But
	 * complain if we find one here and the RangeFunction has one too.
	 */
	foreach(lc, r->functions)
	{
		List	   *pair = (List *) lfirst(lc);
		Node	   *fexpr;
		List	   *coldeflist;
		Node	   *newfexpr;
		Node	   *last_srf;

		/* Disassemble the function-call/column-def-list pairs */
		Assert(list_length(pair) == 2);
		fexpr = (Node *) linitial(pair);
		coldeflist = (List *) lsecond(pair);

		/*
		 * If we find a function call unnest() with more than one argument and
		 * no special decoration, transform it into separate unnest() calls on
		 * each argument.  This is a kluge, for sure, but it's less nasty than
		 * other ways of implementing the SQL-standard UNNEST() syntax.
		 *
		 * If there is any decoration (including a coldeflist), we don't
		 * transform, which probably means a no-such-function error later.  We
		 * could alternatively throw an error right now, but that doesn't seem
		 * tremendously helpful.  If someone is using any such decoration,
		 * then they're not using the SQL-standard syntax, and they're more
		 * likely expecting an un-tweaked function call.
		 *
		 * Note: the transformation changes a non-schema-qualified unnest()
		 * function name into schema-qualified pg_catalog.unnest().  This
		 * choice is also a bit debatable, but it seems reasonable to force
		 * use of built-in unnest() when we make this transformation.
		 */
		if (IsA(fexpr, FuncCall))
		{
			FuncCall   *fc = (FuncCall *) fexpr;

			if (list_length(fc->funcname) == 1 &&
				strcmp(strVal(linitial(fc->funcname)), "unnest") == 0 &&
				list_length(fc->args) > 1 &&
				fc->agg_order == NIL &&
				fc->agg_filter == NULL &&
				fc->over == NULL &&
				!fc->agg_star &&
				!fc->agg_distinct &&
				!fc->func_variadic &&
				coldeflist == NIL)
			{
				ListCell   *lc2;

				foreach(lc2, fc->args)
				{
					Node	   *arg = (Node *) lfirst(lc2);
					FuncCall   *newfc;

					last_srf = pstate->p_last_srf;

					newfc = makeFuncCall(SystemFuncName("unnest"),
										 list_make1(arg),
										 COERCE_EXPLICIT_CALL,
										 fc->location);

					newfexpr = transformExpr(pstate, (Node *) newfc,
											 EXPR_KIND_FROM_FUNCTION);

					/* nodeFunctionscan.c requires SRFs to be at top level */
					if (pstate->p_last_srf != last_srf &&
						pstate->p_last_srf != newfexpr)
						ereport(ERROR,
								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
								 errmsg("set-returning functions must appear at top level of FROM"),
								 parser_errposition(pstate,
													exprLocation(pstate->p_last_srf))));

					funcexprs = lappend(funcexprs, newfexpr);

					funcnames = lappend(funcnames,
										FigureColname((Node *) newfc));

					/* coldeflist is empty, so no error is possible */

					coldeflists = lappend(coldeflists, coldeflist);
				}
				continue;		/* done with this function item */
			}
		}

		/* normal case ... */
		last_srf = pstate->p_last_srf;

		newfexpr = transformExpr(pstate, fexpr,
								 EXPR_KIND_FROM_FUNCTION);

		/* nodeFunctionscan.c requires SRFs to be at top level */
		if (pstate->p_last_srf != last_srf &&
			pstate->p_last_srf != newfexpr)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("set-returning functions must appear at top level of FROM"),
					 parser_errposition(pstate,
										exprLocation(pstate->p_last_srf))));

		funcexprs = lappend(funcexprs, newfexpr);

		funcnames = lappend(funcnames,
							FigureColname(fexpr));

		if (coldeflist && r->coldeflist)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("multiple column definition lists are not allowed for the same function"),
					 parser_errposition(pstate,
										exprLocation((Node *) r->coldeflist))));

		coldeflists = lappend(coldeflists, coldeflist);
	}

	pstate->p_lateral_active = false;

	/*
	 * We must assign collations now so that the RTE exposes correct collation
	 * info for Vars created from it.
	 */
	assign_list_collations(pstate, funcexprs);

	/*
	 * Install the top-level coldeflist if there was one (we already checked
	 * that there was no conflicting per-function coldeflist).
	 *
	 * We only allow this when there's a single function (even after UNNEST
	 * expansion) and no WITH ORDINALITY.  The reason for the latter
	 * restriction is that it's not real clear whether the ordinality column
	 * should be in the coldeflist, and users are too likely to make mistakes
	 * in one direction or the other.  Putting the coldeflist inside ROWS
	 * FROM() is much clearer in this case.
	 */
	if (r->coldeflist)
	{
		if (list_length(funcexprs) != 1)
		{
			if (r->is_rowsfrom)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("ROWS FROM() with multiple functions cannot have a column definition list"),
						 errhint("Put a separate column definition list for each function inside ROWS FROM()."),
						 parser_errposition(pstate,
											exprLocation((Node *) r->coldeflist))));
			else
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("UNNEST() with multiple arguments cannot have a column definition list"),
						 errhint("Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one."),
						 parser_errposition(pstate,
											exprLocation((Node *) r->coldeflist))));
		}
		if (r->ordinality)
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("WITH ORDINALITY cannot be used with a column definition list"),
					 errhint("Put the column definition list inside ROWS FROM()."),
					 parser_errposition(pstate,
										exprLocation((Node *) r->coldeflist))));

		coldeflists = list_make1(r->coldeflist);
	}

	/*
	 * Mark the RTE as LATERAL if the user said LATERAL explicitly, or if
	 * there are any lateral cross-references in it.
	 */
	is_lateral = r->lateral || contain_vars_of_level((Node *) funcexprs, 0);

	/*
	 * OK, build an RTE and nsitem for the function.
	 */
	return addRangeTableEntryForFunction(pstate,
										 funcnames, funcexprs, coldeflists,
										 r, is_lateral, true);
}

/*
 * transformRangeTableFunc -
 *			Transform a raw RangeTableFunc into TableFunc.
 *
 * Transform the namespace clauses, the document-generating expression, the
 * row-generating expression, the column-generating expressions, and the
 * default value expressions.
 */
static ParseNamespaceItem *
transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
{
	TableFunc  *tf = makeNode(TableFunc);
	const char *constructName;
	Oid			docType;
	bool		is_lateral;
	ListCell   *col;
	char	  **names;
	int			colno;

	/* Currently only XMLTABLE is supported */
	constructName = "XMLTABLE";
	docType = XMLOID;

	/*
	 * We make lateral_only names of this level visible, whether or not the
	 * RangeTableFunc is explicitly marked LATERAL.  This is needed for SQL
	 * spec compliance and seems useful on convenience grounds for all
	 * functions in FROM.
	 *
	 * (LATERAL can't nest within a single pstate level, so we don't need
	 * save/restore logic here.)
	 */
	Assert(!pstate->p_lateral_active);
	pstate->p_lateral_active = true;

	/* Transform and apply typecast to the row-generating expression ... */
	Assert(rtf->rowexpr != NULL);
	tf->rowexpr = coerce_to_specific_type(pstate,
										  transformExpr(pstate, rtf->rowexpr, EXPR_KIND_FROM_FUNCTION),
										  TEXTOID,
										  constructName);
	assign_expr_collations(pstate, tf->rowexpr);

	/* ... and to the document itself */
	Assert(rtf->docexpr != NULL);
	tf->docexpr = coerce_to_specific_type(pstate,
										  transformExpr(pstate, rtf->docexpr, EXPR_KIND_FROM_FUNCTION),
										  docType,
										  constructName);
	assign_expr_collations(pstate, tf->docexpr);

	/* undef ordinality column number */
	tf->ordinalitycol = -1;

	/* Process column specs */
	names = palloc(sizeof(char *) * list_length(rtf->columns));

	colno = 0;
	foreach(col, rtf->columns)
	{
		RangeTableFuncCol *rawc = (RangeTableFuncCol *) lfirst(col);
		Oid			typid;
		int32		typmod;
		Node	   *colexpr;
		Node	   *coldefexpr;
		int			j;

		tf->colnames = lappend(tf->colnames,
							   makeString(pstrdup(rawc->colname)));

		/*
		 * Determine the type and typmod for the new column. FOR ORDINALITY
		 * columns are INTEGER per spec; the others are user-specified.
		 */
		if (rawc->for_ordinality)
		{
			if (tf->ordinalitycol != -1)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("only one FOR ORDINALITY column is allowed"),
						 parser_errposition(pstate, rawc->location)));

			typid = INT4OID;
			typmod = -1;
			tf->ordinalitycol = colno;
		}
		else
		{
			if (rawc->typeName->setof)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
						 errmsg("column \"%s\" cannot be declared SETOF",
								rawc->colname),
						 parser_errposition(pstate, rawc->location)));

			typenameTypeIdAndMod(pstate, rawc->typeName,
								 &typid, &typmod);
		}

		tf->coltypes = lappend_oid(tf->coltypes, typid);
		tf->coltypmods = lappend_int(tf->coltypmods, typmod);
		tf->colcollations = lappend_oid(tf->colcollations,
										get_typcollation(typid));

		/* Transform the PATH and DEFAULT expressions */
		if (rawc->colexpr)
		{
			colexpr = coerce_to_specific_type(pstate,
											  transformExpr(pstate, rawc->colexpr,
															EXPR_KIND_FROM_FUNCTION),
											  TEXTOID,
											  constructName);
			assign_expr_collations(pstate, colexpr);
		}
		else
			colexpr = NULL;

		if (rawc->coldefexpr)
		{
			coldefexpr = coerce_to_specific_type_typmod(pstate,
														transformExpr(pstate, rawc->coldefexpr,
																	  EXPR_KIND_FROM_FUNCTION),
														typid, typmod,
														constructName);
			assign_expr_collations(pstate, coldefexpr);
		}
		else
			coldefexpr = NULL;

		tf->colexprs = lappend(tf->colexprs, colexpr);
		tf->coldefexprs = lappend(tf->coldefexprs, coldefexpr);

		if (rawc->is_not_null)
			tf->notnulls = bms_add_member(tf->notnulls, colno);

		/* make sure column names are unique */
		for (j = 0; j < colno; j++)
			if (strcmp(names[j], rawc->colname) == 0)
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("column name \"%s\" is not unique",
								rawc->colname),
						 parser_errposition(pstate, rawc->location)));
		names[colno] = rawc->colname;

		colno++;
	}
	pfree(names);

	/* Namespaces, if any, also need to be transformed */
	if (rtf->namespaces != NIL)
	{
		ListCell   *ns;
		ListCell   *lc2;
		List	   *ns_uris = NIL;
		List	   *ns_names = NIL;
		bool		default_ns_seen = false;

		foreach(ns, rtf->namespaces)
		{
			ResTarget  *r = (ResTarget *) lfirst(ns);
			Node	   *ns_uri;

			Assert(IsA(r, ResTarget));
			ns_uri = transformExpr(pstate, r->val, EXPR_KIND_FROM_FUNCTION);
			ns_uri = coerce_to_specific_type(pstate, ns_uri,
											 TEXTOID, constructName);
			assign_expr_collations(pstate, ns_uri);
			ns_uris = lappend(ns_uris, ns_uri);

			/* Verify consistency of name list: no dupes, only one DEFAULT */
			if (r->name != NULL)
			{
				foreach(lc2, ns_names)
				{
					String	   *ns_node = lfirst_node(String, lc2);

					if (ns_node == NULL)
						continue;
					if (strcmp(strVal(ns_node), r->name) == 0)
						ereport(ERROR,
								(errcode(ERRCODE_SYNTAX_ERROR),
								 errmsg("namespace name \"%s\" is not unique",
										r->name),
								 parser_errposition(pstate, r->location)));
				}
			}
			else
			{
				if (default_ns_seen)
					ereport(ERROR,
							(errcode(ERRCODE_SYNTAX_ERROR),
							 errmsg("only one default namespace is allowed"),
							 parser_errposition(pstate, r->location)));
				default_ns_seen = true;
			}

			/* We represent DEFAULT by a null pointer */
			ns_names = lappend(ns_names,
							   r->name ? makeString(r->name) : NULL);
		}

		tf->ns_uris = ns_uris;
		tf->ns_names = ns_names;
	}

	tf->location = rtf->location;

	pstate->p_lateral_active = false;

	/*
	 * Mark the RTE as LATERAL if the user said LATERAL explicitly, or if
	 * there are any lateral cross-references in it.
	 */
	is_lateral = rtf->lateral || contain_vars_of_level((Node *) tf, 0);

	return addRangeTableEntryForTableFunc(pstate,
										  tf, rtf->alias, is_lateral, true);
}

/*
 * transformRangeTableSample --- transform a TABLESAMPLE clause
 *
 * Caller has already transformed rts->relation, we just have to validate
 * the remaining fields and create a TableSampleClause node.
 */
static TableSampleClause *
transformRangeTableSample(ParseState *pstate, RangeTableSample *rts)
{
	TableSampleClause *tablesample;
	Oid			handlerOid;
	Oid			funcargtypes[1];
	TsmRoutine *tsm;
	List	   *fargs;
	ListCell   *larg,
			   *ltyp;

	/*
	 * To validate the sample method name, look up the handler function, which
	 * has the same name, one dummy INTERNAL argument, and a result type of
	 * tsm_handler.  (Note: tablesample method names are not schema-qualified
	 * in the SQL standard; but since they are just functions to us, we allow
	 * schema qualification to resolve any potential ambiguity.)
	 */
	funcargtypes[0] = INTERNALOID;

	handlerOid = LookupFuncName(rts->method, 1, funcargtypes, true);

	/* we want error to complain about no-such-method, not no-such-function */
	if (!OidIsValid(handlerOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("tablesample method %s does not exist",
						NameListToString(rts->method)),
				 parser_errposition(pstate, rts->location)));

	/* check that handler has correct return type */
	if (get_func_rettype(handlerOid) != TSM_HANDLEROID)
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("function %s must return type %s",
						NameListToString(rts->method), "tsm_handler"),
				 parser_errposition(pstate, rts->location)));

	/* OK, run the handler to get TsmRoutine, for argument type info */
	tsm = GetTsmRoutine(handlerOid);

	tablesample = makeNode(TableSampleClause);
	tablesample->tsmhandler = handlerOid;

	/* check user provided the expected number of arguments */
	if (list_length(rts->args) != list_length(tsm->parameterTypes))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT),
				 errmsg_plural("tablesample method %s requires %d argument, not %d",
							   "tablesample method %s requires %d arguments, not %d",
							   list_length(tsm->parameterTypes),
							   NameListToString(rts->method),
							   list_length(tsm->parameterTypes),
							   list_length(rts->args)),
				 parser_errposition(pstate, rts->location)));

	/*
	 * Transform the arguments, typecasting them as needed.  Note we must also
	 * assign collations now, because assign_query_collations() doesn't
	 * examine any substructure of RTEs.
	 */
	fargs = NIL;
	forboth(larg, rts->args, ltyp, tsm->parameterTypes)
	{
		Node	   *arg = (Node *) lfirst(larg);
		Oid			argtype = lfirst_oid(ltyp);

		arg = transformExpr(pstate, arg, EXPR_KIND_FROM_FUNCTION);
		arg = coerce_to_specific_type(pstate, arg, argtype, "TABLESAMPLE");
		assign_expr_collations(pstate, arg);
		fargs = lappend(fargs, arg);
	}
	tablesample->args = fargs;

	/* Process REPEATABLE (seed) */
	if (rts->repeatable != NULL)
	{
		Node	   *arg;

		if (!tsm->repeatable_across_queries)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("tablesample method %s does not support REPEATABLE",
							NameListToString(rts->method)),
					 parser_errposition(pstate, rts->location)));

		arg = transformExpr(pstate, rts->repeatable, EXPR_KIND_FROM_FUNCTION);
		arg = coerce_to_specific_type(pstate, arg, FLOAT8OID, "REPEATABLE");
		assign_expr_collations(pstate, arg);
		tablesample->repeatable = (Expr *) arg;
	}
	else
		tablesample->repeatable = NULL;

	return tablesample;
}

/*
 * getNSItemForSpecialRelationTypes
 *
 * If given RangeVar refers to a CTE or an EphemeralNamedRelation,
 * build and return an appropriate ParseNamespaceItem, otherwise return NULL
 */
static ParseNamespaceItem *
getNSItemForSpecialRelationTypes(ParseState *pstate, RangeVar *rv)
{
	ParseNamespaceItem *nsitem;
	CommonTableExpr *cte;
	Index		levelsup;

	/*
	 * if it is a qualified name, it can't be a CTE or tuplestore reference
	 */
	if (rv->schemaname)
		return NULL;

	cte = scanNameSpaceForCTE(pstate, rv->relname, &levelsup);
	if (cte)
		nsitem = addRangeTableEntryForCTE(pstate, cte, levelsup, rv, true);
	else if (scanNameSpaceForENR(pstate, rv->relname))
		nsitem = addRangeTableEntryForENR(pstate, rv, true);
	else
		nsitem = NULL;

	return nsitem;
}

/*
 * transformFromClauseItem -
 *	  Transform a FROM-clause item, adding any required entries to the
 *	  range table list being built in the ParseState, and return the
 *	  transformed item ready to include in the joinlist.  Also build a
 *	  ParseNamespaceItem list describing the names exposed by this item.
 *	  This routine can recurse to handle SQL92 JOIN expressions.
 *
 * The function return value is the node to add to the jointree (a
 * RangeTblRef or JoinExpr).  Additional output parameters are:
 *
 * *top_nsitem: receives the ParseNamespaceItem directly corresponding to the
 * jointree item.  (This is only used during internal recursion, not by
 * outside callers.)
 *
 * *namespace: receives a List of ParseNamespaceItems for the RTEs exposed
 * as table/column names by this item.  (The lateral_only flags in these items
 * are indeterminate and should be explicitly set by the caller before use.)
 */
static Node *
transformFromClauseItem(ParseState *pstate, Node *n,
						ParseNamespaceItem **top_nsitem,
						List **namespace)
{
	/* Guard against stack overflow due to overly deep subtree */
	check_stack_depth();

	if (IsA(n, RangeVar))
	{
		/* Plain relation reference, or perhaps a CTE reference */
		RangeVar   *rv = (RangeVar *) n;
		RangeTblRef *rtr;
		ParseNamespaceItem *nsitem;

		/* Check if it's a CTE or tuplestore reference */
		nsitem = getNSItemForSpecialRelationTypes(pstate, rv);

		/* if not found above, must be a table reference */
		if (!nsitem)
			nsitem = transformTableEntry(pstate, rv);

		*top_nsitem = nsitem;
		*namespace = list_make1(nsitem);
		rtr = makeNode(RangeTblRef);
		rtr->rtindex = nsitem->p_rtindex;
		return (Node *) rtr;
	}
	else if (IsA(n, RangeSubselect))
	{
		/* sub-SELECT is like a plain relation */
		RangeTblRef *rtr;
		ParseNamespaceItem *nsitem;

		nsitem = transformRangeSubselect(pstate, (RangeSubselect *) n);
		*top_nsitem = nsitem;
		*namespace = list_make1(nsitem);
		rtr = makeNode(RangeTblRef);
		rtr->rtindex = nsitem->p_rtindex;
		return (Node *) rtr;
	}
	else if (IsA(n, RangeFunction))
	{
		/* function is like a plain relation */
		RangeTblRef *rtr;
		ParseNamespaceItem *nsitem;

		nsitem = transformRangeFunction(pstate, (RangeFunction *) n);
		*top_nsitem = nsitem;
		*namespace = list_make1(nsitem);
		rtr = makeNode(RangeTblRef);
		rtr->rtindex = nsitem->p_rtindex;
		return (Node *) rtr;
	}
	else if (IsA(n, RangeTableFunc))
	{
		/* table function is like a plain relation */
		RangeTblRef *rtr;
		ParseNamespaceItem *nsitem;

		nsitem = transformRangeTableFunc(pstate, (RangeTableFunc *) n);
		*top_nsitem = nsitem;
		*namespace = list_make1(nsitem);
		rtr = makeNode(RangeTblRef);
		rtr->rtindex = nsitem->p_rtindex;
		return (Node *) rtr;
	}
	else if (IsA(n, RangeTableSample))
	{
		/* TABLESAMPLE clause (wrapping some other valid FROM node) */
		RangeTableSample *rts = (RangeTableSample *) n;
		Node	   *rel;
		RangeTblEntry *rte;

		/* Recursively transform the contained relation */
		rel = transformFromClauseItem(pstate, rts->relation,
									  top_nsitem, namespace);
		rte = (*top_nsitem)->p_rte;
		/* We only support this on plain relations and matviews */
		if (rte->rtekind != RTE_RELATION ||
			(rte->relkind != RELKIND_RELATION &&
			 rte->relkind != RELKIND_MATVIEW &&
			 rte->relkind != RELKIND_PARTITIONED_TABLE &&
			 rte->relkind != RELKIND_DIRECTORY_TABLE))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("TABLESAMPLE clause can only be applied to tables and materialized views"),
					 parser_errposition(pstate, exprLocation(rts->relation))));

		/* Transform TABLESAMPLE details and attach to the RTE */
		rte->tablesample = transformRangeTableSample(pstate, rts);
		return rel;
	}
	else if (IsA(n, JoinExpr))
	{
		/* A newfangled join expression */
		JoinExpr   *j = (JoinExpr *) n;
		ParseNamespaceItem *nsitem;
		ParseNamespaceItem *l_nsitem;
		ParseNamespaceItem *r_nsitem;
		List	   *l_namespace,
				   *r_namespace,
				   *my_namespace,
				   *l_colnames,
				   *r_colnames,
				   *res_colnames,
				   *l_colnos,
				   *r_colnos,
				   *res_colvars;
		ParseNamespaceColumn *l_nscolumns,
				   *r_nscolumns,
				   *res_nscolumns;
		int			res_colindex;
		bool		lateral_ok;
		int			sv_namespace_length;
		int			k;

		/*
		 * Recursively process the left subtree, then the right.  We must do
		 * it in this order for correct visibility of LATERAL references.
		 */
		j->larg = transformFromClauseItem(pstate, j->larg,
										  &l_nsitem,
										  &l_namespace);

		/*
		 * Make the left-side RTEs available for LATERAL access within the
		 * right side, by temporarily adding them to the pstate's namespace
		 * list.  Per SQL:2008, if the join type is not INNER or LEFT then the
		 * left-side names must still be exposed, but it's an error to
		 * reference them.  (Stupid design, but that's what it says.)  Hence,
		 * we always push them into the namespace, but mark them as not
		 * lateral_ok if the jointype is wrong.
		 *
		 * Notice that we don't require the merged namespace list to be
		 * conflict-free.  See the comments for scanNameSpaceForRefname().
		 */
		lateral_ok = (j->jointype == JOIN_INNER || j->jointype == JOIN_LEFT);
		setNamespaceLateralState(l_namespace, true, lateral_ok);

		sv_namespace_length = list_length(pstate->p_namespace);
		pstate->p_namespace = list_concat(pstate->p_namespace, l_namespace);

		/* And now we can process the RHS */
		j->rarg = transformFromClauseItem(pstate, j->rarg,
										  &r_nsitem,
										  &r_namespace);

		/* Remove the left-side RTEs from the namespace list again */
		pstate->p_namespace = list_truncate(pstate->p_namespace,
											sv_namespace_length);

		/*
		 * Check for conflicting refnames in left and right subtrees. Must do
		 * this because higher levels will assume I hand back a self-
		 * consistent namespace list.
		 */
		checkNameSpaceConflicts(pstate, l_namespace, r_namespace);

		/*
		 * Generate combined namespace info for possible use below.
		 */
		my_namespace = list_concat(l_namespace, r_namespace);

		/*
		 * We'll work from the nscolumns data and eref alias column names for
		 * each of the input nsitems.  Note that these include dropped
		 * columns, which is helpful because we can keep track of physical
		 * input column numbers more easily.
		 */
		l_nscolumns = l_nsitem->p_nscolumns;
		l_colnames = l_nsitem->p_names->colnames;
		r_nscolumns = r_nsitem->p_nscolumns;
		r_colnames = r_nsitem->p_names->colnames;

		/*
		 * Natural join does not explicitly specify columns; must generate
		 * columns to join. Need to run through the list of columns from each
		 * table or join result and match up the column names. Use the first
		 * table, and check every column in the second table for a match.
		 * (We'll check that the matches were unique later on.) The result of
		 * this step is a list of column names just like an explicitly-written
		 * USING list.
		 */
		if (j->isNatural)
		{
			List	   *rlist = NIL;
			ListCell   *lx,
					   *rx;

			Assert(j->usingClause == NIL);	/* shouldn't have USING() too */

			foreach(lx, l_colnames)
			{
				char	   *l_colname = strVal(lfirst(lx));
				String	   *m_name = NULL;

				if (l_colname[0] == '\0')
					continue;	/* ignore dropped columns */

				foreach(rx, r_colnames)
				{
					char	   *r_colname = strVal(lfirst(rx));

					if (strcmp(l_colname, r_colname) == 0)
					{
						m_name = makeString(l_colname);
						break;
					}
				}

				/* matched a right column? then keep as join column... */
				if (m_name != NULL)
					rlist = lappend(rlist, m_name);
			}

			j->usingClause = rlist;
		}

		/*
		 * If a USING clause alias was specified, save the USING columns as
		 * its column list.
		 */
		if (j->join_using_alias)
			j->join_using_alias->colnames = j->usingClause;

		/*
		 * Now transform the join qualifications, if any.
		 */
		l_colnos = NIL;
		r_colnos = NIL;
		res_colnames = NIL;
		res_colvars = NIL;

		/* this may be larger than needed, but it's not worth being exact */
		res_nscolumns = (ParseNamespaceColumn *)
			palloc0((list_length(l_colnames) + list_length(r_colnames)) *
					sizeof(ParseNamespaceColumn));
		res_colindex = 0;

		if (j->usingClause)
		{
			/*
			 * JOIN/USING (or NATURAL JOIN, as transformed above). Transform
			 * the list into an explicit ON-condition.
			 */
			List	   *ucols = j->usingClause;
			List	   *l_usingvars = NIL;
			List	   *r_usingvars = NIL;
			ListCell   *ucol;

			Assert(j->quals == NULL);	/* shouldn't have ON() too */

			foreach(ucol, ucols)
			{
				char	   *u_colname = strVal(lfirst(ucol));
				ListCell   *col;
				int			ndx;
				int			l_index = -1;
				int			r_index = -1;
				Var		   *l_colvar,
						   *r_colvar;

				Assert(u_colname[0] != '\0');

				/* Check for USING(foo,foo) */
				foreach(col, res_colnames)
				{
					char	   *res_colname = strVal(lfirst(col));

					if (strcmp(res_colname, u_colname) == 0)
						ereport(ERROR,
								(errcode(ERRCODE_DUPLICATE_COLUMN),
								 errmsg("column name \"%s\" appears more than once in USING clause",
										u_colname)));
				}

				/* Find it in left input */
				ndx = 0;
				foreach(col, l_colnames)
				{
					char	   *l_colname = strVal(lfirst(col));

					if (strcmp(l_colname, u_colname) == 0)
					{
						if (l_index >= 0)
							ereport(ERROR,
									(errcode(ERRCODE_AMBIGUOUS_COLUMN),
									 errmsg("common column name \"%s\" appears more than once in left table",
											u_colname)));
						l_index = ndx;
					}
					ndx++;
				}
				if (l_index < 0)
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_COLUMN),
							 errmsg("column \"%s\" specified in USING clause does not exist in left table",
									u_colname)));
				l_colnos = lappend_int(l_colnos, l_index + 1);

				/* Find it in right input */
				ndx = 0;
				foreach(col, r_colnames)
				{
					char	   *r_colname = strVal(lfirst(col));

					if (strcmp(r_colname, u_colname) == 0)
					{
						if (r_index >= 0)
							ereport(ERROR,
									(errcode(ERRCODE_AMBIGUOUS_COLUMN),
									 errmsg("common column name \"%s\" appears more than once in right table",
											u_colname)));
						r_index = ndx;
					}
					ndx++;
				}
				if (r_index < 0)
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_COLUMN),
							 errmsg("column \"%s\" specified in USING clause does not exist in right table",
									u_colname)));
				r_colnos = lappend_int(r_colnos, r_index + 1);

				/* Build Vars to use in the generated JOIN ON clause */
				l_colvar = buildVarFromNSColumn(pstate, l_nscolumns + l_index);
				l_usingvars = lappend(l_usingvars, l_colvar);
				r_colvar = buildVarFromNSColumn(pstate, r_nscolumns + r_index);
				r_usingvars = lappend(r_usingvars, r_colvar);

				/*
				 * While we're here, add column names to the res_colnames
				 * list.  It's a bit ugly to do this here while the
				 * corresponding res_colvars entries are not made till later,
				 * but doing this later would require an additional traversal
				 * of the usingClause list.
				 */
				res_colnames = lappend(res_colnames, lfirst(ucol));
			}

			/* Construct the generated JOIN ON clause */
			j->quals = transformJoinUsingClause(pstate,
												l_usingvars,
												r_usingvars);
		}
		else if (j->quals)
		{
			/* User-written ON-condition; transform it */
			j->quals = transformJoinOnClause(pstate, j, my_namespace);
		}
		else
		{
			/* CROSS JOIN: no quals */
		}

		/*
		 * If this is an outer join, now mark the appropriate child RTEs as
		 * being nulled by this join.  We have finished processing the child
		 * join expressions as well as the current join's quals, which deal in
		 * non-nulled input columns.  All future references to those RTEs will
		 * see possibly-nulled values, and we should mark generated Vars to
		 * account for that.  In particular, the join alias Vars that we're
		 * about to build should reflect the nulling effects of this join.
		 *
		 * A difficulty with doing this is that we need the join's RT index,
		 * which we don't officially have yet.  However, no other RTE can get
		 * made between here and the addRangeTableEntryForJoin call, so we can
		 * predict what the assignment will be.  (Alternatively, we could call
		 * addRangeTableEntryForJoin before we have all the data computed, but
		 * this seems less ugly.)
		 */
		j->rtindex = list_length(pstate->p_rtable) + 1;

		switch (j->jointype)
		{
			case JOIN_INNER:
				break;
			case JOIN_LEFT:
				markRelsAsNulledBy(pstate, j->rarg, j->rtindex);
				break;
			case JOIN_FULL:
				markRelsAsNulledBy(pstate, j->larg, j->rtindex);
				markRelsAsNulledBy(pstate, j->rarg, j->rtindex);
				break;
			case JOIN_RIGHT:
				markRelsAsNulledBy(pstate, j->larg, j->rtindex);
				break;
			default:
				/* shouldn't see any other types here */
				elog(ERROR, "unrecognized join type: %d",
					 (int) j->jointype);
				break;
		}

		/*
		 * Now we can construct join alias expressions for the USING columns.
		 */
		if (j->usingClause)
		{
			ListCell   *lc1,
					   *lc2;

			/* Scan the colnos lists to recover info from the previous loop */
			forboth(lc1, l_colnos, lc2, r_colnos)
			{
				int			l_index = lfirst_int(lc1) - 1;
				int			r_index = lfirst_int(lc2) - 1;
				Var		   *l_colvar,
						   *r_colvar;
				Node	   *u_colvar;
				ParseNamespaceColumn *res_nscolumn;

				/*
				 * Note we re-build these Vars: they might have different
				 * varnullingrels than the ones made in the previous loop.
				 */
				l_colvar = buildVarFromNSColumn(pstate, l_nscolumns + l_index);
				r_colvar = buildVarFromNSColumn(pstate, r_nscolumns + r_index);

				/* Construct the join alias Var for this column */
				u_colvar = buildMergedJoinVar(pstate,
											  j->jointype,
											  l_colvar,
											  r_colvar);
				res_colvars = lappend(res_colvars, u_colvar);

				/* Construct column's res_nscolumns[] entry */
				res_nscolumn = res_nscolumns + res_colindex;
				res_colindex++;
				if (u_colvar == (Node *) l_colvar)
				{
					/* Merged column is equivalent to left input */
					*res_nscolumn = l_nscolumns[l_index];
				}
				else if (u_colvar == (Node *) r_colvar)
				{
					/* Merged column is equivalent to right input */
					*res_nscolumn = r_nscolumns[r_index];
				}
				else
				{
					/*
					 * Merged column is not semantically equivalent to either
					 * input, so it needs to be referenced as the join output
					 * column.
					 */
					res_nscolumn->p_varno = j->rtindex;
					res_nscolumn->p_varattno = res_colindex;
					res_nscolumn->p_vartype = exprType(u_colvar);
					res_nscolumn->p_vartypmod = exprTypmod(u_colvar);
					res_nscolumn->p_varcollid = exprCollation(u_colvar);
					res_nscolumn->p_varnosyn = j->rtindex;
					res_nscolumn->p_varattnosyn = res_colindex;
				}
			}
		}

		/* Add remaining columns from each side to the output columns */
		res_colindex +=
			extractRemainingColumns(pstate,
									l_nscolumns, l_colnames, &l_colnos,
									&res_colnames, &res_colvars,
									res_nscolumns + res_colindex);
		res_colindex +=
			extractRemainingColumns(pstate,
									r_nscolumns, r_colnames, &r_colnos,
									&res_colnames, &res_colvars,
									res_nscolumns + res_colindex);

		/* If join has an alias, it syntactically hides all inputs */
		if (j->alias)
		{
			for (k = 0; k < res_colindex; k++)
			{
				ParseNamespaceColumn *nscol = res_nscolumns + k;

				nscol->p_varnosyn = j->rtindex;
				nscol->p_varattnosyn = k + 1;
			}
		}

		/*
		 * Now build an RTE and nsitem for the result of the join.
		 */
		nsitem = addRangeTableEntryForJoin(pstate,
										   res_colnames,
										   res_nscolumns,
										   j->jointype,
										   list_length(j->usingClause),
										   res_colvars,
										   l_colnos,
										   r_colnos,
										   j->join_using_alias,
										   j->alias,
										   true);

		/* Verify that we correctly predicted the join's RT index */
		Assert(j->rtindex == nsitem->p_rtindex);
		/* Cross-check number of columns, too */
		Assert(res_colindex == list_length(nsitem->p_names->colnames));

		/*
		 * Save a link to the JoinExpr in the proper element of p_joinexprs.
		 * Since we maintain that list lazily, it may be necessary to fill in
		 * empty entries before we can add the JoinExpr in the right place.
		 */
		for (k = list_length(pstate->p_joinexprs) + 1; k < j->rtindex; k++)
			pstate->p_joinexprs = lappend(pstate->p_joinexprs, NULL);
		pstate->p_joinexprs = lappend(pstate->p_joinexprs, j);
		Assert(list_length(pstate->p_joinexprs) == j->rtindex);

		/*
		 * If the join has a USING alias, build a ParseNamespaceItem for that
		 * and add it to the list of nsitems in the join's input.
		 */
		if (j->join_using_alias)
		{
			ParseNamespaceItem *jnsitem;

			jnsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem));
			jnsitem->p_names = j->join_using_alias;
			jnsitem->p_rte = nsitem->p_rte;
			jnsitem->p_rtindex = nsitem->p_rtindex;
			jnsitem->p_perminfo = NULL;
			/* no need to copy the first N columns, just use res_nscolumns */
			jnsitem->p_nscolumns = res_nscolumns;
			/* set default visibility flags; might get changed later */
			jnsitem->p_rel_visible = true;
			jnsitem->p_cols_visible = true;
			jnsitem->p_lateral_only = false;
			jnsitem->p_lateral_ok = true;
			/* Per SQL, we must check for alias conflicts */
			checkNameSpaceConflicts(pstate, list_make1(jnsitem), my_namespace);
			my_namespace = lappend(my_namespace, jnsitem);
		}

		/*
		 * Prepare returned namespace list.  If the JOIN has an alias then it
		 * hides the contained RTEs completely; otherwise, the contained RTEs
		 * are still visible as table names, but are not visible for
		 * unqualified column-name access.
		 *
		 * Note: if there are nested alias-less JOINs, the lower-level ones
		 * will remain in the list although they have neither p_rel_visible
		 * nor p_cols_visible set.  We could delete such list items, but it's
		 * unclear that it's worth expending cycles to do so.
		 */
		if (j->alias != NULL)
			my_namespace = NIL;
		else
			setNamespaceColumnVisibility(my_namespace, false);

		/*
		 * The join RTE itself is always made visible for unqualified column
		 * names.  It's visible as a relation name only if it has an alias.
		 */
		nsitem->p_rel_visible = (j->alias != NULL);
		nsitem->p_cols_visible = true;
		nsitem->p_lateral_only = false;
		nsitem->p_lateral_ok = true;

		*top_nsitem = nsitem;
		*namespace = lappend(my_namespace, nsitem);

		return (Node *) j;
	}
	else
		elog(ERROR, "unrecognized node type: %d", (int) nodeTag(n));
	return NULL;				/* can't get here, keep compiler quiet */
}

/*
 * buildVarFromNSColumn -
 *	  build a Var node using ParseNamespaceColumn data
 *
 * This is used to construct joinaliasvars entries.
 * We can assume varlevelsup should be 0, and no location is specified.
 * Note also that no column SELECT privilege is requested here; that would
 * happen only if the column is actually referenced in the query.
 */
static Var *
buildVarFromNSColumn(ParseState *pstate, ParseNamespaceColumn *nscol)
{
	Var		   *var;

	Assert(nscol->p_varno > 0); /* i.e., not deleted column */
	var = makeVar(nscol->p_varno,
				  nscol->p_varattno,
				  nscol->p_vartype,
				  nscol->p_vartypmod,
				  nscol->p_varcollid,
				  0);
	/* makeVar doesn't offer parameters for these, so set by hand: */
	var->varnosyn = nscol->p_varnosyn;
	var->varattnosyn = nscol->p_varattnosyn;

	/* ... and update varnullingrels */
	markNullableIfNeeded(pstate, var);

	return var;
}

/*
 * buildMergedJoinVar -
 *	  generate a suitable replacement expression for a merged join column
 */
static Node *
buildMergedJoinVar(ParseState *pstate, JoinType jointype,
				   Var *l_colvar, Var *r_colvar)
{
	Oid			outcoltype;
	int32		outcoltypmod;
	Node	   *l_node,
			   *r_node,
			   *res_node;

	outcoltype = select_common_type(pstate,
									list_make2(l_colvar, r_colvar),
									"JOIN/USING",
									NULL);
	outcoltypmod = select_common_typmod(pstate,
										list_make2(l_colvar, r_colvar),
										outcoltype);

	/*
	 * Insert coercion functions if needed.  Note that a difference in typmod
	 * can only happen if input has typmod but outcoltypmod is -1. In that
	 * case we insert a RelabelType to clearly mark that result's typmod is
	 * not same as input.  We never need coerce_type_typmod.
	 */
	if (l_colvar->vartype != outcoltype)
		l_node = coerce_type(pstate, (Node *) l_colvar, l_colvar->vartype,
							 outcoltype, outcoltypmod,
							 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
	else if (l_colvar->vartypmod != outcoltypmod)
		l_node = (Node *) makeRelabelType((Expr *) l_colvar,
										  outcoltype, outcoltypmod,
										  InvalidOid,	/* fixed below */
										  COERCE_IMPLICIT_CAST);
	else
		l_node = (Node *) l_colvar;

	if (r_colvar->vartype != outcoltype)
		r_node = coerce_type(pstate, (Node *) r_colvar, r_colvar->vartype,
							 outcoltype, outcoltypmod,
							 COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
	else if (r_colvar->vartypmod != outcoltypmod)
		r_node = (Node *) makeRelabelType((Expr *) r_colvar,
										  outcoltype, outcoltypmod,
										  InvalidOid,	/* fixed below */
										  COERCE_IMPLICIT_CAST);
	else
		r_node = (Node *) r_colvar;

	/*
	 * Choose what to emit
	 */
	switch (jointype)
	{
		case JOIN_INNER:

			/*
			 * We can use either var; prefer non-coerced one if available.
			 */
			if (IsA(l_node, Var))
				res_node = l_node;
			else if (IsA(r_node, Var))
				res_node = r_node;
			else
				res_node = l_node;
			break;
		case JOIN_LEFT:
			/* Always use left var */
			res_node = l_node;
			break;
		case JOIN_RIGHT:
			/* Always use right var */
			res_node = r_node;
			break;
		case JOIN_FULL:
			{
				/*
				 * Here we must build a COALESCE expression to ensure that the
				 * join output is non-null if either input is.
				 */
				CoalesceExpr *c = makeNode(CoalesceExpr);

				c->coalescetype = outcoltype;
				/* coalescecollid will get set below */
				c->args = list_make2(l_node, r_node);
				c->location = -1;
				res_node = (Node *) c;
				break;
			}
		default:
			elog(ERROR, "unrecognized join type: %d", (int) jointype);
			res_node = NULL;	/* keep compiler quiet */
			break;
	}

	/*
	 * Apply assign_expr_collations to fix up the collation info in the
	 * coercion and CoalesceExpr nodes, if we made any.  This must be done now
	 * so that the join node's alias vars show correct collation info.
	 */
	assign_expr_collations(pstate, res_node);

	return res_node;
}

/*
 * markRelsAsNulledBy -
 *	  Mark the given jointree node and its children as nulled by join jindex
 */
static void
markRelsAsNulledBy(ParseState *pstate, Node *n, int jindex)
{
	int			varno;
	ListCell   *lc;

	/* Note: we can't see FromExpr here */
	if (IsA(n, RangeTblRef))
	{
		varno = ((RangeTblRef *) n)->rtindex;
	}
	else if (IsA(n, JoinExpr))
	{
		JoinExpr   *j = (JoinExpr *) n;

		/* recurse to children */
		markRelsAsNulledBy(pstate, j->larg, jindex);
		markRelsAsNulledBy(pstate, j->rarg, jindex);
		varno = j->rtindex;
	}
	else
	{
		elog(ERROR, "unrecognized node type: %d", (int) nodeTag(n));
		varno = 0;				/* keep compiler quiet */
	}

	/*
	 * Now add jindex to the p_nullingrels set for relation varno.  Since we
	 * maintain the p_nullingrels list lazily, we might need to extend it to
	 * make the varno'th entry exist.
	 */
	while (list_length(pstate->p_nullingrels) < varno)
		pstate->p_nullingrels = lappend(pstate->p_nullingrels, NULL);
	lc = list_nth_cell(pstate->p_nullingrels, varno - 1);
	lfirst(lc) = bms_add_member((Bitmapset *) lfirst(lc), jindex);
}

/*
 * setNamespaceColumnVisibility -
 *	  Convenience subroutine to update cols_visible flags in a namespace list.
 */
static void
setNamespaceColumnVisibility(List *namespace, bool cols_visible)
{
	ListCell   *lc;

	foreach(lc, namespace)
	{
		ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);

		nsitem->p_cols_visible = cols_visible;
	}
}

/*
 * setNamespaceLateralState -
 *	  Convenience subroutine to update LATERAL flags in a namespace list.
 */
static void
setNamespaceLateralState(List *namespace, bool lateral_only, bool lateral_ok)
{
	ListCell   *lc;

	foreach(lc, namespace)
	{
		ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);

		nsitem->p_lateral_only = lateral_only;
		nsitem->p_lateral_ok = lateral_ok;
	}
}


/*
 * transformWhereClause -
 *	  Transform the qualification and make sure it is of type boolean.
 *	  Used for WHERE and allied clauses.
 *
 * constructName does not affect the semantics, but is used in error messages
 */
Node *
transformWhereClause(ParseState *pstate, Node *clause,
					 ParseExprKind exprKind, const char *constructName)
{
	Node	   *qual;

	if (clause == NULL)
		return NULL;

	qual = transformExpr(pstate, clause, exprKind);

	qual = coerce_to_boolean(pstate, qual, constructName);

	return qual;
}


/*
 * transformLimitClause -
 *	  Transform the expression and make sure it is of type bigint.
 *	  Used for LIMIT and allied clauses.
 *
 * Note: as of Postgres 8.2, LIMIT expressions are expected to yield int8,
 * rather than int4 as before.
 *
 * constructName does not affect the semantics, but is used in error messages
 */
Node *
transformLimitClause(ParseState *pstate, Node *clause,
					 ParseExprKind exprKind, const char *constructName,
					 LimitOption limitOption)
{
	Node	   *qual;

	if (clause == NULL)
		return NULL;

	qual = transformExpr(pstate, clause, exprKind);

	qual = coerce_to_specific_type(pstate, qual, INT8OID, constructName);

	/* LIMIT can't refer to any variables of the current query */
	checkExprIsVarFree(pstate, qual, constructName);

	/*
	 * Don't allow NULLs in FETCH FIRST .. WITH TIES.  This test is ugly and
	 * extremely simplistic, in that you can pass a NULL anyway by hiding it
	 * inside an expression -- but this protects ruleutils against emitting an
	 * unadorned NULL that's not accepted back by the grammar.
	 */
	if (exprKind == EXPR_KIND_LIMIT && limitOption == LIMIT_OPTION_WITH_TIES &&
		IsA(clause, A_Const) && castNode(A_Const, clause)->isnull)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE),
				 errmsg("row count cannot be null in FETCH FIRST ... WITH TIES clause")));

	return qual;
}

/*
 * checkExprIsVarFree
 *		Check that given expr has no Vars of the current query level
 *		(aggregates and window functions should have been rejected already).
 *
 * This is used to check expressions that have to have a consistent value
 * across all rows of the query, such as a LIMIT.  Arguably it should reject
 * volatile functions, too, but we don't do that --- whatever value the
 * function gives on first execution is what you get.
 *
 * constructName does not affect the semantics, but is used in error messages
 */
static void
checkExprIsVarFree(ParseState *pstate, Node *n, const char *constructName)
{
	if (contain_vars_of_level(n, 0))
	{
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
		/* translator: %s is name of a SQL construct, eg LIMIT */
				 errmsg("argument of %s must not contain variables",
						constructName),
				 parser_errposition(pstate,
									locate_var_of_level(n, 0))));
	}
}


/*
 * checkTargetlistEntrySQL92 -
 *	  Validate a targetlist entry found by findTargetlistEntrySQL92
 *
 * When we select a pre-existing tlist entry as a result of syntax such
 * as "GROUP BY 1", we have to make sure it is acceptable for use in the
 * indicated clause type; transformExpr() will have treated it as a regular
 * targetlist item.
 */
static void
checkTargetlistEntrySQL92(ParseState *pstate, TargetEntry *tle,
						  ParseExprKind exprKind)
{
	switch (exprKind)
	{
		case EXPR_KIND_GROUP_BY:
			/* reject aggregates and window functions */
			if (pstate->p_hasAggs &&
				contain_aggs_of_level((Node *) tle->expr, 0))
				ereport(ERROR,
						(errcode(ERRCODE_GROUPING_ERROR),
				/* translator: %s is name of a SQL construct, eg GROUP BY */
						 errmsg("aggregate functions are not allowed in %s",
								ParseExprKindName(exprKind)),
						 parser_errposition(pstate,
											locate_agg_of_level((Node *) tle->expr, 0))));
			if (pstate->p_hasWindowFuncs &&
				contain_windowfuncs((Node *) tle->expr))
				ereport(ERROR,
						(errcode(ERRCODE_WINDOWING_ERROR),
				/* translator: %s is name of a SQL construct, eg GROUP BY */
						 errmsg("window functions are not allowed in %s",
								ParseExprKindName(exprKind)),
						 parser_errposition(pstate,
											locate_windowfunc((Node *) tle->expr))));
			break;
		case EXPR_KIND_ORDER_BY:
			/* no extra checks needed */
			break;
		case EXPR_KIND_DISTINCT_ON:
			/* no extra checks needed */
			break;
		default:
			elog(ERROR, "unexpected exprKind in checkTargetlistEntrySQL92");
			break;
	}
}

/*
 *	findTargetlistEntrySQL92 -
 *	  Returns the targetlist entry matching the given (untransformed) node.
 *	  If no matching entry exists, one is created and appended to the target
 *	  list as a "resjunk" node.
 *
 * This function supports the old SQL92 ORDER BY interpretation, where the
 * expression is an output column name or number.  If we fail to find a
 * match of that sort, we fall through to the SQL99 rules.  For historical
 * reasons, Postgres also allows this interpretation for GROUP BY, though
 * the standard never did.  However, for GROUP BY we prefer a SQL99 match.
 * This function is *not* used for WINDOW definitions.
 *
 * node		the ORDER BY, GROUP BY, or DISTINCT ON expression to be matched
 * tlist	the target list (passed by reference so we can append to it)
 * exprKind identifies clause type being processed
 */
static TargetEntry *
findTargetlistEntrySQL92(ParseState *pstate, Node *node, List **tlist,
						 ParseExprKind exprKind)
{
	ListCell   *tl;

	/*----------
	 * Handle two special cases as mandated by the SQL92 spec:
	 *
	 * 1. Bare ColumnName (no qualifier or subscripts)
	 *	  For a bare identifier, we search for a matching column name
	 *	  in the existing target list.  Multiple matches are an error
	 *	  unless they refer to identical values; for example,
	 *	  we allow	SELECT a, a FROM table ORDER BY a
	 *	  but not	SELECT a AS b, b FROM table ORDER BY b
	 *	  If no match is found, we fall through and treat the identifier
	 *	  as an expression.
	 *	  For GROUP BY, it is incorrect to match the grouping item against
	 *	  targetlist entries: according to SQL92, an identifier in GROUP BY
	 *	  is a reference to a column name exposed by FROM, not to a target
	 *	  list column.  However, many implementations (including pre-7.0
	 *	  PostgreSQL) accept this anyway.  So for GROUP BY, we look first
	 *	  to see if the identifier matches any FROM column name, and only
	 *	  try for a targetlist name if it doesn't.  This ensures that we
	 *	  adhere to the spec in the case where the name could be both.
	 *	  DISTINCT ON isn't in the standard, so we can do what we like there;
	 *	  we choose to make it work like ORDER BY, on the rather flimsy
	 *	  grounds that ordinary DISTINCT works on targetlist entries.
	 *
	 * 2. IntegerConstant
	 *	  This means to use the n'th item in the existing target list.
	 *	  Note that it would make no sense to order/group/distinct by an
	 *	  actual constant, so this does not create a conflict with SQL99.
	 *	  GROUP BY column-number is not allowed by SQL92, but since
	 *	  the standard has no other behavior defined for this syntax,
	 *	  we may as well accept this common extension.
	 *
	 * Note that pre-existing resjunk targets must not be used in either case,
	 * since the user didn't write them in his SELECT list.
	 *
	 * If neither special case applies, fall through to treat the item as
	 * an expression per SQL99.
	 *----------
	 */
	if (IsA(node, ColumnRef) &&
		list_length(((ColumnRef *) node)->fields) == 1 &&
		IsA(linitial(((ColumnRef *) node)->fields), String))
	{
		char	   *name = strVal(linitial(((ColumnRef *) node)->fields));
		int			location = ((ColumnRef *) node)->location;

		if (exprKind == EXPR_KIND_GROUP_BY)
		{
			/*
			 * In GROUP BY, we must prefer a match against a FROM-clause
			 * column to one against the targetlist.  Look to see if there is
			 * a matching column.  If so, fall through to use SQL99 rules.
			 * NOTE: if name could refer ambiguously to more than one column
			 * name exposed by FROM, colNameToVar will ereport(ERROR). That's
			 * just what we want here.
			 *
			 * Small tweak for 7.4.3: ignore matches in upper query levels.
			 * This effectively changes the search order for bare names to (1)
			 * local FROM variables, (2) local targetlist aliases, (3) outer
			 * FROM variables, whereas before it was (1) (3) (2). SQL92 and
			 * SQL99 do not allow GROUPing BY an outer reference, so this
			 * breaks no cases that are legal per spec, and it seems a more
			 * self-consistent behavior.
			 */
			if (colNameToVar(pstate, name, true, location) != NULL)
				name = NULL;
		}

		if (name != NULL)
		{
			TargetEntry *target_result = NULL;

			foreach(tl, *tlist)
			{
				TargetEntry *tle = (TargetEntry *) lfirst(tl);

				if (!tle->resjunk &&
					strcmp(tle->resname, name) == 0)
				{
					if (target_result != NULL)
					{
						if (!equal(target_result->expr, tle->expr))
							ereport(ERROR,
									(errcode(ERRCODE_AMBIGUOUS_COLUMN),

							/*------
							  translator: first %s is name of a SQL construct, eg ORDER BY */
									 errmsg("%s \"%s\" is ambiguous",
											ParseExprKindName(exprKind),
											name),
									 parser_errposition(pstate, location)));
					}
					else
						target_result = tle;
					/* Stay in loop to check for ambiguity */
				}
			}
			if (target_result != NULL)
			{
				/* return the first match, after suitable validation */
				checkTargetlistEntrySQL92(pstate, target_result, exprKind);
				return target_result;
			}
		}
	}
	if (IsA(node, A_Const))
	{
		A_Const    *aconst = castNode(A_Const, node);
		int			targetlist_pos = 0;
		int			target_pos;

		if (!IsA(&aconst->val, Integer))
			ereport(ERROR,
					(errcode(ERRCODE_SYNTAX_ERROR),
			/* translator: %s is name of a SQL construct, eg ORDER BY */
					 errmsg("non-integer constant in %s",
							ParseExprKindName(exprKind)),
					 parser_errposition(pstate, aconst->location)));

		target_pos = intVal(&aconst->val);
		foreach(tl, *tlist)
		{
			TargetEntry *tle = (TargetEntry *) lfirst(tl);

			if (!tle->resjunk)
			{
				if (++targetlist_pos == target_pos)
				{
					/* return the unique match, after suitable validation */
					checkTargetlistEntrySQL92(pstate, tle, exprKind);
					return tle;
				}
			}
		}
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
		/* translator: %s is name of a SQL construct, eg ORDER BY */
				 errmsg("%s position %d is not in select list",
						ParseExprKindName(exprKind), target_pos),
				 parser_errposition(pstate, aconst->location)));
	}

	/*
	 * Otherwise, we have an expression, so process it per SQL99 rules.
	 */
	return findTargetlistEntrySQL99(pstate, node, tlist, exprKind);
}

/*
 *	findTargetlistEntrySQL99 -
 *	  Returns the targetlist entry matching the given (untransformed) node.
 *	  If no matching entry exists, one is created and appended to the target
 *	  list as a "resjunk" node.
 *
 * This function supports the SQL99 interpretation, wherein the expression
 * is just an ordinary expression referencing input column names.
 *
 * node		the ORDER BY, GROUP BY, etc expression to be matched
 * tlist	the target list (passed by reference so we can append to it)
 * exprKind identifies clause type being processed
 */
static TargetEntry *
findTargetlistEntrySQL99(ParseState *pstate, Node *node, List **tlist,
						 ParseExprKind exprKind)
{
	TargetEntry *target_result;
	ListCell   *tl;
	Node	   *expr;

	/*
	 * Convert the untransformed node to a transformed expression, and search
	 * for a match in the tlist.  NOTE: it doesn't really matter whether there
	 * is more than one match.  Also, we are willing to match an existing
	 * resjunk target here, though the SQL92 cases above must ignore resjunk
	 * targets.
	 */
	expr = transformExpr(pstate, node, exprKind);

	foreach(tl, *tlist)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(tl);
		Node	   *texpr;

		/*
		 * Ignore any implicit cast on the existing tlist expression.
		 *
		 * This essentially allows the ORDER/GROUP/etc item to adopt the same
		 * datatype previously selected for a textually-equivalent tlist item.
		 * There can't be any implicit cast at top level in an ordinary SELECT
		 * tlist at this stage, but the case does arise with ORDER BY in an
		 * aggregate function.
		 */
		texpr = strip_implicit_coercions((Node *) tle->expr);

		if (equal(expr, texpr))
			return tle;
	}

	/*
	 * If no matches, construct a new target entry which is appended to the
	 * end of the target list.  This target is given resjunk = true so that it
	 * will not be projected into the final tuple.
	 */
	target_result = transformTargetEntry(pstate, node, expr, exprKind,
										 NULL, true);

	*tlist = lappend(*tlist, target_result);

	return target_result;
}

/*-------------------------------------------------------------------------
 * Flatten out parenthesized sublists in grouping lists, and some cases
 * of nested grouping sets.
 *
 * Inside a grouping set (ROLLUP, CUBE, or GROUPING SETS), we expect the
 * content to be nested no more than 2 deep: i.e. ROLLUP((a,b),(c,d)) is
 * ok, but ROLLUP((a,(b,c)),d) is flattened to ((a,b,c),d), which we then
 * (later) normalize to ((a,b,c),(d)).
 *
 * CUBE or ROLLUP can be nested inside GROUPING SETS (but not the reverse),
 * and we leave that alone if we find it. But if we see GROUPING SETS inside
 * GROUPING SETS, we can flatten and normalize as follows:
 *	 GROUPING SETS (a, (b,c), GROUPING SETS ((c,d),(e)), (f,g))
 * becomes
 *	 GROUPING SETS ((a), (b,c), (c,d), (e), (f,g))
 *
 * This is per the spec's syntax transformations, but these are the only such
 * transformations we do in parse analysis, so that queries retain the
 * originally specified grouping set syntax for CUBE and ROLLUP as much as
 * possible when deparsed. (Full expansion of the result into a list of
 * grouping sets is left to the planner.)
 *
 * When we're done, the resulting list should contain only these possible
 * elements:
 *	 - an expression
 *	 - a CUBE or ROLLUP with a list of expressions nested 2 deep
 *	 - a GROUPING SET containing any of:
 *		- expression lists
 *		- empty grouping sets
 *		- CUBE or ROLLUP nodes with lists nested 2 deep
 * The return is a new list, but doesn't deep-copy the old nodes except for
 * GroupingSet nodes.
 *
 * As a side effect, flag whether the list has any GroupingSet nodes.
 *-------------------------------------------------------------------------
 */
static Node *
flatten_grouping_sets(Node *expr, bool toplevel, bool *hasGroupingSets)
{
	/* just in case of pathological input */
	check_stack_depth();

	if (expr == (Node *) NIL)
		return (Node *) NIL;

	switch (expr->type)
	{
		case T_RowExpr:
			{
				RowExpr    *r = (RowExpr *) expr;

				if (r->row_format == COERCE_IMPLICIT_CAST)
					return flatten_grouping_sets((Node *) r->args,
												 false, NULL);
			}
			break;
		case T_GroupingSet:
			{
				GroupingSet *gset = (GroupingSet *) expr;
				ListCell   *l2;
				List	   *result_set = NIL;

				if (hasGroupingSets)
					*hasGroupingSets = true;

				/*
				 * at the top level, we skip over all empty grouping sets; the
				 * caller can supply the canonical GROUP BY () if nothing is
				 * left.
				 */

				if (toplevel && gset->kind == GROUPING_SET_EMPTY)
					return (Node *) NIL;

				foreach(l2, gset->content)
				{
					Node	   *n1 = lfirst(l2);
					Node	   *n2 = flatten_grouping_sets(n1, false, NULL);

					if (IsA(n1, GroupingSet) &&
						((GroupingSet *) n1)->kind == GROUPING_SET_SETS)
						result_set = list_concat(result_set, (List *) n2);
					else
						result_set = lappend(result_set, n2);
				}

				/*
				 * At top level, keep the grouping set node; but if we're in a
				 * nested grouping set, then we need to concat the flattened
				 * result into the outer list if it's simply nested.
				 */

				if (toplevel || (gset->kind != GROUPING_SET_SETS))
				{
					return (Node *) makeGroupingSet(gset->kind, result_set, gset->location);
				}
				else
					return (Node *) result_set;
			}
		case T_List:
			{
				List	   *result = NIL;
				ListCell   *l;

				foreach(l, (List *) expr)
				{
					Node	   *n = flatten_grouping_sets(lfirst(l), toplevel, hasGroupingSets);

					if (n != (Node *) NIL)
					{
						if (IsA(n, List))
							result = list_concat(result, (List *) n);
						else
							result = lappend(result, n);
					}
				}

				return (Node *) result;
			}
		default:
			break;
	}

	return expr;
}

/*
 * Transform a single expression within a GROUP BY clause or grouping set.
 *
 * The expression is added to the targetlist if not already present, and to the
 * flatresult list (which will become the groupClause) if not already present
 * there.  The sortClause is consulted for operator and sort order hints.
 *
 * Returns the ressortgroupref of the expression.
 *
 * flatresult	reference to flat list of SortGroupClause nodes
 * seen_local	bitmapset of sortgrouprefs already seen at the local level
 * pstate		ParseState
 * gexpr		node to transform
 * targetlist	reference to TargetEntry list
 * sortClause	ORDER BY clause (SortGroupClause nodes)
 * exprKind		expression kind
 * useSQL99		SQL99 rather than SQL92 syntax
 * toplevel		false if within any grouping set
 */
static Index
transformGroupClauseExpr(List **flatresult, Bitmapset *seen_local,
						 ParseState *pstate, Node *gexpr,
						 List **targetlist, List *sortClause,
						 ParseExprKind exprKind, bool useSQL99, bool toplevel)
{
	TargetEntry *tle;
	bool		found = false;

	if (useSQL99)
		tle = findTargetlistEntrySQL99(pstate, gexpr,
									   targetlist, exprKind);
	else
		tle = findTargetlistEntrySQL92(pstate, gexpr,
									   targetlist, exprKind);

	if (tle->ressortgroupref > 0)
	{
		ListCell   *sl;

		/*
		 * Eliminate duplicates (GROUP BY x, x) but only at local level.
		 * (Duplicates in grouping sets can affect the number of returned
		 * rows, so can't be dropped indiscriminately.)
		 *
		 * Since we don't care about anything except the sortgroupref, we can
		 * use a bitmapset rather than scanning lists.
		 */
		if (bms_is_member(tle->ressortgroupref, seen_local))
			return 0;

		/*
		 * If we're already in the flat clause list, we don't need to consider
		 * adding ourselves again.
		 */
		found = targetIsInSortList(tle, InvalidOid, *flatresult);
		if (found)
			return tle->ressortgroupref;

		/*
		 * If the GROUP BY tlist entry also appears in ORDER BY, copy operator
		 * info from the (first) matching ORDER BY item.  This means that if
		 * you write something like "GROUP BY foo ORDER BY foo USING <<<", the
		 * GROUP BY operation silently takes on the equality semantics implied
		 * by the ORDER BY.  There are two reasons to do this: it improves the
		 * odds that we can implement both GROUP BY and ORDER BY with a single
		 * sort step, and it allows the user to choose the equality semantics
		 * used by GROUP BY, should she be working with a datatype that has
		 * more than one equality operator.
		 *
		 * If we're in a grouping set, though, we force our requested ordering
		 * to be NULLS LAST, because if we have any hope of using a sorted agg
		 * for the job, we're going to be tacking on generated NULL values
		 * after the corresponding groups. If the user demands nulls first,
		 * another sort step is going to be inevitable, but that's the
		 * planner's problem.
		 */

		foreach(sl, sortClause)
		{
			SortGroupClause *sc = (SortGroupClause *) lfirst(sl);

			if (sc->tleSortGroupRef == tle->ressortgroupref)
			{
				SortGroupClause *grpc = copyObject(sc);

				if (!toplevel)
					grpc->nulls_first = false;
				*flatresult = lappend(*flatresult, grpc);
				found = true;
				break;
			}
		}
	}

	/*
	 * If no match in ORDER BY, just add it to the result using default
	 * sort/group semantics.
	 */
	if (!found)
		*flatresult = addTargetToGroupList(pstate, tle,
										   *flatresult, *targetlist,
										   exprLocation(gexpr));

	/*
	 * _something_ must have assigned us a sortgroupref by now...
	 */

	return tle->ressortgroupref;
}

/*
 * Transform a list of expressions within a GROUP BY clause or grouping set.
 *
 * The list of expressions belongs to a single clause within which duplicates
 * can be safely eliminated.
 *
 * Returns an integer list of ressortgroupref values.
 *
 * flatresult	reference to flat list of SortGroupClause nodes
 * pstate		ParseState
 * list			nodes to transform
 * targetlist	reference to TargetEntry list
 * sortClause	ORDER BY clause (SortGroupClause nodes)
 * exprKind		expression kind
 * useSQL99		SQL99 rather than SQL92 syntax
 * toplevel		false if within any grouping set
 */
static List *
transformGroupClauseList(List **flatresult,
						 ParseState *pstate, List *list,
						 List **targetlist, List *sortClause,
						 ParseExprKind exprKind, bool useSQL99, bool toplevel)
{
	Bitmapset  *seen_local = NULL;
	List	   *result = NIL;
	ListCell   *gl;

	foreach(gl, list)
	{
		Node	   *gexpr = (Node *) lfirst(gl);

		Index		ref = transformGroupClauseExpr(flatresult,
												   seen_local,
												   pstate,
												   gexpr,
												   targetlist,
												   sortClause,
												   exprKind,
												   useSQL99,
												   toplevel);

		if (ref > 0)
		{
			seen_local = bms_add_member(seen_local, ref);
			result = lappend_int(result, ref);
		}
	}

	return result;
}

/*
 * Transform a grouping set and (recursively) its content.
 *
 * The grouping set might be a GROUPING SETS node with other grouping sets
 * inside it, but SETS within SETS have already been flattened out before
 * reaching here.
 *
 * Returns the transformed node, which now contains SIMPLE nodes with lists
 * of ressortgrouprefs rather than expressions.
 *
 * flatresult	reference to flat list of SortGroupClause nodes
 * pstate		ParseState
 * gset			grouping set to transform
 * targetlist	reference to TargetEntry list
 * sortClause	ORDER BY clause (SortGroupClause nodes)
 * exprKind		expression kind
 * useSQL99		SQL99 rather than SQL92 syntax
 * toplevel		false if within any grouping set
 */
static Node *
transformGroupingSet(List **flatresult,
					 ParseState *pstate, GroupingSet *gset,
					 List **targetlist, List *sortClause,
					 ParseExprKind exprKind, bool useSQL99, bool toplevel)
{
	ListCell   *gl;
	List	   *content = NIL;

	Assert(toplevel || gset->kind != GROUPING_SET_SETS);

	foreach(gl, gset->content)
	{
		Node	   *n = lfirst(gl);

		if (IsA(n, List))
		{
			List	   *l = transformGroupClauseList(flatresult,
													 pstate, (List *) n,
													 targetlist, sortClause,
													 exprKind, useSQL99, false);

			content = lappend(content, makeGroupingSet(GROUPING_SET_SIMPLE,
													   l,
													   exprLocation(n)));
		}
		else if (IsA(n, GroupingSet))
		{
			GroupingSet *gset2 = (GroupingSet *) lfirst(gl);

			content = lappend(content, transformGroupingSet(flatresult,
															pstate, gset2,
															targetlist, sortClause,
															exprKind, useSQL99, false));
		}
		else
		{
			Index		ref = transformGroupClauseExpr(flatresult,
													   NULL,
													   pstate,
													   n,
													   targetlist,
													   sortClause,
													   exprKind,
													   useSQL99,
													   false);

			content = lappend(content, makeGroupingSet(GROUPING_SET_SIMPLE,
													   list_make1_int(ref),
													   exprLocation(n)));
		}
	}

	/* Arbitrarily cap the size of CUBE, which has exponential growth */
	if (gset->kind == GROUPING_SET_CUBE)
	{
		if (list_length(content) > 12)
			ereport(ERROR,
					(errcode(ERRCODE_TOO_MANY_COLUMNS),
					 errmsg("CUBE is limited to 12 elements"),
					 parser_errposition(pstate, gset->location)));
	}

	return (Node *) makeGroupingSet(gset->kind, content, gset->location);
}


/*
 * transformGroupClause -
 *	  transform a GROUP BY clause
 *
 * GROUP BY items will be added to the targetlist (as resjunk columns)
 * if not already present, so the targetlist must be passed by reference.
 *
 * This is also used for window PARTITION BY clauses (which act almost the
 * same, but are always interpreted per SQL99 rules).
 *
 * Grouping sets make this a lot more complex than it was. Our goal here is
 * twofold: we make a flat list of SortGroupClause nodes referencing each
 * distinct expression used for grouping, with those expressions added to the
 * targetlist if needed. At the same time, we build the groupingSets tree,
 * which stores only ressortgrouprefs as integer lists inside GroupingSet nodes
 * (possibly nested, but limited in depth: a GROUPING_SET_SETS node can contain
 * nested SIMPLE, CUBE or ROLLUP nodes, but not more sets - we flatten that
 * out; while CUBE and ROLLUP can contain only SIMPLE nodes).
 *
 * We skip much of the hard work if there are no grouping sets.
 *
 * One subtlety is that the groupClause list can end up empty while the
 * groupingSets list is not; this happens if there are only empty grouping
 * sets, or an explicit GROUP BY (). This has the same effect as specifying
 * aggregates or a HAVING clause with no GROUP BY; the output is one row per
 * grouping set even if the input is empty.
 *
 * Returns the transformed (flat) groupClause.
 *
 * pstate		ParseState
 * grouplist	clause to transform
 * groupingSets reference to list to contain the grouping set tree
 * targetlist	reference to TargetEntry list
 * sortClause	ORDER BY clause (SortGroupClause nodes)
 * exprKind		expression kind
 * useSQL99		SQL99 rather than SQL92 syntax
 */
List *
transformGroupClause(ParseState *pstate, List *grouplist, List **groupingSets,
					 List **targetlist, List *sortClause,
					 ParseExprKind exprKind, bool useSQL99)
{
	List	   *result = NIL;
	List	   *flat_grouplist;
	List	   *gsets = NIL;
	ListCell   *gl;
	bool		hasGroupingSets = false;
	Bitmapset  *seen_local = NULL;

	/*
	 * Recursively flatten implicit RowExprs. (Technically this is only needed
	 * for GROUP BY, per the syntax rules for grouping sets, but we do it
	 * anyway.)
	 */
	flat_grouplist = (List *) flatten_grouping_sets((Node *) grouplist,
													true,
													&hasGroupingSets);

	/*
	 * If the list is now empty, but hasGroupingSets is true, it's because we
	 * elided redundant empty grouping sets. Restore a single empty grouping
	 * set to leave a canonical form: GROUP BY ()
	 */

	if (flat_grouplist == NIL && hasGroupingSets)
	{
		flat_grouplist = list_make1(makeGroupingSet(GROUPING_SET_EMPTY,
													NIL,
													exprLocation((Node *) grouplist)));
	}

	foreach(gl, flat_grouplist)
	{
		Node	   *gexpr = (Node *) lfirst(gl);

		if (IsA(gexpr, GroupingSet))
		{
			GroupingSet *gset = (GroupingSet *) gexpr;

			switch (gset->kind)
			{
				case GROUPING_SET_EMPTY:
					gsets = lappend(gsets, gset);
					break;
				case GROUPING_SET_SIMPLE:
					/* can't happen */
					Assert(false);
					break;
				case GROUPING_SET_SETS:
				case GROUPING_SET_CUBE:
				case GROUPING_SET_ROLLUP:
					gsets = lappend(gsets,
									transformGroupingSet(&result,
														 pstate, gset,
														 targetlist, sortClause,
														 exprKind, useSQL99, true));
					break;
			}
		}
		else
		{
			Index		ref = transformGroupClauseExpr(&result, seen_local,
													   pstate, gexpr,
													   targetlist, sortClause,
													   exprKind, useSQL99, true);

			if (ref > 0)
			{
				seen_local = bms_add_member(seen_local, ref);
				if (hasGroupingSets)
					gsets = lappend(gsets,
									makeGroupingSet(GROUPING_SET_SIMPLE,
													list_make1_int(ref),
													exprLocation(gexpr)));
			}
		}
	}

	/* parser should prevent this */
	Assert(gsets == NIL || groupingSets != NULL);

	if (groupingSets)
		*groupingSets = gsets;

	return result;
}

/*
 * transformSortClause -
 *	  transform an ORDER BY clause
 *
 * ORDER BY items will be added to the targetlist (as resjunk columns)
 * if not already present, so the targetlist must be passed by reference.
 *
 * This is also used for window and aggregate ORDER BY clauses (which act
 * almost the same, but are always interpreted per SQL99 rules).
 */
List *
transformSortClause(ParseState *pstate,
					List *orderlist,
					List **targetlist,
					ParseExprKind exprKind,
					bool useSQL99)
{
	List	   *sortlist = NIL;
	ListCell   *olitem;

	foreach(olitem, orderlist)
	{
		SortBy	   *sortby = (SortBy *) lfirst(olitem);
		TargetEntry *tle;

		if (useSQL99)
			tle = findTargetlistEntrySQL99(pstate, sortby->node,
										   targetlist, exprKind);
		else
			tle = findTargetlistEntrySQL92(pstate, sortby->node,
										   targetlist, exprKind);

		sortlist = addTargetToSortList(pstate, tle,
									   sortlist, *targetlist, sortby);
	}

	return sortlist;
}

/*
 * transformWindowDefinitions -
 *		transform window definitions (WindowDef to WindowClause)
 *
 * There's a fair bit to do here: column references in the PARTITION and
 * ORDER clauses must be valid; ORDER clause must present if the function
 * requires; the frame clause must be checked to ensure that the function
 * supports framing, that the framed column is of the right type, that the
 * offset is sane, that the start and end of the frame are sane.
 * Then we translate it to use the proper parse nodes for the respective
 * part of the clause.
 */
List *
transformWindowDefinitions(ParseState *pstate,
						   List *windowdefs,
						   List **targetlist)
{
	List	   *result = NIL;
	Index		winref = 0;
	ListCell   *lc;

	/*
	 * We have two lists of window specs: one in the ParseState -- put there
	 * when we find the OVER(...) clause in the targetlist and the other
	 * is windowClause, a list of named window clauses. So, we concatenate
	 * them together.
	 *
	 * Note that we're careful place those found in the target list at
	 * the end because the spec might refer to a named clause and we'll
	 * after to know about those first.
	 */
	foreach(lc, windowdefs)
	{
		WindowDef  *windef = (WindowDef *) lfirst(lc);
		WindowClause *refwc = NULL;
		List	   *partitionClause;
		List	   *orderClause;
		Oid			rangeopfamily = InvalidOid;
		Oid			rangeopcintype = InvalidOid;
		WindowClause *wc;

		winref++;

		/*
		 * Check for duplicate window names.
		 */
		if (windef->name &&
			findWindowClause(result, windef->name) != NULL)
			ereport(ERROR,
					(errcode(ERRCODE_WINDOWING_ERROR),
					 errmsg("window \"%s\" is already defined", windef->name),
					 parser_errposition(pstate, windef->location)));

		/*
		 * If it references a previous window, look that up.
		 */
		if (windef->refname)
		{
			refwc = findWindowClause(result, windef->refname);
			if (refwc == NULL)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("window \"%s\" does not exist",
								windef->refname),
						 parser_errposition(pstate, windef->location)));
		}

		/*
		 * Transform PARTITION and ORDER specs, if any.  These are treated
		 * almost exactly like top-level GROUP BY and ORDER BY clauses,
		 * including the special handling of nondefault operator semantics.
		 */
		orderClause = transformSortClause(pstate,
										  windef->orderClause,
										  targetlist,
										  EXPR_KIND_WINDOW_ORDER,
										  true /* force SQL99 rules */ );
		partitionClause = transformGroupClause(pstate,
											   windef->partitionClause,
											   NULL,
											   targetlist,
											   orderClause,
											   EXPR_KIND_WINDOW_PARTITION,
											   true /* force SQL99 rules */ );

		/*
		 * And prepare the new WindowClause.
		 */
		wc = makeNode(WindowClause);
		wc->name = windef->name;
		wc->refname = windef->refname;

		/*
		 * Per spec, a windowdef that references a previous one copies the
		 * previous partition clause (and mustn't specify its own).  It can
		 * specify its own ordering clause, but only if the previous one had
		 * none.  It always specifies its own frame clause, and the previous
		 * one must not have a frame clause.  Yeah, it's bizarre that each of
		 * these cases works differently, but SQL:2008 says so; see 7.11
		 * <window clause> syntax rule 10 and general rule 1.  The frame
		 * clause rule is especially bizarre because it makes "OVER foo"
		 * different from "OVER (foo)", and requires the latter to throw an
		 * error if foo has a nondefault frame clause.  Well, ours not to
		 * reason why, but we do go out of our way to throw a useful error
		 * message for such cases.
		 */
		if (refwc)
		{
			if (partitionClause)
				ereport(ERROR,
						(errcode(ERRCODE_WINDOWING_ERROR),
						 errmsg("cannot override PARTITION BY clause of window \"%s\"",
								windef->refname),
						 parser_errposition(pstate, windef->location)));
			wc->partitionClause = copyObject(refwc->partitionClause);
		}
		else
			wc->partitionClause = partitionClause;
		if (refwc)
		{
			if (orderClause && refwc->orderClause)
				ereport(ERROR,
						(errcode(ERRCODE_WINDOWING_ERROR),
						 errmsg("cannot override ORDER BY clause of window \"%s\"",
								windef->refname),
						 parser_errposition(pstate, windef->location)));
			if (orderClause)
			{
				wc->orderClause = orderClause;
				wc->copiedOrder = false;
			}
			else
			{
				wc->orderClause = copyObject(refwc->orderClause);
				wc->copiedOrder = true;
			}
		}
		else
		{
			wc->orderClause = orderClause;
			wc->copiedOrder = false;
		}
		if (refwc && refwc->frameOptions != FRAMEOPTION_DEFAULTS)
		{
			/*
			 * Use this message if this is a WINDOW clause, or if it's an OVER
			 * clause that includes ORDER BY or framing clauses.  (We already
			 * rejected PARTITION BY above, so no need to check that.)
			 */
			if (windef->name ||
				orderClause || windef->frameOptions != FRAMEOPTION_DEFAULTS)
				ereport(ERROR,
						(errcode(ERRCODE_WINDOWING_ERROR),
						 errmsg("cannot copy window \"%s\" because it has a frame clause",
								windef->refname),
						 parser_errposition(pstate, windef->location)));
			/* Else this clause is just OVER (foo), so say this: */
			ereport(ERROR,
					(errcode(ERRCODE_WINDOWING_ERROR),
			errmsg("cannot copy window \"%s\" because it has a frame clause",
				   windef->refname),
					 errhint("Omit the parentheses in this OVER clause."),
					 parser_errposition(pstate, windef->location)));
		}

		/*
		 * Finally, process the framing clause. parseProcessWindFunc() will
		 * have picked up window functions that do not support framing.
		 *
		 * What we do need to do is the following:
		 * - If BETWEEN has been specified, the trailing bound is not
		 *   UNBOUNDED FOLLOWING; the leading bound is not UNBOUNDED
		 *   PRECEDING; if the first bound specifies CURRENT ROW, the
		 *   second bound shall not specify a PRECEDING bound; if the
		 *   first bound specifies a FOLLOWING bound, the second bound
		 *   shall not specify a PRECEDING or CURRENT ROW bound.
		 *
		 * - If the user did not specify BETWEEN, the bound is assumed to be
		 *   a trailing bound and the leading bound is set to CURRENT ROW.
		 *   We're careful not to set is_between here because the user did not
		 *   specify it.
		 *
		 * - If RANGE is specified: the ORDER BY clause of the window spec
		 *   may specify only one column; the type of that column must support
		 *   +/- <integer> operations and must be merge-joinable.
		 */

		wc->frameOptions = windef->frameOptions;

		/*
		 * RANGE offset PRECEDING/FOLLOWING requires exactly one ORDER BY
		 * column; check that and get its sort opfamily info.
		 */
		if ((wc->frameOptions & FRAMEOPTION_RANGE) &&
			(wc->frameOptions & (FRAMEOPTION_START_OFFSET |
								 FRAMEOPTION_END_OFFSET)))
		{
			SortGroupClause *sortcl;
			Node	   *sortkey;
			int16		rangestrategy;

			if (list_length(wc->orderClause) != 1)
				ereport(ERROR,
						(errcode(ERRCODE_WINDOWING_ERROR),
						 errmsg("RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column"),
						 parser_errposition(pstate, windef->location)));
			sortcl = linitial_node(SortGroupClause, wc->orderClause);
			sortkey = get_sortgroupclause_expr(sortcl, *targetlist);
			/* Find the sort operator in pg_amop */
			if (!get_ordering_op_properties(sortcl->sortop,
											&rangeopfamily,
											&rangeopcintype,
											&rangestrategy))
				elog(ERROR, "operator %u is not a valid ordering operator",
					 sortcl->sortop);
			/* Record properties of sort ordering */
			wc->inRangeColl = exprCollation(sortkey);
			wc->inRangeAsc = (rangestrategy == BTLessStrategyNumber);
			wc->inRangeNullsFirst = sortcl->nulls_first;
		}

		/* Per spec, GROUPS mode requires an ORDER BY clause */
		if (wc->frameOptions & FRAMEOPTION_GROUPS)
		{
			if (wc->orderClause == NIL)
				ereport(ERROR,
						(errcode(ERRCODE_WINDOWING_ERROR),
						 errmsg("GROUPS mode requires an ORDER BY clause"),
						 parser_errposition(pstate, windef->location)));
		}

		/* Process frame offset expressions */
		wc->startOffset = transformFrameOffset(pstate, wc->frameOptions,
											   rangeopfamily, rangeopcintype,
											   &wc->startInRangeFunc,
											   windef->startOffset);
		wc->endOffset = transformFrameOffset(pstate, wc->frameOptions,
											 rangeopfamily, rangeopcintype,
											 &wc->endInRangeFunc,
											 windef->endOffset);
		wc->runCondition = NIL;
		wc->winref = winref;

		/* finally, check function restriction with this spec. */
		winref_checkspec(pstate, *targetlist, winref,
						 PointerIsValid(wc->orderClause),
						 wc->frameOptions != FRAMEOPTION_DEFAULTS);

		result = lappend(result, wc);
	}

	/* If there are no window functions in the targetlist,
	 * forget the window clause.
	 */
	if (!pstate->p_hasWindowFuncs)
		pstate->p_windowdefs = NIL;

	return result;
}

/*
 * transformDistinctClause -
 *	  transform a DISTINCT clause
 *
 * Since we may need to add items to the query's targetlist, that list
 * is passed by reference.
 *
 * As with GROUP BY, we absorb the sorting semantics of ORDER BY as much as
 * possible into the distinctClause.  This avoids a possible need to re-sort,
 * and allows the user to choose the equality semantics used by DISTINCT,
 * should she be working with a datatype that has more than one equality
 * operator.
 *
 * is_agg is true if we are transforming an aggregate(DISTINCT ...)
 * function call.  This does not affect any behavior, only the phrasing
 * of error messages.
 */
List *
transformDistinctClause(ParseState *pstate,
						List **targetlist, List *sortClause, bool is_agg)
{
	List	   *result = NIL;
	ListCell   *slitem;
	ListCell   *tlitem;

	/*
	 * The distinctClause should consist of all ORDER BY items followed by all
	 * other non-resjunk targetlist items.  There must not be any resjunk
	 * ORDER BY items --- that would imply that we are sorting by a value that
	 * isn't necessarily unique within a DISTINCT group, so the results
	 * wouldn't be well-defined.  This construction ensures we follow the rule
	 * that sortClause and distinctClause match; in fact the sortClause will
	 * always be a prefix of distinctClause.
	 *
	 * Note a corner case: the same TLE could be in the ORDER BY list multiple
	 * times with different sortops.  We have to include it in the
	 * distinctClause the same way to preserve the prefix property. The net
	 * effect will be that the TLE value will be made unique according to both
	 * sortops.
	 */
	foreach(slitem, sortClause)
	{
		SortGroupClause *scl = (SortGroupClause *) lfirst(slitem);
		TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist);

		if (tle->resjunk)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
					 is_agg ?
					 errmsg("in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list") :
					 errmsg("for SELECT DISTINCT, ORDER BY expressions must appear in select list"),
					 parser_errposition(pstate,
										exprLocation((Node *) tle->expr))));
		result = lappend(result, copyObject(scl));
	}

	/*
	 * Now add any remaining non-resjunk tlist items, using default sort/group
	 * semantics for their data types.
	 */
	foreach(tlitem, *targetlist)
	{
		TargetEntry *tle = (TargetEntry *) lfirst(tlitem);

		if (tle->resjunk)
			continue;			/* ignore junk */
		result = addTargetToGroupList(pstate, tle,
									  result, *targetlist,
									  exprLocation((Node *) tle->expr));
	}

	/*
	 * Complain if we found nothing to make DISTINCT.  Returning an empty list
	 * would cause the parsed Query to look like it didn't have DISTINCT, with
	 * results that would probably surprise the user.  Note: this case is
	 * presently impossible for aggregates because of grammar restrictions,
	 * but we check anyway.
	 */
	if (result == NIL)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 is_agg ?
				 errmsg("an aggregate with DISTINCT must have at least one argument") :
				 errmsg("SELECT DISTINCT must have at least one column")));

	return result;
}

/*
 * transformDistinctOnClause -
 *	  transform a DISTINCT ON clause
 *
 * Since we may need to add items to the query's targetlist, that list
 * is passed by reference.
 *
 * As with GROUP BY, we absorb the sorting semantics of ORDER BY as much as
 * possible into the distinctClause.  This avoids a possible need to re-sort,
 * and allows the user to choose the equality semantics used by DISTINCT,
 * should she be working with a datatype that has more than one equality
 * operator.
 */
List *
transformDistinctOnClause(ParseState *pstate, List *distinctlist,
						  List **targetlist, List *sortClause)
{
	List	   *result = NIL;
	List	   *sortgrouprefs = NIL;
	bool		skipped_sortitem;
	ListCell   *lc;
	ListCell   *lc2;

	/*
	 * Add all the DISTINCT ON expressions to the tlist (if not already
	 * present, they are added as resjunk items).  Assign sortgroupref numbers
	 * to them, and make a list of these numbers.  (NB: we rely below on the
	 * sortgrouprefs list being one-for-one with the original distinctlist.
	 * Also notice that we could have duplicate DISTINCT ON expressions and
	 * hence duplicate entries in sortgrouprefs.)
	 */
	foreach(lc, distinctlist)
	{
		Node	   *dexpr = (Node *) lfirst(lc);
		int			sortgroupref;
		TargetEntry *tle;

		tle = findTargetlistEntrySQL92(pstate, dexpr, targetlist,
									   EXPR_KIND_DISTINCT_ON);
		sortgroupref = assignSortGroupRef(tle, *targetlist);
		sortgrouprefs = lappend_int(sortgrouprefs, sortgroupref);
	}

	/*
	 * If the user writes both DISTINCT ON and ORDER BY, adopt the sorting
	 * semantics from ORDER BY items that match DISTINCT ON items, and also
	 * adopt their column sort order.  We insist that the distinctClause and
	 * sortClause match, so throw error if we find the need to add any more
	 * distinctClause items after we've skipped an ORDER BY item that wasn't
	 * in DISTINCT ON.
	 */
	skipped_sortitem = false;
	foreach(lc, sortClause)
	{
		SortGroupClause *scl = (SortGroupClause *) lfirst(lc);

		if (list_member_int(sortgrouprefs, scl->tleSortGroupRef))
		{
			if (skipped_sortitem)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
						 errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
						 parser_errposition(pstate,
											get_matching_location(scl->tleSortGroupRef,
																  sortgrouprefs,
																  distinctlist))));
			else
				result = lappend(result, copyObject(scl));
		}
		else
			skipped_sortitem = true;
	}

	/*
	 * Now add any remaining DISTINCT ON items, using default sort/group
	 * semantics for their data types.  (Note: this is pretty questionable; if
	 * the ORDER BY list doesn't include all the DISTINCT ON items and more
	 * besides, you certainly aren't using DISTINCT ON in the intended way,
	 * and you probably aren't going to get consistent results.  It might be
	 * better to throw an error or warning here.  But historically we've
	 * allowed it, so keep doing so.)
	 */
	forboth(lc, distinctlist, lc2, sortgrouprefs)
	{
		Node	   *dexpr = (Node *) lfirst(lc);
		int			sortgroupref = lfirst_int(lc2);
		TargetEntry *tle = get_sortgroupref_tle(sortgroupref, *targetlist);

		if (targetIsInSortList(tle, InvalidOid, result))
			continue;			/* already in list (with some semantics) */
		if (skipped_sortitem)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
					 errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions"),
					 parser_errposition(pstate, exprLocation(dexpr))));
		result = addTargetToGroupList(pstate, tle,
									  result, *targetlist,
									  exprLocation(dexpr));
	}

	/*
	 * An empty result list is impossible here because of grammar
	 * restrictions.
	 */
	Assert(result != NIL);

	return result;
}

/*
 * transformScatterClause -
 *	  transform a SCATTER BY clause
 *
 * SCATTER BY items will be added to the targetlist (as resjunk columns)
 * if not already present, so the targetlist must be passed by reference.
 *
 */
List *
transformScatterClause(ParseState *pstate,
					   List *scatterlist,
					   List **targetlist)
{
	List	   *outlist = NIL;
	ListCell   *olitem;

	/* Special case handling for SCATTER RANDOMLY */
	if (list_length(scatterlist) == 1 && linitial(scatterlist) == NULL)
		return list_make1(NULL);
	
	/* preprocess the scatter clause, lookup TLEs */
	foreach(olitem, scatterlist)
	{
		Node			*node = lfirst(olitem);
		TargetEntry		*tle;

		tle = findTargetlistEntrySQL99(pstate, node, targetlist,
									   EXPR_KIND_SCATTER_BY);

		/* coerce unknown to text */
		if (exprType((Node *) tle->expr) == UNKNOWNOID)
		{
			tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
											 UNKNOWNOID, TEXTOID, -1,
											 COERCION_IMPLICIT,
											 COERCE_IMPLICIT_CAST,
											 -1);
		}

		outlist = lappend(outlist, tle->expr);
	}
	return outlist;
}

/*
 * get_matching_location
 *		Get the exprLocation of the exprs member corresponding to the
 *		(first) member of sortgrouprefs that equals sortgroupref.
 *
 * This is used so that we can point at a troublesome DISTINCT ON entry.
 * (Note that we need to use the original untransformed DISTINCT ON list
 * item, as whatever TLE it corresponds to will very possibly have a
 * parse location pointing to some matching entry in the SELECT list
 * or ORDER BY list.)
 */
static int
get_matching_location(int sortgroupref, List *sortgrouprefs, List *exprs)
{
	ListCell   *lcs;
	ListCell   *lce;

	forboth(lcs, sortgrouprefs, lce, exprs)
	{
		if (lfirst_int(lcs) == sortgroupref)
			return exprLocation((Node *) lfirst(lce));
	}
	/* if no match, caller blew it */
	elog(ERROR, "get_matching_location: no matching sortgroupref");
	return -1;					/* keep compiler quiet */
}

/*
 * resolve_unique_index_expr
 *		Infer a unique index from a list of indexElems, for ON
 *		CONFLICT clause
 *
 * Perform parse analysis of expressions and columns appearing within ON
 * CONFLICT clause.  During planning, the returned list of expressions is used
 * to infer which unique index to use.
 */
static List *
resolve_unique_index_expr(ParseState *pstate, InferClause *infer,
						  Relation heapRel)
{
	List	   *result = NIL;
	ListCell   *l;

	foreach(l, infer->indexElems)
	{
		IndexElem  *ielem = (IndexElem *) lfirst(l);
		InferenceElem *pInfer = makeNode(InferenceElem);
		Node	   *parse;

		/*
		 * Raw grammar re-uses CREATE INDEX infrastructure for unique index
		 * inference clause, and so will accept opclasses by name and so on.
		 *
		 * Make no attempt to match ASC or DESC ordering or NULLS FIRST/NULLS
		 * LAST ordering, since those are not significant for inference
		 * purposes (any unique index matching the inference specification in
		 * other regards is accepted indifferently).  Actively reject this as
		 * wrong-headed.
		 */
		if (ielem->ordering != SORTBY_DEFAULT)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
					 errmsg("ASC/DESC is not allowed in ON CONFLICT clause"),
					 parser_errposition(pstate,
										exprLocation((Node *) infer))));
		if (ielem->nulls_ordering != SORTBY_NULLS_DEFAULT)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
					 errmsg("NULLS FIRST/LAST is not allowed in ON CONFLICT clause"),
					 parser_errposition(pstate,
										exprLocation((Node *) infer))));

		if (!ielem->expr)
		{
			/* Simple index attribute */
			ColumnRef  *n;

			/*
			 * Grammar won't have built raw expression for us in event of
			 * plain column reference.  Create one directly, and perform
			 * expression transformation.  Planner expects this, and performs
			 * its own normalization for the purposes of matching against
			 * pg_index.
			 */
			n = makeNode(ColumnRef);
			n->fields = list_make1(makeString(ielem->name));
			/* Location is approximately that of inference specification */
			n->location = infer->location;
			parse = (Node *) n;
		}
		else
		{
			/* Do parse transformation of the raw expression */
			parse = (Node *) ielem->expr;
		}

		/*
		 * transformExpr() will reject subqueries, aggregates, window
		 * functions, and SRFs, based on being passed
		 * EXPR_KIND_INDEX_EXPRESSION.  So we needn't worry about those
		 * further ... not that they would match any available index
		 * expression anyway.
		 */
		pInfer->expr = transformExpr(pstate, parse, EXPR_KIND_INDEX_EXPRESSION);

		/* Perform lookup of collation and operator class as required */
		if (!ielem->collation)
			pInfer->infercollid = InvalidOid;
		else
			pInfer->infercollid = LookupCollation(pstate, ielem->collation,
												  exprLocation(pInfer->expr));

		if (!ielem->opclass)
			pInfer->inferopclass = InvalidOid;
		else
			pInfer->inferopclass = get_opclass_oid(BTREE_AM_OID,
												   ielem->opclass, false);

		result = lappend(result, pInfer);
	}

	return result;
}

/*
 * transformOnConflictArbiter -
 *		transform arbiter expressions in an ON CONFLICT clause.
 *
 * Transformed expressions used to infer one unique index relation to serve as
 * an ON CONFLICT arbiter.  Partial unique indexes may be inferred using WHERE
 * clause from inference specification clause.
 */
void
transformOnConflictArbiter(ParseState *pstate,
						   OnConflictClause *onConflictClause,
						   List **arbiterExpr, Node **arbiterWhere,
						   Oid *constraint)
{
	InferClause *infer = onConflictClause->infer;

	*arbiterExpr = NIL;
	*arbiterWhere = NULL;
	*constraint = InvalidOid;

	if (onConflictClause->action == ONCONFLICT_UPDATE && !infer)
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("ON CONFLICT DO UPDATE requires inference specification or constraint name"),
				 errhint("For example, ON CONFLICT (column_name)."),
				 parser_errposition(pstate,
									exprLocation((Node *) onConflictClause))));

	/*
	 * To simplify certain aspects of its design, speculative insertion into
	 * system catalogs is disallowed
	 */
	if (IsCatalogRelation(pstate->p_target_relation))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("ON CONFLICT is not supported with system catalog tables"),
				 parser_errposition(pstate,
									exprLocation((Node *) onConflictClause))));

	/* Same applies to table used by logical decoding as catalog table */
	if (RelationIsUsedAsCatalogTable(pstate->p_target_relation))
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("ON CONFLICT is not supported on table \"%s\" used as a catalog table",
						RelationGetRelationName(pstate->p_target_relation)),
				 parser_errposition(pstate,
									exprLocation((Node *) onConflictClause))));

	/* ON CONFLICT DO NOTHING does not require an inference clause */
	if (infer)
	{
		if (infer->indexElems)
			*arbiterExpr = resolve_unique_index_expr(pstate, infer,
													 pstate->p_target_relation);

		/*
		 * Handling inference WHERE clause (for partial unique index
		 * inference)
		 */
		if (infer->whereClause)
			*arbiterWhere = transformExpr(pstate, infer->whereClause,
										  EXPR_KIND_INDEX_PREDICATE);

		/*
		 * If the arbiter is specified by constraint name, get the constraint
		 * OID and mark the constrained columns as requiring SELECT privilege,
		 * in the same way as would have happened if the arbiter had been
		 * specified by explicit reference to the constraint's index columns.
		 */
		if (infer->conname)
		{
			Oid			relid = RelationGetRelid(pstate->p_target_relation);
			RTEPermissionInfo *perminfo = pstate->p_target_nsitem->p_perminfo;
			Bitmapset  *conattnos;

			conattnos = get_relation_constraint_attnos(relid, infer->conname,
													   false, constraint);

			/* Make sure the rel as a whole is marked for SELECT access */
			perminfo->requiredPerms |= ACL_SELECT;
			/* Mark the constrained columns as requiring SELECT access */
			perminfo->selectedCols = bms_add_members(perminfo->selectedCols,
													 conattnos);
		}
	}

	/*
	 * It's convenient to form a list of expressions based on the
	 * representation used by CREATE INDEX, since the same restrictions are
	 * appropriate (e.g. on subqueries).  However, from here on, a dedicated
	 * primnode representation is used for inference elements, and so
	 * assign_query_collations() can be trusted to do the right thing with the
	 * post parse analysis query tree inference clause representation.
	 */
}

/*
 * addTargetToSortList
 *		If the given targetlist entry isn't already in the SortGroupClause
 *		list, add it to the end of the list, using the given sort ordering
 *		info.
 *
 * Returns the updated SortGroupClause list.
 */
List *
addTargetToSortList(ParseState *pstate, TargetEntry *tle,
					List *sortlist, List *targetlist, SortBy *sortby)
{
	Oid			restype = exprType((Node *) tle->expr);
	Oid			sortop;
	Oid			eqop;
	bool		hashable;
	bool		reverse;
	int			location;
	ParseCallbackState pcbstate;

	/* if tlist item is an UNKNOWN literal, change it to TEXT */
	if (restype == UNKNOWNOID)
	{
		tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
										 restype, TEXTOID, -1,
										 COERCION_IMPLICIT,
										 COERCE_IMPLICIT_CAST,
										 exprLocation((Node *) tle->expr));
		restype = TEXTOID;
	}

	/*
	 * Rather than clutter the API of get_sort_group_operators and the other
	 * functions we're about to use, make use of error context callback to
	 * mark any error reports with a parse position.  We point to the operator
	 * location if present, else to the expression being sorted.  (NB: use the
	 * original untransformed expression here; the TLE entry might well point
	 * at a duplicate expression in the regular SELECT list.)
	 */
	location = sortby->location;
	if (location < 0)
		location = exprLocation(sortby->node);
	setup_parser_errposition_callback(&pcbstate, pstate, location);

	/* determine the sortop, eqop, and directionality */
	switch (sortby->sortby_dir)
	{
		case SORTBY_DEFAULT:
		case SORTBY_ASC:
			get_sort_group_operators(restype,
									 true, true, false,
									 &sortop, &eqop, NULL,
									 &hashable);
			reverse = false;
			break;
		case SORTBY_DESC:
			get_sort_group_operators(restype,
									 false, true, true,
									 NULL, &eqop, &sortop,
									 &hashable);
			reverse = true;
			break;
		case SORTBY_USING:
			Assert(sortby->useOp != NIL);
			sortop = compatible_oper_opid(sortby->useOp,
										  restype,
										  restype,
										  false);

			/*
			 * Verify it's a valid ordering operator, fetch the corresponding
			 * equality operator, and determine whether to consider it like
			 * ASC or DESC.
			 */
			eqop = get_equality_op_for_ordering_op(sortop, &reverse);
			if (!OidIsValid(eqop))
				ereport(ERROR,
						(errcode(ERRCODE_WRONG_OBJECT_TYPE),
						 errmsg("operator %s is not a valid ordering operator",
								strVal(llast(sortby->useOp))),
						 errhint("Ordering operators must be \"<\" or \">\" members of btree operator families.")));

			/*
			 * Also see if the equality operator is hashable.
			 */
			hashable = op_hashjoinable(eqop, restype);
			break;
		default:
			elog(ERROR, "unrecognized sortby_dir: %d", sortby->sortby_dir);
			sortop = InvalidOid;	/* keep compiler quiet */
			eqop = InvalidOid;
			hashable = false;
			reverse = false;
			break;
	}

	cancel_parser_errposition_callback(&pcbstate);

	/* avoid making duplicate sortlist entries */
	if (!targetIsInSortList(tle, sortop, sortlist))
	{
		SortGroupClause *sortcl = makeNode(SortGroupClause);

		sortcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);

		sortcl->eqop = eqop;
		sortcl->sortop = sortop;
		sortcl->hashable = hashable;

		switch (sortby->sortby_nulls)
		{
			case SORTBY_NULLS_DEFAULT:
				/* NULLS FIRST is default for DESC; other way for ASC */
				sortcl->nulls_first = reverse;
				break;
			case SORTBY_NULLS_FIRST:
				sortcl->nulls_first = true;
				break;
			case SORTBY_NULLS_LAST:
				sortcl->nulls_first = false;
				break;
			default:
				elog(ERROR, "unrecognized sortby_nulls: %d",
					 sortby->sortby_nulls);
				break;
		}

		sortlist = lappend(sortlist, sortcl);
	}

	return sortlist;
}

/*
 * addTargetToGroupList
 *		If the given targetlist entry isn't already in the SortGroupClause
 *		list, add it to the end of the list, using default sort/group
 *		semantics.
 *
 * This is very similar to addTargetToSortList, except that we allow the
 * case where only a grouping (equality) operator can be found, and that
 * the TLE is considered "already in the list" if it appears there with any
 * sorting semantics.
 *
 * location is the parse location to be fingered in event of trouble.  Note
 * that we can't rely on exprLocation(tle->expr), because that might point
 * to a SELECT item that matches the GROUP BY item; it'd be pretty confusing
 * to report such a location.
 *
 * Returns the updated SortGroupClause list.
 */
static List *
addTargetToGroupList(ParseState *pstate, TargetEntry *tle,
					 List *grouplist, List *targetlist, int location)
{
	Oid			restype = exprType((Node *) tle->expr);

	/* if tlist item is an UNKNOWN literal, change it to TEXT */
	if (restype == UNKNOWNOID)
	{
		tle->expr = (Expr *) coerce_type(pstate, (Node *) tle->expr,
										 restype, TEXTOID, -1,
										 COERCION_IMPLICIT,
										 COERCE_IMPLICIT_CAST,
										 -1);
		restype = TEXTOID;
	}

	/* avoid making duplicate grouplist entries */
	if (!targetIsInSortList(tle, InvalidOid, grouplist))
	{
		SortGroupClause *grpcl = makeNode(SortGroupClause);
		Oid			sortop;
		Oid			eqop;
		bool		hashable;
		ParseCallbackState pcbstate;

		setup_parser_errposition_callback(&pcbstate, pstate, location);

		/* determine the eqop and optional sortop */
		get_sort_group_operators(restype,
								 false, true, false,
								 &sortop, &eqop, NULL,
								 &hashable);

		cancel_parser_errposition_callback(&pcbstate);

		grpcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
		grpcl->eqop = eqop;
		grpcl->sortop = sortop;
		grpcl->nulls_first = false; /* OK with or without sortop */
		grpcl->hashable = hashable;

		grouplist = lappend(grouplist, grpcl);
	}

	return grouplist;
}

/*
 * assignSortGroupRef
 *	  Assign the targetentry an unused ressortgroupref, if it doesn't
 *	  already have one.  Return the assigned or pre-existing refnumber.
 *
 * 'tlist' is the targetlist containing (or to contain) the given targetentry.
 */
Index
assignSortGroupRef(TargetEntry *tle, List *tlist)
{
	Index		maxRef;
	ListCell   *l;

	if (tle->ressortgroupref)	/* already has one? */
		return tle->ressortgroupref;

	/* easiest way to pick an unused refnumber: max used + 1 */
	maxRef = 0;
	foreach(l, tlist)
	{
		Index		ref = ((TargetEntry *) lfirst(l))->ressortgroupref;

		if (ref > maxRef)
			maxRef = ref;
	}
	tle->ressortgroupref = maxRef + 1;
	return tle->ressortgroupref;
}

/*
 * targetIsInSortList
 *		Is the given target item already in the sortlist?
 *		If sortop is not InvalidOid, also test for a match to the sortop.
 *
 * It is not an oversight that this function ignores the nulls_first flag.
 * We check sortop when determining if an ORDER BY item is redundant with
 * earlier ORDER BY items, because it's conceivable that "ORDER BY
 * foo USING <, foo USING <<<" is not redundant, if <<< distinguishes
 * values that < considers equal.  We need not check nulls_first
 * however, because a lower-order column with the same sortop but
 * opposite nulls direction is redundant.  Also, we can consider
 * ORDER BY foo ASC, foo DESC redundant, so check for a commutator match.
 *
 * Works for both ordering and grouping lists (sortop would normally be
 * InvalidOid when considering grouping).  Note that the main reason we need
 * this routine (and not just a quick test for nonzeroness of ressortgroupref)
 * is that a TLE might be in only one of the lists.
 */
bool
targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList)
{
	Index		ref = tle->ressortgroupref;
	ListCell   *l;

	/* no need to scan list if tle has no marker */
	if (ref == 0)
		return false;

	foreach(l, sortList)
	{
		SortGroupClause *scl = (SortGroupClause *) lfirst(l);

		if (scl->tleSortGroupRef == ref &&
			(sortop == InvalidOid ||
			 sortop == scl->sortop ||
			 sortop == get_commutator(scl->sortop)))
			return true;
	}
	return false;
}

/*
 * findWindowClause
 *		Find the named WindowClause in the list, or return NULL if not there
 */
static WindowClause *
findWindowClause(List *wclist, const char *name)
{
	ListCell   *l;

	foreach(l, wclist)
	{
		WindowClause *wc = (WindowClause *) lfirst(l);

		if (wc->name && strcmp(wc->name, name) == 0)
			return wc;
	}

	return NULL;
}

/*
 * transformFrameOffset
 *		Process a window frame offset expression
 *
 * In RANGE mode, rangeopfamily is the sort opfamily for the input ORDER BY
 * column, and rangeopcintype is the input data type the sort operator is
 * registered with.  We expect the in_range function to be registered with
 * that same type.  (In binary-compatible cases, it might be different from
 * the input column's actual type, so we can't use that for the lookups.)
 * We'll return the OID of the in_range function to *inRangeFunc.
 */
static Node *
transformFrameOffset(ParseState *pstate, int frameOptions,
					 Oid rangeopfamily, Oid rangeopcintype, Oid *inRangeFunc,
					 Node *clause)
{
	const char *constructName = NULL;
	Node	   *node;

	*inRangeFunc = InvalidOid;	/* default result */

	/* Quick exit if no offset expression */
	if (clause == NULL)
		return NULL;

	if (frameOptions & FRAMEOPTION_ROWS)
	{
		/* Transform the raw expression tree */
		node = transformExpr(pstate, clause, EXPR_KIND_WINDOW_FRAME_ROWS);

		/*
		 * Like LIMIT clause, simply coerce to int8
		 */
		constructName = "ROWS";
		node = coerce_to_specific_type(pstate, node, INT8OID, constructName);
	}
	else if (frameOptions & FRAMEOPTION_RANGE)
	{
		/*
		 * We must look up the in_range support function that's to be used,
		 * possibly choosing one of several, and coerce the "offset" value to
		 * the appropriate input type.
		 */
		Oid			nodeType;
		Oid			preferredType;
		int			nfuncs = 0;
		int			nmatches = 0;
		Oid			selectedType = InvalidOid;
		Oid			selectedFunc = InvalidOid;
		CatCList   *proclist;
		int			i;

		/* Transform the raw expression tree */
		node = transformExpr(pstate, clause, EXPR_KIND_WINDOW_FRAME_RANGE);
		nodeType = exprType(node);

		/*
		 * If there are multiple candidates, we'll prefer the one that exactly
		 * matches nodeType; or if nodeType is as yet unknown, prefer the one
		 * that exactly matches the sort column type.  (The second rule is
		 * like what we do for "known_type operator unknown".)
		 */
		preferredType = (nodeType != UNKNOWNOID) ? nodeType : rangeopcintype;

		/* Find the in_range support functions applicable to this case */
		proclist = SearchSysCacheList2(AMPROCNUM,
									   ObjectIdGetDatum(rangeopfamily),
									   ObjectIdGetDatum(rangeopcintype));
		for (i = 0; i < proclist->n_members; i++)
		{
			HeapTuple	proctup = &proclist->members[i]->tuple;
			Form_pg_amproc procform = (Form_pg_amproc) GETSTRUCT(proctup);

			/* The search will find all support proc types; ignore others */
			if (procform->amprocnum != BTINRANGE_PROC)
				continue;
			nfuncs++;

			/* Ignore function if given value can't be coerced to that type */
			if (!can_coerce_type(1, &nodeType, &procform->amprocrighttype,
								 COERCION_IMPLICIT))
				continue;
			nmatches++;

			/* Remember preferred match, or any match if didn't find that */
			if (selectedType != preferredType)
			{
				selectedType = procform->amprocrighttype;
				selectedFunc = procform->amproc;
			}
		}
		ReleaseCatCacheList(proclist);

		/*
		 * Throw error if needed.  It seems worth taking the trouble to
		 * distinguish "no support at all" from "you didn't match any
		 * available offset type".
		 */
		if (nfuncs == 0)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s",
							format_type_be(rangeopcintype)),
					 parser_errposition(pstate, exprLocation(node))));
		if (nmatches == 0)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s",
							format_type_be(rangeopcintype),
							format_type_be(nodeType)),
					 errhint("Cast the offset value to an appropriate type."),
					 parser_errposition(pstate, exprLocation(node))));
		if (nmatches != 1 && selectedType != preferredType)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s",
							format_type_be(rangeopcintype),
							format_type_be(nodeType)),
					 errhint("Cast the offset value to the exact intended type."),
					 parser_errposition(pstate, exprLocation(node))));

		/* OK, coerce the offset to the right type */
		constructName = "RANGE";
		node = coerce_to_specific_type(pstate, node,
									   selectedType, constructName);
		*inRangeFunc = selectedFunc;
	}
	else if (frameOptions & FRAMEOPTION_GROUPS)
	{
		/* Transform the raw expression tree */
		node = transformExpr(pstate, clause, EXPR_KIND_WINDOW_FRAME_GROUPS);

		/*
		 * Like LIMIT clause, simply coerce to int8
		 */
		constructName = "GROUPS";
		node = coerce_to_specific_type(pstate, node, INT8OID, constructName);
	}
	else
	{
		Assert(false);
		node = NULL;
	}

	/* In GPDB, we allow this. */
#if 0
	/* Disallow variables in frame offsets */
	checkExprIsVarFree(pstate, node, constructName);
#endif

	return node;
}
