/*-------------------------------------------------------------------------
 *
 * functions.c
 *	  Execution of SQL-language functions
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.108.2.2 2007/04/02 18:49:36 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/xact.h"
#include "catalog/catquery.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/executor.h"          /* ExecutorStart, ExecutorRun, etc */
#include "executor/functions.h"
#include "funcapi.h"
#include "parser/parse_coerce.h"
#include "parser/parse_expr.h"
#include "tcop/tcopprot.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
#include "catalog/namespace.h"
#include "catalog/pg_namespace.h"
#include "cdb/cdbvars.h"
#include "optimizer/clauses.h"
#include "executor/spi.h"
#include "cdb/memquota.h"
#include "postmaster/autovacuum.h"

/*
 * We have an execution_state record for each query in a function.	Each
 * record contains a plantree for its query.  If the query is currently in
 * F_EXEC_RUN state then there's a QueryDesc too.
 */
typedef enum
{
	F_EXEC_START, F_EXEC_RUN, F_EXEC_DONE
} ExecStatus;

typedef struct local_es
{
	struct local_es *next;
	ExecStatus	status;
	Node	   *stmt;			/* PlannedStmt or utility statement */
	QueryDesc  *qd;				/* null unless status == RUN */
} execution_state;

#define LAST_POSTQUEL_COMMAND(es) ((es)->next == NULL)


/*
 * An SQLFunctionCache record is built during the first call,
 * and linked to from the fn_extra field of the FmgrInfo struct.
 */
typedef struct
{
	char	   *src;			/* function body text (for error msgs) */

	Oid		   *argtypes;		/* resolved types of arguments */
	Oid			rettype;		/* actual return type */
	int16		typlen;			/* length of the return type */
	bool		typbyval;		/* true if return type is pass by value */
	bool		returnsTuple;	/* true if returning whole tuple result */
	bool		shutdown_reg;	/* true if registered shutdown callback */
	bool		readonly_func;	/* true to run in "read only" mode */

	ParamListInfo paramLI;		/* Param list representing current args */

	JunkFilter *junkFilter;		/* used only if returnsTuple */

	/* head of linked list of execution_state records */
	execution_state *func_state;
} SQLFunctionCache;

typedef SQLFunctionCache *SQLFunctionCachePtr;


/* non-export function prototypes */
static execution_state *init_execution_state(List *queryTree_list,
					 SQLFunctionCache *fcache,
					 bool readonly_func);
static void init_sql_fcache(FmgrInfo *finfo);
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache);
static TupleTableSlot * postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache);
static void postquel_end(execution_state *es);
static void postquel_sub_params(SQLFunctionCachePtr fcache,
					FunctionCallInfo fcinfo);
static Datum postquel_execute(execution_state *es,
				 FunctionCallInfo fcinfo,
				 SQLFunctionCachePtr fcache,
				 MemoryContext resultcontext);
static void sql_exec_error_callback(void *arg);
static void ShutdownSQLFunction(Datum arg);
static bool querytree_safe_for_segment_walker(Node *expr, void *context);

/**
 * Walker for querytree_safe_for_segment. 
 */
bool querytree_safe_for_segment_walker(Node *expr, void *context)
{
	Assert(context == NULL);
	
	if (!expr)
	{
		/**
		 * Do not end recursion just because we have reached one leaf node.
		 */
		return false;
	}

	switch(nodeTag(expr))
	{
		case T_Query:
			{
				Query *q = (Query *) expr;
				
				if (!allow_segment_DML &&
					(q->commandType != CMD_SELECT
					 || q->intoClause != NULL
					 || q->resultRelation > 0))
				{
					elog(ERROR, "function cannot execute on segment because it issues a non-SELECT statement");
				}
				
				ListCell * f = NULL;
				foreach(f,q->rtable)
				{
					RangeTblEntry *rte = (RangeTblEntry *) lfirst(f);

					if (rte->rtekind == RTE_RELATION)
					{
						Assert(rte->relid != InvalidOid);
						
						Oid namespaceId = get_rel_namespace(rte->relid);

						Assert(namespaceId != InvalidOid);
						
						if (namespaceId != PG_CATALOG_NAMESPACE)
						{
							elog(ERROR, "function cannot execute on segment because it accesses relation \"%s.%s\"", 
									quote_identifier(get_namespace_name(namespaceId)), quote_identifier(get_rel_name(rte->relid)));
						}
					}
				}
				query_tree_walker(q, querytree_safe_for_segment_walker, context, 0);
				break;
			}
		default:
			break;
	}
	
	return expression_tree_walker(expr, querytree_safe_for_segment_walker, context);
}


/**
 * This function determines if the query tree is safe to be planned and executed on a segment. The checks it performs are:
 * 1. The query cannot access any non-catalog relation.
 * 2. The query must be select only.
 * In case of a problem, the method spits out an error.
 */
void querytree_safe_for_segment(Query *query)
{
	Assert(query);
	querytree_safe_for_segment_walker((Node *)query, NULL);
}

static execution_state *
init_execution_state(List *queryTree_list, SQLFunctionCache *fcache, bool readonly_func)
{
	execution_state *firstes = NULL;
	execution_state *preves = NULL;
	ListCell   *qtl_item;

	foreach(qtl_item, queryTree_list)
	{
		Query	   *queryTree = (Query *) lfirst(qtl_item);
		Node	   *stmt;
		execution_state *newes;

		Assert(IsA(queryTree, Query));

		if (queryTree->commandType == CMD_UTILITY)
			stmt = queryTree->utilityStmt;
		else
			stmt = (Node *) pg_plan_query(queryTree, NULL, QRL_INHERIT);

		/* Precheck all commands for validity in a function */
		if (IsA(stmt, TransactionStmt))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			/* translator: %s is a SQL statement name */
					 errmsg("%s is not allowed in a SQL function",
							CreateCommandTag(stmt))));

		if (readonly_func && !CommandIsReadOnly(stmt))
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			/* translator: %s is a SQL statement name */
					 errmsg("%s is not allowed in a non-volatile function",
							CreateCommandTag(stmt))));

		newes = (execution_state *) palloc(sizeof(execution_state));
		if (preves)
			preves->next = newes;
		else
			firstes = newes;

		newes->next = NULL;
		newes->status = F_EXEC_START;
		newes->stmt = stmt;
		newes->qd = NULL;

		preves = newes;
	}

	return firstes;
}

static void
init_sql_fcache(FmgrInfo *finfo)
{
	Oid			foid = finfo->fn_oid;
	Oid			rettype;
	HeapTuple	procedureTuple;
	Form_pg_proc procedureStruct;
	SQLFunctionCachePtr fcache;
	Oid		   *argOidVect;
	int			nargs;
	List	   *queryTree_list;
	Datum		tmp;
	bool		isNull;
	ListCell * list_item;
	cqContext  *pcqCtx;

	fcache = (SQLFunctionCachePtr) palloc0(sizeof(SQLFunctionCache));

	/*
	 * get the procedure tuple corresponding to the given function Oid
	 */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(foid)));

	procedureTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(procedureTuple))
		elog(ERROR, "cache lookup failed for function %u", foid);
	procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple);

	
	/*
	 * get the result type from the procedure tuple, and check for polymorphic
	 * result type; if so, find out the actual result type.
	 */
	rettype = procedureStruct->prorettype;

	if (rettype == ANYARRAYOID || rettype == ANYELEMENTOID)
	{
		rettype = get_fn_expr_rettype(finfo);
		if (rettype == InvalidOid)		/* this probably should not happen */
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("could not determine actual result type for function declared to return type %s",
							format_type_be(procedureStruct->prorettype)),
									errOmitLocation(true)));
	}

	fcache->rettype = rettype;

	/* Fetch the typlen and byval info for the result type */
	get_typlenbyval(rettype, &fcache->typlen, &fcache->typbyval);

	/* Remember if function is STABLE/IMMUTABLE */
	fcache->readonly_func =
		(procedureStruct->provolatile != PROVOLATILE_VOLATILE);

	/*
	 * We need the actual argument types to pass to the parser.
	 */
	nargs = procedureStruct->pronargs;
	if (nargs > 0)
	{
		int			argnum;

		argOidVect = (Oid *) palloc(nargs * sizeof(Oid));
		memcpy(argOidVect,
			   procedureStruct->proargtypes.values,
			   nargs * sizeof(Oid));
		/* Resolve any polymorphic argument types */
		for (argnum = 0; argnum < nargs; argnum++)
		{
			Oid			argtype = argOidVect[argnum];

			if (argtype == ANYARRAYOID || argtype == ANYELEMENTOID)
			{
				argtype = get_fn_expr_argtype(finfo, argnum);
				if (argtype == InvalidOid)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("could not determine actual type of argument declared %s",
									format_type_be(argOidVect[argnum])),
											errOmitLocation(true)));
				argOidVect[argnum] = argtype;
			}
		}
	}
	else
		argOidVect = NULL;
	fcache->argtypes = argOidVect;

	/*
	 * Parse and rewrite the queries in the function text.
	 */
	tmp = caql_getattr(pcqCtx,
					   Anum_pg_proc_prosrc,
					   &isNull);
	if (isNull)
		elog(ERROR, "null prosrc for function %u", foid);
	fcache->src = TextDatumGetCString(tmp);

	queryTree_list = pg_parse_and_rewrite(fcache->src, argOidVect, nargs);
	

	/*
	 * If we have only SELECT statements with no FROM clauses, we should
	 * be able to execute them locally, even on the QE.  Most often, this is something 
	 * like   SELECT $1
	 * Functions use that type of SELECT to evaluate expressions, so without those,
	 * no functions would be useful.
	 * 
	 * We also need to execute certain catalog queries locally.  The Fault-Tolerance system
	 * does queries of gp_configuration, and some DDL and Utility commands do selects from the 
	 * catalog table, etc.    So, if the FROM clause consists only of catalog tables, we 
	 * will run the query locally.
	 * 
	 */
	if (Gp_role == GP_ROLE_EXECUTE)
	{
		bool canRunLocal = true;
		foreach(list_item, queryTree_list)
		{
			Node	   *parsetree = (Node *) lfirst(list_item);
			if (IsA(parsetree,Query))
			{
				/* This will error out if there is a problem with the query tree */
				querytree_safe_for_segment((Query*)parsetree);
			}
			else
			{
				canRunLocal = false;
				break;
			}		
		}
		
		if (!canRunLocal)
		{
			if (procedureStruct->provolatile == PROVOLATILE_VOLATILE)
				elog(ERROR,"Volatile SQL function %s cannot be executed from the segment databases",NameStr(procedureStruct->proname));	
			else if (procedureStruct->provolatile == PROVOLATILE_STABLE)
				elog(ERROR,"Stable SQL function %s cannot be executed from the segment databases",NameStr(procedureStruct->proname));
			else 
				elog(ERROR,"SQL function %s cannot be executed from the segment databases",NameStr(procedureStruct->proname));		
		}
	}

	/*
	 * Check that the function returns the type it claims to.  Although
	 * in simple cases this was already done when the function was defined,
	 * we have to recheck because database objects used in the function's
	 * queries might have changed type.  We'd have to do it anyway if the
	 * function had any polymorphic arguments.
	 *
	 * Note: we set fcache->returnsTuple according to whether we are
	 * returning the whole tuple result or just a single column.  In the
	 * latter case we clear returnsTuple because we need not act different
	 * from the scalar result case, even if it's a rowtype column.
	 *
	 * In the returnsTuple case, check_sql_fn_retval will also construct a
	 * JunkFilter we can use to coerce the returned rowtype to the desired
	 * form.
	 */
	fcache->returnsTuple = check_sql_fn_retval(foid,
											   rettype,
											   queryTree_list,
											   &fcache->junkFilter);

	/* Finally, plan the queries */
	fcache->func_state = init_execution_state(queryTree_list,
											  fcache,
											  fcache->readonly_func);

	caql_endscan(pcqCtx);

	finfo->fn_extra = (void *) fcache;
}


static void
postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
{
	Snapshot	snapshot;

	Assert(es->qd == NULL);

	/*
	 * In a read-only function, use the surrounding query's snapshot;
	 * otherwise take a new snapshot for each query.  The snapshot should
	 * include a fresh command ID so that all work to date in this transaction
	 * is visible.	We copy in both cases so that postquel_end can
	 * unconditionally do FreeSnapshot.
	 */
	if (fcache->readonly_func)
		snapshot = CopySnapshot(ActiveSnapshot);
	else
	{
		CommandCounterIncrement();
		snapshot = CopySnapshot(GetTransactionSnapshot());
	}

	if (IsA(es->stmt, PlannedStmt))
	{
		es->qd = CreateQueryDesc((PlannedStmt *) es->stmt,
								 fcache->src,
								 snapshot, InvalidSnapshot,
								 None_Receiver,
								 fcache->paramLI, false);

		if (gp_enable_gpperfmon 
			&& Gp_role == GP_ROLE_DISPATCH 
			&& log_min_messages < DEBUG4)
		{
			/* For log level of DEBUG4, gpmon is sent information about queries inside SQL functions as well */
			Assert(fcache->src);
			gpmon_qlog_query_text(es->qd->gpmon_pkt,
					fcache->src,
					application_name,
					NULL /* resqueue name */,
					NULL /* priority */);

		}
		else
		{
			/* Otherwise, we do not record information about internal queries. */
			es->qd->gpmon_pkt = NULL;
		}
	}
	
	else
	{
		es->qd = CreateUtilityQueryDesc(es->stmt,
										fcache->src,
										snapshot,
										None_Receiver,
										fcache->paramLI);
	}

	/* We assume we don't need to set up ActiveSnapshot for ExecutorStart */

	/* Utility commands don't need Executor. */
	if (es->qd->utilitystmt == NULL)
	{
		/*
		 * Only set up to collect queued triggers if it's not a SELECT.
		 * This isn't just an optimization, but is necessary in case a SELECT
		 * returns multiple rows to caller --- we mustn't exit from the
		 * function execution with a stacked AfterTrigger level still active.
		 */
		if (es->qd->operation != CMD_SELECT)
			AfterTriggerBeginQuery();
		
		
    	if (SPI_IsMemoryReserved())
    	{
    		es->qd->plannedstmt->query_mem = SPI_GetMemoryReservation();                		
    	}

    	ExecutorStart(es->qd, 0);
	}

	es->status = F_EXEC_RUN;
}

static TupleTableSlot *
postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
{
	TupleTableSlot *result;
	Snapshot	saveActiveSnapshot;
	long		count;

	/* Make our snapshot the active one for any called functions */
	saveActiveSnapshot = ActiveSnapshot;
	PG_TRY();
	{
		ActiveSnapshot = es->qd->snapshot;

		if (es->qd->utilitystmt != NULL)
		{
			/* ProcessUtility needs the PlannedStmt for DECLARE CURSOR */
			ProcessUtility((es->qd->plannedstmt ?
							(Node *) es->qd->plannedstmt :
							es->qd->utilitystmt), 
						   fcache->src,
						   es->qd->params,
						   false, /* not top level */
						   es->qd->dest, NULL);
			result = NULL;
		}
		else
		{
			/*
			 * If it's the function's last command, and it's a SELECT, fetch
			 * one row at a time so we can return the results. Otherwise just
			 * run it to completion.  (If we run to completion then
			 * ExecutorRun is guaranteed to return NULL.)
			 */
			if (LAST_POSTQUEL_COMMAND(es) &&
				es->qd->operation == CMD_SELECT &&
				es->qd->plannedstmt->intoClause == NULL)
				count = 1L;
			else
				count = 0L;

			result = ExecutorRun(es->qd, ForwardScanDirection, count);
		}
	}
	PG_CATCH();
	{
		/* Restore global vars and propagate error */
		ActiveSnapshot = saveActiveSnapshot;
		PG_RE_THROW();
	}
	PG_END_TRY();

	ActiveSnapshot = saveActiveSnapshot;

	return result;
}

static void
postquel_end(execution_state *es)
{
	Snapshot	saveActiveSnapshot;
	int savedSegNum = -1;

	/* mark status done to ensure we don't do ExecutorEnd twice */
	es->status = F_EXEC_DONE;

	/* Utility commands don't need Executor. */
	if (es->qd->utilitystmt == NULL)
	{
		/* Make our snapshot the active one for any called functions */
		saveActiveSnapshot = ActiveSnapshot;
		PG_TRY();
		{
			ActiveSnapshot = es->qd->snapshot;

			if (es->qd->operation != CMD_SELECT)
				AfterTriggerEndQuery(es->qd->estate);

		  if (Gp_role == GP_ROLE_DISPATCH && es->qd->resource != NULL)
		  {
		    savedSegNum = list_length(es->qd->resource->segments);
		  }
			ExecutorEnd(es->qd);

			/* MPP-14001: Running auto_stats */
			if (Gp_role == GP_ROLE_DISPATCH)
			{
				Oid			relationOid = InvalidOid; 					/* relation that is modified */
				AutoStatsCmdType cmdType = AUTOSTATS_CMDTYPE_SENTINEL; 	/* command type */
				autostats_get_cmdtype(es->qd->plannedstmt, &cmdType, &relationOid);
				auto_stats(cmdType, relationOid, es->qd->es_processed, true /* inFunction */, savedSegNum);
			}
		}
		PG_CATCH();
		{
			/* Restore global vars and propagate error */
			ActiveSnapshot = saveActiveSnapshot;
			PG_RE_THROW();
		}
		PG_END_TRY();
		ActiveSnapshot = saveActiveSnapshot;
	}

	FreeSnapshot(es->qd->snapshot);
	FreeQueryDesc(es->qd);
	es->qd = NULL;
}

/* Build ParamListInfo array representing current arguments */
static void
postquel_sub_params(SQLFunctionCachePtr fcache,
					FunctionCallInfo fcinfo)
{
	ParamListInfo paramLI;
	int			nargs = fcinfo->nargs;

	if (nargs > 0)
	{
		int			i;

		/* sizeof(ParamListInfoData) includes the first array element */
		paramLI = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
									   (nargs - 1) *sizeof(ParamExternData));
		paramLI->numParams = nargs;

		for (i = 0; i < nargs; i++)
		{
			ParamExternData *prm = &paramLI->params[i];

			prm->value = fcinfo->arg[i];
			prm->isnull = fcinfo->argnull[i];
			prm->pflags = 0;
			prm->ptype = fcache->argtypes[i];
		}
	}
	else
		paramLI = NULL;

	if (fcache->paramLI)
		pfree(fcache->paramLI);

	fcache->paramLI = paramLI;
}

static Datum
postquel_execute(execution_state *es,
				 FunctionCallInfo fcinfo,
				 SQLFunctionCachePtr fcache,
				 MemoryContext resultcontext)
{
	TupleTableSlot *slot;
	Datum		value;
	MemoryContext oldcontext;

	if (es->status == F_EXEC_START)
		postquel_start(es, fcache);

	slot = postquel_getnext(es, fcache);

	if (TupIsNull(slot))
	{
		/*
		 * We fall out here for all cases except where we have obtained a row
		 * from a function's final SELECT.
		 */
		postquel_end(es);
		fcinfo->isnull = true;
		return 0;
	}

	/*
	 * If we got a row from a command within the function it has to be the
	 * final command.  All others shouldn't be returning anything.
	 */
	Assert(LAST_POSTQUEL_COMMAND(es));

	/*
	 * Set up to return the function value.  For pass-by-reference datatypes,
	 * be sure to allocate the result in resultcontext, not the current memory
	 * context (which has query lifespan).
	 */
	oldcontext = MemoryContextSwitchTo(resultcontext);

	if (fcache->returnsTuple)
	{
		/*
		 * We are returning the whole tuple, so filter it and apply the proper
		 * labeling to make it a valid Datum.  There are several reasons why
		 * we do this:
		 *
		 * 1. To copy the tuple out of the child execution context and into
		 * the desired result context.
		 *
		 * 2. To remove any junk attributes present in the raw subselect
		 * result. (This is probably not absolutely necessary, but it seems
		 * like good policy.)
		 *
		 * 3. To insert dummy null columns if the declared result type has any
		 * attisdropped columns.
		 */
		HeapTuple	newtup;
		HeapTupleHeader dtup;
		uint32		t_len;
		Oid			dtuptype;
		int32		dtuptypmod;

		newtup = ExecRemoveJunk(fcache->junkFilter, slot);

		/*
		 * Compress out the HeapTuple header data.	We assume that
		 * heap_form_tuple made the tuple with header and body in one palloc'd
		 * chunk.  We want to return a pointer to the chunk start so that it
		 * will work if someone tries to free it.
		 */
		t_len = newtup->t_len;
		dtup = (HeapTupleHeader) newtup;
		memmove((char *) dtup, (char *) newtup->t_data, t_len);

		/*
		 * Use the declared return type if it's not RECORD; else take the type
		 * from the computed result, making sure a typmod has been assigned.
		 */
		if (fcache->rettype != RECORDOID)
		{
			/* function has a named composite return type */
			dtuptype = fcache->rettype;
			dtuptypmod = -1;
		}
		else
		{
			/* function is declared to return RECORD */
			TupleDesc	tupDesc = fcache->junkFilter->jf_cleanTupType;

			if (tupDesc->tdtypeid == RECORDOID &&
				tupDesc->tdtypmod < 0)
				assign_record_type_typmod(tupDesc);
			dtuptype = tupDesc->tdtypeid;
			dtuptypmod = tupDesc->tdtypmod;
		}

		HeapTupleHeaderSetDatumLength(dtup, t_len);
		HeapTupleHeaderSetTypeId(dtup, dtuptype);
		HeapTupleHeaderSetTypMod(dtup, dtuptypmod);

		value = PointerGetDatum(dtup);
		fcinfo->isnull = false;
	}
	else
	{
		/*
		 * Returning a scalar, which we have to extract from the first column
		 * of the SELECT result, and then copy into result context if needed.
		 */
		value = slot_getattr(slot, 1, &(fcinfo->isnull));

		if (!fcinfo->isnull)
			value = datumCopy(value, fcache->typbyval, fcache->typlen);
	}

	MemoryContextSwitchTo(oldcontext);

	/*
	 * If this is a single valued function we have to end the function
	 * execution now.
	 */
	if (!fcinfo->flinfo->fn_retset)
		postquel_end(es);

	return value;
}

Datum
fmgr_sql(PG_FUNCTION_ARGS)
{
	MemoryContext oldcontext;
	SQLFunctionCachePtr fcache;
	ErrorContextCallback sqlerrcontext;
	execution_state *es;
	Datum		result = 0;

	/*
	 * Switch to context in which the fcache lives.  This ensures that
	 * parsetrees, plans, etc, will have sufficient lifetime.  The
	 * sub-executor is responsible for deleting per-tuple information.
	 */
	oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);

	/*
	 * Setup error traceback support for ereport()
	 */
	sqlerrcontext.callback = sql_exec_error_callback;
	sqlerrcontext.arg = fcinfo->flinfo;
	sqlerrcontext.previous = error_context_stack;
	error_context_stack = &sqlerrcontext;

	/*
	 * Initialize fcache (build plans) if first time through.
	 */
	fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
	if (fcache == NULL)
	{
		init_sql_fcache(fcinfo->flinfo);
		fcache = (SQLFunctionCachePtr) fcinfo->flinfo->fn_extra;
	}
	es = fcache->func_state;

	/*
	 * Convert params to appropriate format if starting a fresh execution. (If
	 * continuing execution, we can re-use prior params.)
	 */
	if (es && es->status == F_EXEC_START)
		postquel_sub_params(fcache, fcinfo);

	/*
	 * Find first unfinished query in function.
	 */
	while (es && es->status == F_EXEC_DONE)
		es = es->next;

	bool orig_gp_enable_gpperfmon = gp_enable_gpperfmon;

	PG_TRY();
	{
		/*
		 * Temporarily disable gpperfmon since we don't send information for internal queries in
		 * most cases, except when the debugging level is set to DEBUG4 or DEBUG5.
		 */
		if (log_min_messages > DEBUG4)
		{
			gp_enable_gpperfmon = false;
		}

		/*
		 * Execute each command in the function one after another until we're
		 * executing the final command and get a result or we run out of commands.
		 */
		while (es)
		{
			result = postquel_execute(es, fcinfo, fcache, oldcontext);
			if (es->status != F_EXEC_DONE)
				break;
			es = es->next;
		}

		gp_enable_gpperfmon = orig_gp_enable_gpperfmon;
	}
	PG_CATCH();
	{
		gp_enable_gpperfmon = orig_gp_enable_gpperfmon;
		PG_RE_THROW();
	}
	PG_END_TRY();

	/*
	 * If we've gone through every command in this function, we are done.
	 */
	if (es == NULL)
	{
		/*
		 * Reset the execution states to start over again on next call.
		 */
		es = fcache->func_state;
		while (es)
		{
			es->status = F_EXEC_START;
			es = es->next;
		}

		/*
		 * Let caller know we're finished.
		 */
		if (fcinfo->flinfo->fn_retset)
		{
			ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;

			if (rsi && IsA(rsi, ReturnSetInfo))
				rsi->isDone = ExprEndResult;
			else
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("set-valued function called in context that cannot accept a set"),
									errOmitLocation(true)));
			fcinfo->isnull = true;
			result = (Datum) 0;

			/* Deregister shutdown callback, if we made one */
			if (fcache->shutdown_reg)
			{
				UnregisterExprContextCallback(rsi->econtext,
											  ShutdownSQLFunction,
											  PointerGetDatum(fcache));
				fcache->shutdown_reg = false;
			}
		}

		error_context_stack = sqlerrcontext.previous;

		MemoryContextSwitchTo(oldcontext);

		return result;
	}

	/*
	 * If we got a result from a command within the function it has to be the
	 * final command.  All others shouldn't be returning anything.
	 */
	Assert(LAST_POSTQUEL_COMMAND(es));

	/*
	 * Let caller know we're not finished.
	 */
	if (fcinfo->flinfo->fn_retset)
	{
		ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;

		if (rsi && IsA(rsi, ReturnSetInfo))
			rsi->isDone = ExprMultipleResult;
		else
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("set-valued function called in context that cannot accept a set"),
								errOmitLocation(true)));

		/*
		 * Ensure we will get shut down cleanly if the exprcontext is not run
		 * to completion.
		 */
		if (!fcache->shutdown_reg)
		{
			RegisterExprContextCallback(rsi->econtext,
										ShutdownSQLFunction,
										PointerGetDatum(fcache));
			fcache->shutdown_reg = true;
		}
	}

	error_context_stack = sqlerrcontext.previous;

	MemoryContextSwitchTo(oldcontext);

	return result;
}


/*
 * error context callback to let us supply a call-stack traceback
 */
static void
sql_exec_error_callback(void *arg)
{
	FmgrInfo   *flinfo = (FmgrInfo *) arg;
	SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) flinfo->fn_extra;
	HeapTuple	func_tuple;
	Form_pg_proc functup;
	char	   *fn_name;
	int			syntaxerrposition;
	cqContext  *pcqCtx;

	/* Need access to function's pg_proc tuple */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(flinfo->fn_oid)));

	func_tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(func_tuple))
	{
		caql_endscan(pcqCtx);
		return;					/* shouldn't happen */
	}
	functup = (Form_pg_proc) GETSTRUCT(func_tuple);
	fn_name = NameStr(functup->proname);

	/*
	 * If there is a syntax error position, convert to internal syntax error
	 */
	syntaxerrposition = geterrposition();
	if (syntaxerrposition > 0)
	{
		bool		isnull;
		Datum		tmp;
		char	   *prosrc;

		tmp = caql_getattr(pcqCtx,
						   Anum_pg_proc_prosrc,
						   &isnull);
		if (isnull)
			elog(ERROR, "null prosrc");
		prosrc = DatumGetCString(DirectFunctionCall1(textout, tmp));
		errposition(0);
		internalerrposition(syntaxerrposition);
		internalerrquery(prosrc);
		pfree(prosrc);
	}

	/*
	 * Try to determine where in the function we failed.  If there is a query
	 * with non-null QueryDesc, finger it.	(We check this rather than looking
	 * for F_EXEC_RUN state, so that errors during ExecutorStart or
	 * ExecutorEnd are blamed on the appropriate query; see postquel_start and
	 * postquel_end.)
	 */
	if (fcache)
	{
		execution_state *es;
		int			query_num;

		es = fcache->func_state;
		query_num = 1;
		while (es)
		{
			if (es->qd)
			{
				errcontext("SQL function \"%s\" statement %d",
						   fn_name, query_num);
				break;
			}
			es = es->next;
			query_num++;
		}
		if (es == NULL)
		{
			/*
			 * couldn't identify a running query; might be function entry,
			 * function exit, or between queries.
			 */
			errcontext("SQL function \"%s\"", fn_name);
		}
	}
	else
	{
		/* must have failed during init_sql_fcache() */
		errcontext("SQL function \"%s\" during startup", fn_name);
	}

	caql_endscan(pcqCtx);
}


/*
 * callback function in case a function-returning-set needs to be shut down
 * before it has been run to completion
 */
static void
ShutdownSQLFunction(Datum arg)
{
	SQLFunctionCachePtr fcache = (SQLFunctionCachePtr) DatumGetPointer(arg);
	execution_state *es = fcache->func_state;

	while (es != NULL)
	{
		/* Shut down anything still running */
		if (es->status == F_EXEC_RUN)
			postquel_end(es);
		/* Reset states to START in case we're called again */
		es->status = F_EXEC_START;
		es = es->next;
	}

	/* execUtils will deregister the callback... */
	fcache->shutdown_reg = false;
}


/*
 * check_sql_fn_retval() -- check return value of a list of sql parse trees.
 *
 * The return value of a sql function is the value returned by
 * the final query in the function.  We do some ad-hoc type checking here
 * to be sure that the user is returning the type he claims.
 *
 * For a polymorphic function the passed rettype must be the actual resolved
 * output type of the function; we should never see ANYARRAY or ANYELEMENT
 * as rettype.  (This means we can't check the type during function definition
 * of a polymorphic function.)
 *
 * This function returns true if the sql function returns the entire tuple
 * result of its final SELECT, and false otherwise.  Note that because we
 * allow "SELECT rowtype_expression", this may be false even when the declared
 * function return type is a rowtype.
 *
 * If junkFilter isn't NULL, then *junkFilter is set to a JunkFilter defined
 * to convert the function's tuple result to the correct output tuple type.
 * Whenever the result value is false (ie, the function isn't returning a
 * tuple result), *junkFilter is set to NULL.
 */
bool
check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
					JunkFilter **junkFilter)
{
	Query	   *parse;
	List	   *tlist;
	ListCell   *tlistitem;
	int			tlistlen;
	char		fn_typtype;
	Oid			restype;

	if (junkFilter)
		*junkFilter = NULL;		/* default result */

	/* guard against empty function body; OK only if void return type */
	if (queryTreeList == NIL)
	{
		if (rettype != VOIDOID)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
			 errmsg("return type mismatch in function declared to return %s",
					format_type_be(rettype)),
				 errdetail("Function's final statement must be a SELECT."),
							errOmitLocation(true)));
		return false;
	}

	/* find the final query */
	parse = (Query *) lfirst(list_tail(queryTreeList));

	/*
	 * If the last query isn't a SELECT, the return type must be VOID.
	 *
	 * Note: eventually replace this test with QueryReturnsTuples?  We'd need
	 * a more general method of determining the output type, though.
	 */
	if (!(parse->commandType == CMD_SELECT && 
		  parse->intoClause == NULL &&
		  parse->utilityStmt == NULL))
	{
		if (rettype != VOIDOID)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
			 errmsg("return type mismatch in function declared to return %s",
					format_type_be(rettype)),
				 errdetail("Function's final statement must be a SELECT."),
							errOmitLocation(true)));
		return false;
	}

	/*
	 * OK, it's a SELECT, so it must return something matching the declared
	 * type.  (We used to insist that the declared type not be VOID in this
	 * case, but that makes it hard to write a void function that exits
	 * after calling another void function.  Instead, we insist that the
	 * SELECT return void ... so void is treated as if it were a scalar type
	 * below.)
	 */

	/*
	 * Count the non-junk entries in the result targetlist.
	 */
	tlist = parse->targetList;
	tlistlen = ExecCleanTargetListLength(tlist);

	fn_typtype = get_typtype(rettype);

	if (fn_typtype == 'b' || fn_typtype == 'd' ||
		rettype == VOIDOID)
	{
		/*
		 * For scalar-type returns, the target list should have exactly one
		 * entry, and its type should agree with what the user declared. (As
		 * of Postgres 7.2, we accept binary-compatible types too.)
		 */
		if (tlistlen != 1)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
			 errmsg("return type mismatch in function declared to return %s",
					format_type_be(rettype)),
				 errdetail("Final SELECT must return exactly one column."),
							errOmitLocation(true)));

		restype = exprType((Node *) ((TargetEntry *) linitial(tlist))->expr);
		if (!IsBinaryCoercible(restype, rettype))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
			 errmsg("return type mismatch in function declared to return %s",
					format_type_be(rettype)),
					 errdetail("Actual return type is %s.",
							   format_type_be(restype)),
										errOmitLocation(true)));
	}
	else if (fn_typtype == 'c' || rettype == RECORDOID)
	{
		/* Returns a rowtype */
		TupleDesc	tupdesc;
		int			tupnatts;	/* physical number of columns in tuple */
		int			tuplogcols; /* # of nondeleted columns in tuple */
		int			colindex;	/* physical column index */

		/*
		 * If the target list is of length 1, and the type of the varnode in
		 * the target list matches the declared return type, this is okay.
		 * This can happen, for example, where the body of the function is
		 * 'SELECT func2()', where func2 has the same return type as the
		 * function that's calling it.
		 */
		if (tlistlen == 1)
		{
			restype = exprType((Node *) ((TargetEntry *) linitial(tlist))->expr);
			if (IsBinaryCoercible(restype, rettype))
				return false;	/* NOT returning whole tuple */
		}

		/* Is the rowtype fixed, or determined only at runtime? */
		if (get_func_result_type(func_id, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
		{
			/*
			 * Assume we are returning the whole tuple. Crosschecking against
			 * what the caller expects will happen at runtime.
			 */
			if (junkFilter)
			  {
			    TupleDesc cleanTupType = ExecCleanTypeFromTL(tlist, false /* hasoid */);
			    *junkFilter = ExecInitJunkFilter(tlist, cleanTupType, NULL);
			  }
			return true;
		}
		Assert(tupdesc);

		/*
		 * Verify that the targetlist matches the return tuple type. We scan
		 * the non-deleted attributes to ensure that they match the datatypes
		 * of the non-resjunk columns.
		 */
		tupnatts = tupdesc->natts;
		tuplogcols = 0;			/* we'll count nondeleted cols as we go */
		colindex = 0;

		foreach(tlistitem, tlist)
		{
			TargetEntry *tle = (TargetEntry *) lfirst(tlistitem);
			Form_pg_attribute attr;
			Oid			tletype;
			Oid			atttype;

			if (tle->resjunk)
				continue;

			do
			{
				colindex++;
				if (colindex > tupnatts)
					ereport(ERROR,
							(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
							 errmsg("return type mismatch in function declared to return %s",
									format_type_be(rettype)),
					   errdetail("Final SELECT returns too many columns."),
								errOmitLocation(true)));
				attr = tupdesc->attrs[colindex - 1];
			} while (attr->attisdropped);
			tuplogcols++;

			tletype = exprType((Node *) tle->expr);
			atttype = attr->atttypid;
			if (!IsBinaryCoercible(tletype, atttype))
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
						 errmsg("return type mismatch in function declared to return %s",
								format_type_be(rettype)),
						 errdetail("Final SELECT returns %s instead of %s at column %d.",
								   format_type_be(tletype),
								   format_type_be(atttype),
								   tuplogcols),
											errOmitLocation(true)));
		}

		for (;;)
		{
			colindex++;
			if (colindex > tupnatts)
				break;
			if (!tupdesc->attrs[colindex - 1]->attisdropped)
				tuplogcols++;
		}

		if (tlistlen != tuplogcols)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
			 errmsg("return type mismatch in function declared to return %s",
					format_type_be(rettype)),
					 errdetail("Final SELECT returns too few columns."),
								errOmitLocation(true)));

		/* Set up junk filter if needed */
		if (junkFilter)
			*junkFilter = ExecInitJunkFilterConversion(tlist,
												CreateTupleDescCopy(tupdesc),
													   NULL);

		/* Report that we are returning entire tuple result */
		return true;
	}
	else if (rettype == ANYARRAYOID || rettype == ANYELEMENTOID)
	{
		/* This should already have been caught ... */
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
				 errmsg("cannot determine result data type"),
				 errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."),
							errOmitLocation(true)));
	}
	else
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
				 errmsg("return type %s is not supported for SQL functions",
						format_type_be(rettype)),
								errOmitLocation(true)));

	return false;
}
