//---------------------------------------------------------------------------
//	Greenplum Database
//	Copyright (C) 2012 EMC Corp.
//
//	@filename:
//		gpdbwrappers.cpp
//
//	@doc:
//		Implementation of GPDB function wrappers. Note that we should never
// 		return directly from inside the PG_TRY() block, in order to restore
//		the long jump stack. That is why we save the return value of the GPDB
//		function to a local variable and return it after the PG_END_TRY().
//		./README file contains the sources (caches and catalog tables) of metadata
//		requested by the optimizer and retrieved using GPDB function wrappers. Any
//		change to optimizer's requested metadata should also be recorded in ./README file.
//
//
//	@test:
//
//
//---------------------------------------------------------------------------

#include "gpopt/gpdbwrappers.h"

#include <limits>  // std::numeric_limits

#include "gpos/base.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/optimizer/COptimizerConfig.h"
#include "gpos/error/CAutoExceptionStack.h"
#include "gpos/error/CException.h"

#include "gpopt/utils/gpdbdefs.h"
#include "naucrates/exception.h"

#include "catalog/pg_collation.h"
extern "C" {
#include "access/amapi.h"
#include "access/external.h"
#include "access/genam.h"
#include "access/parallel.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_inherits.h"
#include "cdb/cdbvars.h"
#include "foreign/fdwapi.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/optimizer.h"
#include "optimizer/plancat.h"
#include "optimizer/prep.h"
#include "optimizer/subselect.h"
#include "parser/parse_agg.h"
#include "partitioning/partdesc.h"
#include "storage/lmgr.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/partcache.h"

extern bool enable_parallel;
extern int max_parallel_workers_per_gather;
}
#define GP_WRAP_START                                            \
	sigjmp_buf local_sigjmp_buf;                                 \
	{                                                            \
		CAutoExceptionStack aes((void **) &PG_exception_stack,   \
								(void **) &error_context_stack); \
		if (0 == sigsetjmp(local_sigjmp_buf, 0))                 \
		{                                                        \
			aes.SetLocalJmp(&local_sigjmp_buf)

#define GP_WRAP_END                                        \
	}                                                      \
	else                                                   \
	{                                                      \
		GPOS_RAISE(gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError); \
	}                                                      \
	}

using namespace gpos;

bool
gpdb::AggregateExists(Oid oid)
{
	GP_WRAP_START;
	{
		return aggregate_exists(oid);
	}
	GP_WRAP_END;
	return false;
}

Bitmapset *
gpdb::BmsAddMember(Bitmapset *a, int x)
{
	GP_WRAP_START;
	{
		return bms_add_member(a, x);
	}
	GP_WRAP_END;
	return nullptr;
}

int
gpdb::BmsNextMember(const Bitmapset *a, int prevbit)
{
	GP_WRAP_START;
	{
		return bms_next_member(a, prevbit);
	}
	GP_WRAP_END;
	return -2;
}

void *
gpdb::CopyObject(void *from)
{
	GP_WRAP_START;
	{
		return copyObjectImpl(from);
	}
	GP_WRAP_END;
	return nullptr;
}

Size
gpdb::DatumSize(Datum value, bool type_by_val, int iTypLen)
{
	GP_WRAP_START;
	{
		return datumGetSize(value, type_by_val, iTypLen);
	}
	GP_WRAP_END;
	return 0;
}

Node *
gpdb::MutateExpressionTree(Node *node, Node *(*mutator)(Node *, void *), void *context)
{
	GP_WRAP_START;
	{
		return expression_tree_mutator_wrapper(node, mutator, context);
	}
	GP_WRAP_END;
	return nullptr;
}

bool
gpdb::WalkExpressionTree(Node *node, bool (*walker)(Node *, void *), void *context)
{
	GP_WRAP_START;
	{
		return expression_tree_walker_wrapper(node, walker, context);
	}
	GP_WRAP_END;
	return false;
}

gpos::BOOL
gpdb::WalkQueryTree(Query *query, bool (*walker)(), void *context, int flags)
{
	GP_WRAP_START;
	{
		return query_tree_walker(query, walker, context, flags);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::ExprType(Node *expr)
{
	GP_WRAP_START;
	{
		return exprType(expr);
	}
	GP_WRAP_END;
	return 0;
}

int32
gpdb::ExprTypeMod(Node *expr)
{
	GP_WRAP_START;
	{
		return exprTypmod(expr);
	}
	GP_WRAP_END;
	return 0;
}

Oid
gpdb::ExprCollation(Node *expr)
{
	GP_WRAP_START;
	{
		if (expr && IsA(expr, List))
		{
			// GPDB_91_MERGE_FIXME: collation
			List *exprlist = (List *) expr;
			ListCell *lc;

			Oid collation = InvalidOid;
			foreach (lc, exprlist)
			{
				Node *expr = (Node *) lfirst(lc);
				if ((collation = exprCollation(expr)) != InvalidOid)
				{
					break;
				}
			}
			return collation;
		}
		else
		{
			return exprCollation(expr);
		}
	}
	GP_WRAP_END;
	return 0;
}

Oid
gpdb::TypeCollation(Oid type)
{
	GP_WRAP_START;
	{
		// The real oid returned by the get_typcollation function as the result
		// Cancel the logic that used the value DEFAULT_COLLATION_OID
		Oid typcollation = get_typcollation(type);
		return OidIsValid(typcollation) ? typcollation : InvalidOid;
	}
	GP_WRAP_END;
	return 0;
}

void
gpdb::TypLenByVal(Oid typid, int16 *typlen, bool *typbyval)
{
	GP_WRAP_START;
	{
		get_typlenbyval(typid, typlen, typbyval);
	}
	GP_WRAP_END;
}

List *
gpdb::ExtractNodesPlan(Plan *pl, int node_tag, bool descend_into_subqueries)
{
	GP_WRAP_START;
	{
		return extract_nodes_plan(pl, node_tag, descend_into_subqueries);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::ExtractNodesExpression(Node *node, int node_tag,
							 bool descend_into_subqueries)
{
	GP_WRAP_START;
	{
		return extract_nodes_expression(node, node_tag,
										descend_into_subqueries);
	}
	GP_WRAP_END;
	return NIL;
}

void
gpdb::FreeAttrStatsSlot(AttStatsSlot *sslot)
{
	GP_WRAP_START;
	{
		free_attstatsslot(sslot);
		return;
	}
	GP_WRAP_END;
}

bool
gpdb::IsFuncAllowedForPartitionSelection(Oid funcid)
{
	GP_WRAP_START;
	switch (funcid)
	{
			// These are the functions we have allowed as lossy casts for Partition selection.
			// For range partition selection, the logic in ORCA checks on bounds of the partition ranges.
			// Hence these must be increasing functions.
		case F_TIMESTAMP_DATE:		// date(timestamp) -> date
		case F_INT4_FLOAT8:			// int4(float8) -> int4
		case F_INT4_FLOAT4:			// int4(float4) -> int4
		case F_INT2_INT8:			// int2(int8) -> int2
		case F_INT4_INT8:			// int4(int8) -> int4
		case F_INT2_INT4:			// int2(int4) -> int2
		case F_INT8_FLOAT4:			// int8(float4) -> int8
		case F_INT2_FLOAT4:			// int2(float4) -> int2
		case F_NUMERIC_FLOAT4:		// numeric(float4) -> numeric
		case F_INT8_FLOAT8:			// int8(float8) -> int8
		case F_INT2_FLOAT8:			// int2(float4) -> int2
		case F_FLOAT4_FLOAT8:		// float4(float8) -> float4
		case F_FLOAT8_NUMERIC:		// numeric(float8) -> numeric
		case F_NUMERIC_INT8:		// int8(numeric) -> int8
		case F_NUMERIC_INT2:		// int2(numeric) -> int2
		case F_NUMERIC_INT4:		// int4(numeric) -> int4
			return true;
		default:
			return false;
	}
	GP_WRAP_END;
}

bool
gpdb::FuncStrict(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return func_strict(funcid);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsFuncNDVPreserving(Oid funcid)
{
	// Given a function oid, return whether it's one of a list of NDV-preserving
	// functions (estimated NDV of output is similar to that of the input)
	switch (funcid)
	{
		// for now, these are the functions we consider for this optimization
		case F_LOWER_TEXT:
		case F_LTRIM_TEXT:
		case F_BTRIM_TEXT:
		case F_RTRIM_TEXT:
		case F_UPPER_TEXT:
			return true;
		default:
			return false;
	}
}

char
gpdb::FuncStability(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return func_volatile(funcid);
	}
	GP_WRAP_END;
	return '\0';
}

RegProcedure
gpdb::FuncSupport(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_support(funcid);
	}
	GP_WRAP_END;
	return InvalidOid;
}

Oid
gpdb::FuncNamespace(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_namespace(funcid);
	}
	GP_WRAP_END;
	return InvalidOid;
}

char
gpdb::FuncExecLocation(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return func_exec_location(funcid);
	}
	GP_WRAP_END;
	return '\0';
}

bool
gpdb::FunctionExists(Oid oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return function_exists(oid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetAggIntermediateResultType(Oid aggid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_aggregate */
		return get_agg_transtype(aggid);
	}
	GP_WRAP_END;
	return 0;
}

int
gpdb::GetAggregateArgTypes(Aggref *aggref, Oid *inputTypes)
{
	GP_WRAP_START;
	{
		return get_aggregate_argtypes(aggref, inputTypes);
	}
	GP_WRAP_END;
	return 0;
}

Oid
gpdb::ResolveAggregateTransType(Oid aggfnoid, Oid aggtranstype, Oid *inputTypes,
								int numArguments)
{
	GP_WRAP_START;
	{
		return resolve_aggregate_transtype(aggfnoid, aggtranstype, inputTypes,
										   numArguments);
	}
	GP_WRAP_END;
	return 0;
}

static Datum
GetAggInitVal(Datum textInitVal, Oid transtype)
{
	Oid			typinput,
				typioparam;
	char	   *strInitVal;
	Datum		initVal;

	getTypeInputInfo(transtype, &typinput, &typioparam);
	strInitVal = TextDatumGetCString(textInitVal);
	initVal = OidInputFunctionCall(typinput, strInitVal,
								   typioparam, -1);
	pfree(strInitVal);
	return initVal;
}

void
gpdb::GetAggregateInfo(Aggref *aggref, Oid *aggtransfn,
					   Oid *aggfinalfn, Oid *aggcombinefn,
					   Oid *aggserialfn, Oid *aggdeserialfn,
					   Oid *aggtranstype, int *aggtransspace,
					   Datum *initValue, bool *initValueIsNull,
					   bool *shareable)
{
	GP_WRAP_START;
	{
		HeapTuple	aggTuple;
		Form_pg_aggregate aggform;
		Datum		textInitVal;
		Oid			inputTypes[FUNC_MAX_ARGS];
		int			numArguments;

		aggTuple = SearchSysCache1(AGGFNOID,
							   ObjectIdGetDatum(aggref->aggfnoid));
		if (!HeapTupleIsValid(aggTuple))
			elog(ERROR, "cache lookup failed for aggregate %u",
				 aggref->aggfnoid);

		aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
		*aggtransfn = aggform->aggtransfn;
		*aggfinalfn = aggform->aggfinalfn;
		*aggcombinefn = aggform->aggcombinefn;
		*aggserialfn = aggform->aggserialfn;
		*aggdeserialfn = aggform->aggdeserialfn;
		*aggtranstype = aggform->aggtranstype;
		*aggtransspace = aggform->aggtransspace;

		/*
		 * Resolve the possibly-polymorphic aggregate transition type.
		 */
		/* extract argument types (ignoring any ORDER BY expressions) */
		numArguments = get_aggregate_argtypes(aggref, inputTypes);

		/* resolve actual type of transition state, if polymorphic */
		*aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid,
											   *aggtranstype,
											   inputTypes,
											   numArguments);

		/* get initial value */
		textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple,
									Anum_pg_aggregate_agginitval,
									initValueIsNull);


		if (*initValueIsNull)
			*initValue = (Datum) 0;
		else
			*initValue = GetAggInitVal(textInitVal, *aggtranstype);
		
		/*
		 * If finalfn is marked read-write, we can't share transition states; but
		 * it is okay to share states for AGGMODIFY_SHAREABLE aggs.
		 *
		 * In principle, in a partial aggregate, we could share the transition
		 * state even if the final function is marked as read-write, because the
		 * partial aggregate doesn't execute the final function.  But it's too
		 * early to know whether we're going perform a partial aggregate.
		 */
		*shareable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE);

		ReleaseSysCache(aggTuple);

	}
	GP_WRAP_END;
}


int
gpdb::FindCompatibleAgg(List *agginfos, Aggref *newagg,
						List **same_input_transnos)
{

	GP_WRAP_START;
	{
		return find_compatible_agg(agginfos, newagg, same_input_transnos);
	}
	GP_WRAP_END;
	return -1;
}

int
gpdb::FindCompatibleTrans(List *aggtransinfos, bool shareable,
						  Oid aggtransfn, Oid aggtranstype,
						  int transtypeLen, bool transtypeByVal,
						  Oid aggcombinefn, Oid aggserialfn,
						  Oid aggdeserialfn, Datum initValue, 
						  bool initValueIsNull, List *transnos)
{
	GP_WRAP_START;
	{
		return find_compatible_trans(aggtransinfos, shareable, aggtransfn,
			aggtranstype, transtypeLen, transtypeByVal, aggcombinefn, aggserialfn,
			aggdeserialfn, initValue, initValueIsNull, transnos);
	}
	GP_WRAP_END;
	return -1;
}


Query *
gpdb::FlattenJoinAliasVar(Query *query, gpos::ULONG query_level)
{
	GP_WRAP_START;
	{
		return flatten_join_alias_var_optimizer(query, query_level);
	}
	GP_WRAP_END;

	return nullptr;
}

bool
gpdb::IsOrderedAgg(Oid aggid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_aggregate */
		return is_agg_ordered(aggid);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsRepSafeAgg(Oid aggid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_aggregate */
		return is_agg_repsafe(aggid);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsAggPartialCapable(Oid aggid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_aggregate */
		return is_agg_partial_capable(aggid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetAggregate(const char *agg, Oid type_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_aggregate */
		return get_aggregate(agg, type_oid);
	}
	GP_WRAP_END;
	return 0;
}

Oid
gpdb::GetArrayType(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		return get_array_type(typid);
	}
	GP_WRAP_END;
	return 0;
}

bool
gpdb::GetAttrStatsSlot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind,
					   Oid reqop, int flags)
{
	GP_WRAP_START;
	{
		return get_attstatsslot(sslot, statstuple, reqkind, reqop, flags);
	}
	GP_WRAP_END;
	return false;
}

HeapTuple
gpdb::GetAttStats(Oid relid, AttrNumber attnum)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_statistic */
		return get_att_stats(relid, attnum);
	}
	GP_WRAP_END;
	return nullptr;
}

List *
gpdb::GetExtStats(Relation rel)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_statistic_ext */
		return GetRelationExtStatistics(rel);
	}
	GP_WRAP_END;
	return nullptr;
}

char *
gpdb::GetExtStatsName(Oid statOid)
{
	GP_WRAP_START;
	{
		return GetExtStatisticsName(statOid);
	}
	GP_WRAP_END;
	return nullptr;
}

List *
gpdb::GetExtStatsKinds(Oid statOid)
{
	GP_WRAP_START;
	{
		return GetExtStatisticsKinds(statOid);
	}
	GP_WRAP_END;
	return nullptr;
}

Oid
gpdb::GetCommutatorOp(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		return get_commutator(opno);
	}
	GP_WRAP_END;
	return 0;
}

char *
gpdb::GetCheckConstraintName(Oid check_constraint_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_constraint */
		return get_check_constraint_name(check_constraint_oid);
	}
	GP_WRAP_END;
	return nullptr;
}

Oid
gpdb::GetCheckConstraintRelid(Oid check_constraint_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_constraint */
		return get_check_constraint_relid(check_constraint_oid);
	}
	GP_WRAP_END;
	return 0;
}

Node *
gpdb::PnodeCheckConstraint(Oid check_constraint_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_constraint */
		return get_check_constraint_expr_tree(check_constraint_oid);
	}
	GP_WRAP_END;
	return nullptr;
}

List *
gpdb::GetCheckConstraintOids(Oid rel_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_constraint */
		return get_check_constraint_oids(rel_oid);
	}
	GP_WRAP_END;
	return nullptr;
}

Node *
gpdb::GetRelationPartConstraints(Relation rel)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_partition, pg_partition_rule, pg_constraint */
		List *part_quals = RelationGetPartitionQual(rel);
		if (part_quals)
		{
			return (Node *) make_ands_explicit(part_quals);
		}
	}
	GP_WRAP_END;
	return nullptr;
}

PartitionKey
gpdb::GetRelationPartitionKey(Relation rel)
{
	GP_WRAP_START;
	{
		return RelationGetPartitionKey(rel);
	}
	GP_WRAP_END;
	return nullptr;
}

PartitionDesc
gpdb::RelationGetPartitionDesc(Relation rel, bool omit_detached)
{
	GP_WRAP_START;
	{
		return ::RelationGetPartitionDesc(rel, omit_detached);
	}
	GP_WRAP_END;
	return nullptr;
}

bool
gpdb::GetCastFunc(Oid src_oid, Oid dest_oid, bool *is_binary_coercible,
				  Oid *cast_fn_oid, CoercionPathType *pathtype)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_cast */
		return get_cast_func(src_oid, dest_oid, is_binary_coercible,
							 cast_fn_oid, pathtype);
	}
	GP_WRAP_END;
	return false;
}

unsigned int
gpdb::GetComparisonType(Oid op_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amop */
		return get_comparison_type(op_oid);
	}
	GP_WRAP_END;
	return CmptOther;
}

Oid
gpdb::GetComparisonOperator(Oid left_oid, Oid right_oid, unsigned int cmpt)
{
	GP_WRAP_START;
	{
#ifdef FAULT_INJECTOR
		SIMPLE_FAULT_INJECTOR("gpdbwrappers_get_comparison_operator");
#endif
		/* catalog tables: pg_amop */
		return get_comparison_operator(left_oid, right_oid, (CmpType) cmpt);
	}
	GP_WRAP_END;
	return InvalidOid;
}

Oid
gpdb::GetEqualityOp(Oid type_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		Oid eq_opr;

		get_sort_group_operators(type_oid, false, true, false, nullptr, &eq_opr,
								 nullptr, nullptr);

		return eq_opr;
	}
	GP_WRAP_END;
	return InvalidOid;
}

Oid
gpdb::GetEqualityOpForOrderingOp(Oid opno, bool *reverse)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amop */
		return get_equality_op_for_ordering_op(opno, reverse);
	}
	GP_WRAP_END;
	return InvalidOid;
}

Oid
gpdb::GetOrderingOpForEqualityOp(Oid opno, bool *reverse)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amop */
		return get_ordering_op_for_equality_op(opno, reverse);
	}
	GP_WRAP_END;
	return InvalidOid;
}

char *
gpdb::GetFuncName(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_name(funcid);
	}
	GP_WRAP_END;
	return nullptr;
}

List *
gpdb::GetFuncOutputArgTypes(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_output_arg_types(funcid);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::ProcessRecordFuncTargetList(Oid funcid, List *targetList)
{
	GP_WRAP_START;
	{
		HeapTuple	tp;
		int			numargs;
		Oid		   *argtypes = NULL;
		char	  **argnames = NULL;
		char	   *argmodes = NULL;
		int         i;
		Datum       datum;
		bool        isNull;
		Oid         prorettype;
		ListCell    *lc = NULL;
		int         index;

		tp = SearchSysCache1(PROCOID,
		                     ObjectIdGetDatum(funcid));
		if (!HeapTupleIsValid(tp))
			elog(ERROR, "cache lookup failed for function %u", funcid);
		datum = SysCacheGetAttr(PROCOID, tp, Anum_pg_proc_prorettype, &isNull);
		prorettype = DatumGetObjectId(datum);
		ReleaseSysCache(tp);

		if (prorettype != RECORDOID)
			return targetList;

		numargs = get_func_arg_info(tp, &argtypes, &argnames, &argmodes);

		if (numargs > 0 && argtypes && argnames && argmodes)
		{
			foreach (lc, targetList)
			{
				index = 0;
				TargetEntry *target_entry = (TargetEntry *) lfirst(lc);
				for (i = 0; i < numargs; i++)
				{
					if (PROARGMODE_INOUT == argmodes[i] || PROARGMODE_OUT == argmodes[i] || PROARGMODE_TABLE == argmodes[i])
						index++;

					if (!strcmp(target_entry->resname, argnames[i]) &&
						(PROARGMODE_INOUT == argmodes[i] || PROARGMODE_OUT == argmodes[i] || PROARGMODE_TABLE == argmodes[i]))
					{
						target_entry->resno = index;
						break;
					}
				}
			}
		}
	}
	GP_WRAP_END;
	return targetList;
}

List *
gpdb::GetFuncArgTypes(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_arg_types(funcid);
	}
	GP_WRAP_END;
	return NIL;
}

bool
gpdb::GetFuncRetset(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_retset(funcid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetFuncRetType(Oid funcid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return get_func_rettype(funcid);
	}
	GP_WRAP_END;
	return 0;
}

Oid
gpdb::GetInverseOp(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		return get_negator(opno);
	}
	GP_WRAP_END;
	return 0;
}

RegProcedure
gpdb::GetOpFunc(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		return get_opcode(opno);
	}
	GP_WRAP_END;
	return 0;
}

char *
gpdb::GetOpName(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		return get_opname(opno);
	}
	GP_WRAP_END;
	return nullptr;
}

List *
gpdb::GetRelationKeys(Oid relid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_constraint */
		return get_relation_keys(relid);
	}
	GP_WRAP_END;
	return NIL;
}

Oid
gpdb::GetTypeRelid(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		return get_typ_typrelid(typid);
	}
	GP_WRAP_END;
	return 0;
}

char *
gpdb::GetTypeName(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		return get_type_name(typid);
	}
	GP_WRAP_END;
	return nullptr;
}

int
gpdb::GetGPSegmentCount(void)
{
	GP_WRAP_START;
	{
		return getgpsegmentCount();
	}
	GP_WRAP_END;
	return 0;
}

bool
gpdb::HeapAttIsNull(HeapTuple tup, int attno)
{
	GP_WRAP_START;
	{
		return heap_attisnull(tup, attno, nullptr);
	}
	GP_WRAP_END;
	return false;
}

void
gpdb::FreeHeapTuple(HeapTuple htup)
{
	GP_WRAP_START;
	{
		heap_freetuple(htup);
		return;
	}
	GP_WRAP_END;
}

Oid
gpdb::GetDefaultDistributionOpclassForType(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type, pg_opclass */
		return cdb_default_distribution_opclass_for_type(typid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetColumnDefOpclassForType(List *opclassName, Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type, pg_opclass */
		return cdb_get_opclass_for_column_def(opclassName, typid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetDefaultDistributionOpfamilyForType(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type, pg_opclass */
		return cdb_default_distribution_opfamily_for_type(typid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetDefaultPartitionOpfamilyForType(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type, pg_opclass */
		return default_partition_opfamily_for_type(typid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetHashProcInOpfamily(Oid opfamily, Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amproc, pg_type, pg_opclass */
		return cdb_hashproc_in_opfamily(opfamily, typid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::IsLegacyCdbHashFunction(Oid funcid)
{
	GP_WRAP_START;
	{
		return isLegacyCdbHashFunction(funcid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetLegacyCdbHashOpclassForBaseType(Oid typid)
{
	GP_WRAP_START;
	{
		return get_legacy_cdbhash_opclass_for_base_type(typid);
	}
	GP_WRAP_END;
	return false;
}

Oid
gpdb::GetOpclassFamily(Oid opclass)
{
	GP_WRAP_START;
	{
		return get_opclass_family(opclass);
	}
	GP_WRAP_END;
	return false;
}

List *
gpdb::LAppend(List *list, void *datum)
{
	GP_WRAP_START;
	{
		return lappend(list, datum);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::LAppendInt(List *list, int iDatum)
{
	GP_WRAP_START;
	{
		return lappend_int(list, iDatum);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::LAppendOid(List *list, Oid datum)
{
	GP_WRAP_START;
	{
		return lappend_oid(list, datum);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::LPrepend(void *datum, List *list)
{
	GP_WRAP_START;
	{
		return lcons(datum, list);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::LPrependInt(int datum, List *list)
{
	GP_WRAP_START;
	{
		return lcons_int(datum, list);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::LPrependOid(Oid datum, List *list)
{
	GP_WRAP_START;
	{
		return lcons_oid(datum, list);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::ListConcat(List *list1, List *list2)
{
	GP_WRAP_START;
	{
		return list_concat(list1, list2);
	}
	GP_WRAP_END;
	return NIL;
}

List *
gpdb::ListCopy(List *list)
{
	GP_WRAP_START;
	{
		return list_copy(list);
	}
	GP_WRAP_END;
	return NIL;
}

ListCell *
gpdb::ListHead(List *l)
{
	GP_WRAP_START;
	{
		return list_head(l);
	}
	GP_WRAP_END;
	return nullptr;
}

ListCell *
gpdb::ListTail(List *l)
{
	GP_WRAP_START;
	{
		return list_tail(l);
	}
	GP_WRAP_END;
	return nullptr;
}

uint32
gpdb::ListLength(List *l)
{
	GP_WRAP_START;
	{
		return list_length(l);
	}
	GP_WRAP_END;
	return 0;
}

void *
gpdb::ListNth(List *list, int n)
{
	GP_WRAP_START;
	{
		return list_nth(list, n);
	}
	GP_WRAP_END;
	return nullptr;
}

int
gpdb::ListNthInt(List *list, int n)
{
	GP_WRAP_START;
	{
		return list_nth_int(list, n);
	}
	GP_WRAP_END;
	return 0;
}

Oid
gpdb::ListNthOid(List *list, int n)
{
	GP_WRAP_START;
	{
		return list_nth_oid(list, n);
	}
	GP_WRAP_END;
	return 0;
}

bool
gpdb::ListMemberOid(List *list, Oid oid)
{
	GP_WRAP_START;
	{
		return list_member_oid(list, oid);
	}
	GP_WRAP_END;
	return false;
}

void
gpdb::ListFree(List *list)
{
	GP_WRAP_START;
	{
		list_free(list);
		return;
	}
	GP_WRAP_END;
}

void
gpdb::ListFreeDeep(List *list)
{
	GP_WRAP_START;
	{
		list_free_deep(list);
		return;
	}
	GP_WRAP_END;
}

TypeCacheEntry *
gpdb::LookupTypeCache(Oid type_id, int flags)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type, pg_operator, pg_opclass, pg_opfamily, pg_amop */
		return lookup_type_cache(type_id, flags);
	}
	GP_WRAP_END;
	return nullptr;
}

Value *
gpdb::MakeStringValue(char *str)
{
	GP_WRAP_START;
	{
		return makeString(str);
	}
	GP_WRAP_END;
	return nullptr;
}

Value *
gpdb::MakeIntegerValue(long i)
{
	GP_WRAP_START;
	{
		return makeInteger(i);
	}
	GP_WRAP_END;
	return nullptr;
}

Node *
gpdb::MakeIntConst(int32 intValue)
{
	GP_WRAP_START;
	{
		return (Node *) makeConst(INT4OID, -1, InvalidOid, sizeof(int32),
								  Int32GetDatum(intValue), false, true);
	}
	GP_WRAP_END;
}

Node *
gpdb::MakeBoolConst(bool value, bool isnull)
{
	GP_WRAP_START;
	{
		return makeBoolConst(value, isnull);
	}
	GP_WRAP_END;
	return nullptr;
}

Node *
gpdb::MakeNULLConst(Oid type_oid)
{
	GP_WRAP_START;
	{
		return (Node *) makeNullConst(type_oid, -1 /*consttypmod*/, InvalidOid);
	}
	GP_WRAP_END;
	return nullptr;
}

Node *
gpdb::MakeSegmentFilterExpr(int segid)
{
	GP_WRAP_START;
	{
		return (Node *) makeSegmentFilterExpr(segid);
	}
	GP_WRAP_END;
}

TargetEntry *
gpdb::MakeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
{
	GP_WRAP_START;
	{
		return makeTargetEntry(expr, resno, resname, resjunk);
	}
	GP_WRAP_END;
	return nullptr;
}

Var *
gpdb::MakeVar(Index varno, AttrNumber varattno, Oid vartype, int32 vartypmod,
			  Index varlevelsup)
{
	GP_WRAP_START;
	{
		// GPDB_91_MERGE_FIXME: collation
		Oid collation = TypeCollation(vartype);
		return makeVar(varno, varattno, vartype, vartypmod, collation,
					   varlevelsup);
	}
	GP_WRAP_END;
	return nullptr;
}

void *
gpdb::MemCtxtAllocZeroAligned(MemoryContext context, Size size)
{
	GP_WRAP_START;
	{
		return MemoryContextAllocZeroAligned(context, size);
	}
	GP_WRAP_END;
	return nullptr;
}

void *
gpdb::MemCtxtAllocZero(MemoryContext context, Size size)
{
	GP_WRAP_START;
	{
		return MemoryContextAllocZero(context, size);
	}
	GP_WRAP_END;
	return nullptr;
}

void *
gpdb::MemCtxtRealloc(void *pointer, Size size)
{
	GP_WRAP_START;
	{
		return repalloc(pointer, size);
	}
	GP_WRAP_END;
	return nullptr;
}

char *
gpdb::MemCtxtStrdup(MemoryContext context, const char *string)
{
	GP_WRAP_START;
	{
		return MemoryContextStrdup(context, string);
	}
	GP_WRAP_END;
	return nullptr;
}

// Helper function to throw an error with errcode, message and hint, like you
// would with ereport(...) in the backend. This could be extended for other
// fields, but this is all we need at the moment.
void
gpdb::GpdbEreportImpl(int xerrcode, int severitylevel, const char *xerrmsg,
					  const char *xerrhint, const char *filename, int lineno,
					  const char *funcname)
{
	GP_WRAP_START;
	{
		// We cannot use the ereport() macro here, because we want to pass on
		// the caller's filename and line number. This is essentially an
		// expanded version of ereport(). It will be caught by the
		// GP_WRAP_END, and propagated up as a C++ exception, to be
		// re-thrown as a Postgres error once we leave the C++ land.
		if (errstart(severitylevel, TEXTDOMAIN))
		{
			errcode(xerrcode);
			errmsg("%s", xerrmsg);
			if (xerrhint)
			{
				errhint("%s", xerrhint);
			}
			errfinish(filename, lineno, funcname);
		}
	}
	GP_WRAP_END;
}

char *
gpdb::NodeToString(void *obj)
{
	GP_WRAP_START;
	{
		return nodeToString(obj);
	}
	GP_WRAP_END;
	return nullptr;
}

Node *
gpdb::GetTypeDefault(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		return get_typdefault(typid);
	}
	GP_WRAP_END;
	return nullptr;
}


double
gpdb::NumericToDoubleNoOverflow(Numeric num)
{
	GP_WRAP_START;
	{
		return numeric_to_double_no_overflow(num);
	}
	GP_WRAP_END;
	return 0.0;
}

bool
gpdb::NumericIsNan(Numeric num)
{
	GP_WRAP_START;
	{
		return NUMERIC_IS_NAN(num);
	}
	GP_WRAP_END;
	return false;
}

double
gpdb::ConvertTimeValueToScalar(Datum datum, Oid typid)
{
	bool failure = false;
	GP_WRAP_START;
	{
		return convert_timevalue_to_scalar(datum, typid, &failure);
	}
	GP_WRAP_END;
	return 0.0;
}

double
gpdb::ConvertNetworkToScalar(Datum datum, Oid typid)
{
	bool failure = false;
	GP_WRAP_START;
	{
		return convert_network_to_scalar(datum, typid, &failure);
	}
	GP_WRAP_END;
	return 0.0;
}

bool
gpdb::IsOpHashJoinable(Oid opno, Oid inputtype)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		if (!op_hashjoinable(opno, inputtype))
			return false;

		/*
		 * Even if oprcanhash is true, we need to verify that hash functions
		 * actually exist for this operator. This is because oprcanhash can be
		 * set to true while the operator is only registered in a btree opfamily
		 * and not in a hash opfamily, which would cause execution-time errors
		 * when trying to build hash tables.
		 *
		 * See get_op_hash_functions() in lsyscache.c which requires operators
		 * to be registered in a hash opfamily (amopmethod == HASH_AM_OID).
		 */
		RegProcedure hash_proc;
		if (!get_op_hash_functions(opno, &hash_proc, NULL))
			return false;

		return true;
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsOpMergeJoinable(Oid opno, Oid inputtype)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		return op_mergejoinable(opno, inputtype);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsOpStrict(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator, pg_proc */
		return op_strict(opno);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsOpNDVPreserving(Oid opno)
{
	switch (opno)
	{
		// operators are NDV-preserving if the operation does not change the number
		// of NDVs when one argument is a constant.
		// note that we do additional checks later, e.g. col || 'const' is
		// NDV-preserving, while col1 || col2 is not, same with arithmatic
		// operators
		case OIDTextConcatenateOperator:
		case Int4AddOperator:
		case Int8AddOperator:
		case DateIntervalAddOperator:
		case DateInt4AddOperator:
		case DateTimeAddOperator:
		case DateTimetzAddOperator:
		case NumericAddOperator:
		case TimestampIntervalAddOperator:
		case IntervalTimestampAddOperator:
		case Int4DateAddOperator:
			return true;
		default:
			return false;
	}
}

void
gpdb::GetOpInputTypes(Oid opno, Oid *lefttype, Oid *righttype)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_operator */
		op_input_types(opno, lefttype, righttype);
		return;
	}
	GP_WRAP_END;
}

void *
gpdb::GPDBAlloc(Size size)
{
	GP_WRAP_START;
	{
		return palloc(size);
	}
	GP_WRAP_END;
	return nullptr;
}

void
gpdb::GPDBFree(void *ptr)
{
	GP_WRAP_START;
	{
		pfree(ptr);
		return;
	}
	GP_WRAP_END;
}

bool
gpdb::WalkQueryOrExpressionTree(Node *node, bool (*walker)(Node *, void *), void *context,
								int flags)
{
	GP_WRAP_START;
	{
		return query_or_expression_tree_walker_wrapper(node, walker, context, flags);
	}
	GP_WRAP_END;
	return false;
}

Node *
gpdb::MutateQueryOrExpressionTree(Node *node, Node *(*mutator)(Node *, void *), void *context,
								  int flags)
{
	GP_WRAP_START;
	{
		return query_or_expression_tree_mutator_wrapper(node, mutator, context, flags);
	}
	GP_WRAP_END;
	return nullptr;
}

Query *
gpdb::MutateQueryTree(Query *query, Node *(*mutator)(Node *, void *), void *context,
					  int flags)
{
	GP_WRAP_START;
	{
		return query_tree_mutator_wrapper(query, mutator, context, flags);
	}
	GP_WRAP_END;
	return nullptr;
}

bool
gpdb::WalkQueryTree(Query *query, bool (*walker)(Node *, void *), void *context,
					  int flags)
{
	GP_WRAP_START;
	{
		return query_tree_walker_wrapper(query, walker, context, flags);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::HasSubclassSlow(Oid rel_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_inherits */
		return has_subclass_slow(rel_oid);
	}
	GP_WRAP_END;
	return false;
}

GpPolicy *
gpdb::GetDistributionPolicy(Relation rel)
{
	GP_WRAP_START;
	{
		// external tables are a special case, and we need to manually build
		// the GpPolicy struct which contains the external table's distribution
		if (rel_is_external_table(rel->rd_id))
		{
			return GpPolicyFetch(rel->rd_id);
		}
		// we determine the distribution at a later point for foreign tables
		else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
		{
			return nullptr;
		}
		/* catalog tables: pg_class */
		return relation_policy(rel);
	}
	GP_WRAP_END;
	return nullptr;
}

gpos::BOOL
gpdb::IsChildPartDistributionMismatched(Relation rel)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_class, pg_inherits */
		return child_distribution_mismatch(rel);
	}
	GP_WRAP_END;
	return false;
}

double
gpdb::CdbEstimatePartitionedNumTuples(Relation rel)
{
	GP_WRAP_START;
	{
		return cdb_estimate_partitioned_numtuples(rel);
	}
	GP_WRAP_END;
}

PageEstimate
gpdb::CdbEstimatePartitionedNumPages(Relation rel)
{
	GP_WRAP_START;
	{
		return cdb_estimate_partitioned_numpages(rel);
	}
	GP_WRAP_END;
}

void
gpdb::CloseRelation(Relation rel)
{
	GP_WRAP_START;
	{
		RelationClose(rel);
		return;
	}
	GP_WRAP_END;
}

List *
gpdb::GetRelationIndexes(Relation relation)
{
	GP_WRAP_START;
	{
		if (relation->rd_rel->relhasindex)
		{
			/* catalog tables: from relcache */
			return RelationGetIndexList(relation);
		}
	}
	GP_WRAP_END;
	return NIL;
}

MVNDistinct *
gpdb::GetMVNDistinct(Oid stat_oid)
{
	GP_WRAP_START;
	{
		return statext_ndistinct_load(stat_oid);
	}
	GP_WRAP_END;
}

MVDependencies *
gpdb::GetMVDependencies(Oid stat_oid)
{
	GP_WRAP_START;
	{
		return statext_dependencies_load(stat_oid, true);
	}
	GP_WRAP_END;
}

gpdb::RelationWrapper
gpdb::GetRelation(Oid rel_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: relcache */
		return RelationWrapper{RelationIdGetRelation(rel_oid)};
	}
	GP_WRAP_END;
}

ForeignScan *
gpdb::CreateForeignScan(Oid rel_oid, Index scanrelid, List *qual,
						List *targetlist, Query *query, RangeTblEntry *rte)
{
	GP_WRAP_START;
	{
		return BuildForeignScan(rel_oid, scanrelid, qual, targetlist, query,
								rte);
	}
	GP_WRAP_END;
	return nullptr;
}

TargetEntry *
gpdb::FindFirstMatchingMemberInTargetList(Node *node, List *targetlist)
{
	GP_WRAP_START;
	{
		return tlist_member((Expr *) node, targetlist);
	}
	GP_WRAP_END;
	return nullptr;
}

List *
gpdb::FindMatchingMembersInTargetList(Node *node, List *targetlist)
{
	GP_WRAP_START;
	{
		return tlist_members(node, targetlist);
	}
	GP_WRAP_END;

	return NIL;
}

bool
gpdb::Equals(void *p1, void *p2)
{
	GP_WRAP_START;
	{
		return equal(p1, p2);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsCompositeType(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		return type_is_rowtype(typid);
	}
	GP_WRAP_END;
	return false;
}

bool
gpdb::IsTextRelatedType(Oid typid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type */
		char typcategory;
		bool typispreferred;
		get_type_category_preferred(typid, &typcategory, &typispreferred);

		return typcategory == TYPCATEGORY_STRING;
	}
	GP_WRAP_END;
	return false;
}

StringInfo
gpdb::MakeStringInfo(void)
{
	GP_WRAP_START;
	{
		return makeStringInfo();
	}
	GP_WRAP_END;
	return nullptr;
}

void
gpdb::AppendStringInfo(StringInfo str, const char *str1, const char *str2)
{
	GP_WRAP_START;
	{
		appendStringInfo(str, "%s%s", str1, str2);
		return;
	}
	GP_WRAP_END;
}

int
gpdb::FindNodes(Node *node, List *nodeTags)
{
	GP_WRAP_START;
	{
		return find_nodes(node, nodeTags);
	}
	GP_WRAP_END;
	return -1;
}

int
gpdb::CheckCollation(Node *node)
{
	GP_WRAP_START;
	{
		return check_collation(node);
	}
	GP_WRAP_END;
	return -1;
}

bool
gpdb::HasOrderByOrderingOp(Query *query)
{
	GP_WRAP_START;
	{
		return has_orderby_ordering_op(query);
	}
	GP_WRAP_END;
	return false;
}

Node *
gpdb::CoerceToCommonType(ParseState *pstate, Node *node, Oid target_type,
						 const char *context)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_type, pg_cast */
		return coerce_to_common_type(pstate, node, target_type, context);
	}
	GP_WRAP_END;
	return nullptr;
}

bool
gpdb::ResolvePolymorphicArgType(int numargs, Oid *argtypes, char *argmodes,
								FuncExpr *call_expr)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_proc */
		return resolve_polymorphic_argtypes(numargs, argtypes, argmodes,
											(Node *) call_expr);
	}
	GP_WRAP_END;
	return false;
}

// hash a list of const values with GPDB's hash function
int32
gpdb::CdbHashConstList(List *constants, int num_segments, Oid *hashfuncs)
{
	GP_WRAP_START;
	{
		return cdbhash_const_list(constants, num_segments, hashfuncs);
	}
	GP_WRAP_END;
	return 0;
}

unsigned int
gpdb::CdbHashRandomSeg(int num_segments)
{
	GP_WRAP_START;
	{
		return cdbhashrandomseg(num_segments);
	}
	GP_WRAP_END;
	return 0;
}

// check permissions on range table
void
gpdb::CheckRTPermissions(List *rtable)
{
	GP_WRAP_START;
	{
		ExecCheckRTPerms(rtable, true);
		return;
	}
	GP_WRAP_END;
}


// check that a table doesn't have UPDATE triggers.
bool
gpdb::HasUpdateTriggers(Oid relid)
{
	GP_WRAP_START;
	{
		return has_update_triggers(relid, true);
	}
	GP_WRAP_END;
	return false;
}

// get index op family properties
void
gpdb::IndexOpProperties(Oid opno, Oid opfamily, StrategyNumber *strategynumber,
						Oid *righttype)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amop */

		// Only the right type is returned to the caller, the left
		// type is simply ignored.
		Oid lefttype;
		INT strategy;

		get_op_opfamily_properties(opno, opfamily, false, &strategy, &lefttype,
								   righttype);

		// Ensure the value of strategy doesn't get truncated when converted to StrategyNumber
		GPOS_ASSERT(strategy >= 0 &&
					strategy <= std::numeric_limits<StrategyNumber>::max());
		*strategynumber = static_cast<StrategyNumber>(strategy);
		return;
	}
	GP_WRAP_END;
}

// check whether index column is returnable (for index-only scans)
gpos::BOOL
gpdb::IndexCanReturn(Relation index, int attno)
{
	GP_WRAP_START;
	{
		return index_can_return(index, attno);
	}
	GP_WRAP_END;
}

// get oids of opfamilies for the index keys
List *
gpdb::GetIndexOpFamilies(Oid index_oid)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_index */

		// We return the operator families of the index keys.
		return get_index_opfamilies(index_oid);
	}
	GP_WRAP_END;

	return NIL;
}

// get oids of families this operator belongs to
List *
gpdb::GetOpFamiliesForScOp(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amop */

		// We return the operator families this operator
		// belongs to.
		return get_operator_opfamilies(opno);
	}
	GP_WRAP_END;

	return NIL;
}

// get the OID of hash equality operator(s) compatible with the given op
Oid
gpdb::GetCompatibleHashOpFamily(Oid opno)
{
	GP_WRAP_START;
	{
		return get_compatible_hash_opfamily(opno);
	}
	GP_WRAP_END;
	return InvalidOid;
}

// get the OID of hash equality operator(s) compatible with the given op
Oid
gpdb::GetCompatibleLegacyHashOpFamily(Oid opno)
{
	GP_WRAP_START;
	{
		return get_compatible_legacy_hash_opfamily(opno);
	}
	GP_WRAP_END;
	return InvalidOid;
}

List *
gpdb::GetMergeJoinOpFamilies(Oid opno)
{
	GP_WRAP_START;
	{
		/* catalog tables: pg_amop */

		return get_mergejoin_opfamilies(opno);
	}
	GP_WRAP_END;
	return NIL;
}


// get the OID of base elementtype for a given typid
// eg.: CREATE DOMAIN text_domain as text;
// SELECT oid, typbasetype from pg_type where typname = 'text_domain';
// oid         | XXXXX  --> Oid for text_domain
// typbasetype | 25     --> Oid for base element ie, TEXT
Oid
gpdb::GetBaseType(Oid typid)
{
	GP_WRAP_START;
	{
		return getBaseType(typid);
	}
	GP_WRAP_END;
	return InvalidOid;
}

// Evaluates 'expr' and returns the result as an Expr.
// Caller keeps ownership of 'expr' and takes ownership of the result
Expr *
gpdb::EvaluateExpr(Expr *expr, Oid result_type, int32 typmod)
{
	GP_WRAP_START;
	{
		// GPDB_91_MERGE_FIXME: collation
		return evaluate_expr(expr, result_type, typmod, InvalidOid);
	}
	GP_WRAP_END;
	return nullptr;
}

char *
gpdb::DefGetString(DefElem *defelem)
{
	GP_WRAP_START;
	{
		return defGetString(defelem);
	}
	GP_WRAP_END;
	return nullptr;
}

Expr *
gpdb::TransformArrayConstToArrayExpr(Const *c)
{
	GP_WRAP_START;
	{
		return transform_array_Const_to_ArrayExpr(c);
	}
	GP_WRAP_END;
	return nullptr;
}

Node *
gpdb::EvalConstExpressions(Node *node)
{
	GP_WRAP_START;
	{
		return eval_const_expressions(nullptr, node);
	}
	GP_WRAP_END;
	return nullptr;
}

#ifdef FAULT_INJECTOR
FaultInjectorType_e
gpdb::InjectFaultInOptTasks(const char *fault_name)
{
	GP_WRAP_START;
	{
		return FaultInjector_InjectFaultIfSet(fault_name, DDLNotSpecified, "",
											  "");
	}
	GP_WRAP_END;
	return FaultInjectorTypeNotSpecified;
}
#endif

/*
 * To detect changes to catalog tables that require resetting the Metadata
 * Cache, we use the normal PostgreSQL catalog cache invalidation mechanism.
 * We register a callback to a cache on all the catalog tables that contain
 * information that's contained in the ORCA metadata cache.

 * There is no fine-grained mechanism in the metadata cache for invalidating
 * individual entries ATM, so we just blow the whole cache whenever anything
 * changes. The callback simply increments a counter. Whenever we start
 * planning a query, we check the counter to see if it has changed since the
 * last planned query, and reset the whole cache if it has.
 *
 * To make sure we've covered all catalog tables that contain information
 * that's stored in the metadata cache, there are "catalog tables: xxx"
 * comments in all the calls to backend functions in this file. They indicate
 * which catalog tables each function uses. We conservatively assume that
 * anything fetched via the wrapper functions in this file can end up in the
 * metadata cache and hence need to have an invalidation callback registered.
 */
static bool mdcache_invalidation_counter_registered = false;
static int64 mdcache_invalidation_counter = 0;
static int64 last_mdcache_invalidation_counter = 0;

static void
mdsyscache_invalidation_counter_callback(Datum /*arg*/, int /*cacheid*/,
										 uint32 /*hashvalue*/)
{
	mdcache_invalidation_counter++;
}

static void
mdrelcache_invalidation_counter_callback(Datum /*arg*/, Oid /*relid*/)
{
	mdcache_invalidation_counter++;
}

static void
register_mdcache_invalidation_callbacks(void)
{
	/* These are all the catalog tables that we care about. */
	int metadata_caches[] = {
		AGGFNOID,		  /* pg_aggregate */
		AMOPOPID,		  /* pg_amop */
		CASTSOURCETARGET, /* pg_cast */
		CONSTROID,		  /* pg_constraint */
		OPEROID,		  /* pg_operator */
		OPFAMILYOID,	  /* pg_opfamily */
		STATRELATTINH,	  /* pg_statistics */
		TYPEOID,		  /* pg_type */
		PROCOID,		  /* pg_proc */

		/*
		 * lookup_type_cache() will also access pg_opclass, via GetDefaultOpClass(),
		 * but there is no syscache for it. Postgres doesn't seem to worry about
		 * invalidating the type cache on updates to pg_opclass, so we don't
		 * worry about that either.
		 */
		/* pg_opclass */

		/*
		 * Information from the following catalogs are included in the
		 * relcache, and any updates will generate relcache invalidation
		 * event. We'll catch the relcache invalidation event and don't need
		 * to register a catcache callback for them.
		 */
		/* pg_class */
		/* pg_index */

		/*
		 * pg_foreign_table is updated when a new external table is dropped/created,
		 * which will trigger a relcache invalidation event.
		 */
		/* pg_foreign_table */

		/*
		 * XXX: no syscache on pg_inherits. Is that OK? For any partitioning
		 * changes, I think there will also be updates on pg_partition and/or
		 * pg_partition_rules.
		 */
		/* pg_inherits */

		/*
		 * We assume that gp_segment_config will not change on the fly in a way that
		 * would affect ORCA
		 */
		/* gp_segment_config */
	};
	unsigned int i;

	for (i = 0; i < lengthof(metadata_caches); i++)
	{
		CacheRegisterSyscacheCallback(metadata_caches[i],
									  &mdsyscache_invalidation_counter_callback,
									  (Datum) 0);
	}

	/* also register the relcache callback */
	CacheRegisterRelcacheCallback(&mdrelcache_invalidation_counter_callback,
								  (Datum) 0);
}

// Has there been any catalog changes since last call?
bool
gpdb::MDCacheNeedsReset(void)
{
	GP_WRAP_START;
	{
		if (!mdcache_invalidation_counter_registered)
		{
			register_mdcache_invalidation_callbacks();
			mdcache_invalidation_counter_registered = true;
		}
		if (last_mdcache_invalidation_counter == mdcache_invalidation_counter)
		{
			return false;
		}
		else
		{
			last_mdcache_invalidation_counter = mdcache_invalidation_counter;
			return true;
		}
	}
	GP_WRAP_END;

	return true;
}

// returns true if a query cancel is requested in GPDB
bool
gpdb::IsAbortRequested(void)
{
	// No GP_WRAP_START/END needed here. We just check these global flags,
	// it cannot throw an ereport().
	return (QueryCancelPending || ProcDiePending);
}

// Given the type OID, get the typelem (InvalidOid if not an array type).
Oid
gpdb::GetElementType(Oid array_type_oid)
{
	GP_WRAP_START;
	{
		return get_element_type(array_type_oid);
	}
	GP_WRAP_END;
}

GpPolicy *
gpdb::MakeGpPolicy(GpPolicyType ptype, int nattrs, int numsegments)
{
	GP_WRAP_START;
	{
		/*
		 * FIXME_TABLE_EXPAND: it used by ORCA, help...
		 */
		return makeGpPolicy(ptype, nattrs, numsegments);
	}
	GP_WRAP_END;
}

uint32
gpdb::HashChar(Datum d)
{
	GP_WRAP_START;
	{
		return DatumGetUInt32(DirectFunctionCall1(hashchar, d));
	}
	GP_WRAP_END;
}

uint32
gpdb::HashBpChar(Datum d)
{
	GP_WRAP_START;
	{
		return DatumGetUInt32(
			DirectFunctionCall1Coll(hashbpchar, C_COLLATION_OID, d));
	}
	GP_WRAP_END;
}

uint32
gpdb::HashText(Datum d)
{
	GP_WRAP_START;
	{
		return DatumGetUInt32(
			DirectFunctionCall1Coll(hashtext, C_COLLATION_OID, d));
	}
	GP_WRAP_END;
}

uint32
gpdb::HashName(Datum d)
{
	GP_WRAP_START;
	{
		return DatumGetUInt32(DirectFunctionCall1(hashname, d));
	}
	GP_WRAP_END;
}

uint32
gpdb::UUIDHash(Datum d)
{
	GP_WRAP_START;
	{
		return DatumGetUInt32(DirectFunctionCall1(uuid_hash, d));
	}
	GP_WRAP_END;
}

void *
gpdb::GPDBMemoryContextAlloc(MemoryContext context, Size size)
{
	GP_WRAP_START;
	{
		return MemoryContextAlloc(context, size);
	}
	GP_WRAP_END;
	return nullptr;
}

void
gpdb::GPDBMemoryContextDelete(MemoryContext context)
{
	GP_WRAP_START;
	{
		MemoryContextDelete(context);
	}
	GP_WRAP_END;
}

MemoryContext
gpdb::GPDBAllocSetContextCreate()
{
	GP_WRAP_START;
	{
		MemoryContext cxt;

		cxt =
			AllocSetContextCreate(OptimizerMemoryContext, "GPORCA memory pool",
								  ALLOCSET_DEFAULT_SIZES);
		/*
		 * Declare it as accounting root so that we can call
		 * MemoryContextGetCurrentSpace() on it.
		 */
		MemoryContextDeclareAccountingRoot(cxt);

		return cxt;
	}
	GP_WRAP_END;
	return nullptr;
}

bool
gpdb::ExpressionReturnsSet(Node *clause)
{
	GP_WRAP_START;
	{
		return expression_returns_set(clause);
	}
	GP_WRAP_END;
}

List *
gpdb::GetRelChildIndexes(Oid reloid)
{
	List *partoids = NIL;
	GP_WRAP_START;
	{
		if (InvalidOid == reloid)
		{
			return NIL;
		}
		partoids = find_inheritance_children(reloid, NoLock);
	}
	GP_WRAP_END;

	return partoids;
}

Oid
gpdb::GetForeignServerId(Oid reloid)
{
	GP_WRAP_START;
	{
		return GetForeignServerIdByRelId(reloid);
	}
	GP_WRAP_END;
	return 0;
}

int16
gpdb::GetAppendOnlySegmentFilesCount(Relation rel)
{
	GP_WRAP_START;
	{
		FormData_pg_appendonly aoFormData;
		GetAppendOnlyEntry(rel, &aoFormData);
		return aoFormData.segfilecount;
	}
	GP_WRAP_END;
	return -1;
}

// Locks on partition leafs and indexes are held during optimizer (after
// parse-analyze stage). ORCA need this function to lock relation. Here
// we do not need to consider lock-upgrade issue, reasons are:
//   1. Only UPDATE|DELETE statement may upgrade lock level
//   2. ORCA currently does not support DML on partition tables
//   3. If not partition table, then parser should have already locked
//   4. Even later ORCA support DML on partition tables, the lock mode
//      of leafs should be the same as the mode in root's RTE's rellockmode
//   5. Index does not have lock-upgrade problem.
void
gpdb::GPDBLockRelationOid(Oid reloid, LOCKMODE lockmode)
{
	GP_WRAP_START;
	{
		LockRelationOid(reloid, lockmode);
	}
	GP_WRAP_END;
}

char *
gpdb::GetRelFdwName(Oid reloid)
{
	GP_WRAP_START;
	{
		Oid fs_id = GetForeignServerIdByRelId(reloid);
		ForeignServer *fs = GetForeignServer(fs_id);
		ForeignDataWrapper *fdw = GetForeignDataWrapper(fs->fdwid);
		return fdw->fdwname;
	}
	GP_WRAP_END;
	return nullptr;
}

PathTarget *
gpdb::MakePathtargetFromTlist(List *tlist)
{
	GP_WRAP_START;
	{
		return make_pathtarget_from_tlist(tlist);
	}
	GP_WRAP_END;
}

void
gpdb::SplitPathtargetAtSrfs(PlannerInfo *root, PathTarget *target,
							PathTarget *input_target, List **targets,
							List **targets_contain_srfs)
{
	GP_WRAP_START;
	{
		split_pathtarget_at_srfs(root, target, input_target, targets,
								 targets_contain_srfs);
	}
	GP_WRAP_END;
}

List *
gpdb::MakeTlistFromPathtarget(PathTarget *target)
{
	GP_WRAP_START;
	{
		return make_tlist_from_pathtarget(target);
	}
	GP_WRAP_END;
	return NIL;
}

Node *
gpdb::Expression_tree_mutator(Node *node, Node *(*mutator)(Node*, void*), void *context)
{
	GP_WRAP_START;
	{
		return expression_tree_mutator_wrapper(node, mutator, context);
	}
	GP_WRAP_END;

	return nullptr;
}

TargetEntry *
gpdb::TlistMember(Expr *node, List *targetlist)
{
	GP_WRAP_START;
	{
		return tlist_member(node, targetlist);
	}
	GP_WRAP_END;

	return nullptr;
}

Var *
gpdb::MakeVarFromTargetEntry(Index varno, TargetEntry *tle)
{
	GP_WRAP_START;
	{
		return makeVarFromTargetEntry(varno, tle);
	}
	GP_WRAP_END;
}

TargetEntry *
gpdb::FlatCopyTargetEntry(TargetEntry *src_tle)
{
	GP_WRAP_START;
	{
		return flatCopyTargetEntry(src_tle);
	}
	GP_WRAP_END;
}


// Returns true if type is a RANGE
// pg_type (typtype = 'r')
bool
gpdb::IsTypeRange(Oid typid)
{
	GP_WRAP_START;
	{
		return type_is_range(typid);
	}
	GP_WRAP_END;
	return false;
}

char *
gpdb::GetRelAmName(Oid reloid)
{
	GP_WRAP_START;
	{
		return GetAmName(reloid);
	}
	GP_WRAP_END;
	return nullptr;
}

// Get IndexAmRoutine struct for the given access method handler.
IndexAmRoutine *
gpdb::GetIndexAmRoutineFromAmHandler(Oid am_handler)
{
	GP_WRAP_START;
	{
		return GetIndexAmRoutine(am_handler);
	}
	GP_WRAP_END;
}

bool
gpdb::TestexprIsHashable(Node *testexpr, List *param_ids)
{
	GP_WRAP_START;
	{
		return testexpr_is_hashable(testexpr, param_ids);
	}
	GP_WRAP_END;
	return false;
}

// check if parallel mode is OK (comprehensive check)
bool
gpdb::IsParallelModeOK(void)
{
	GP_WRAP_START;
	{
		if (!enable_parallel)
			return false;

		if (IS_SINGLENODE())
			return false;

		if (max_parallel_workers_per_gather <= 0)
			return false;

		// Check if parallel plans are enabled in current optimizer context
		gpopt::COptCtxt *poctxt = gpopt::COptCtxt::PoctxtFromTLS();
		if (nullptr != poctxt)
		{
			gpopt::COptimizerConfig *optimizer_config = poctxt->GetOptimizerConfig();
			if (nullptr != optimizer_config)
			{
				if (!optimizer_config->CreateParallelPlan())
					return false;
			}
		}
		return true;
	}
	GP_WRAP_END;
	return false;  // default to disabled if no context
}

// EOF
