/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*-------------------------------------------------------------------------
 *
 * lsyscache.c
 *	  Convenience routines for common queries in the system catalog cache.
 *
 * Portions Copyright (c) 2007-2009, Greenplum inc
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.138.2.1 2007/03/19 16:30:40 tgl Exp $
 *
 * NOTES
 *	  Eventually, the index information should go through here, too.
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/hash.h"
#include "access/genam.h" 
#include "bootstrap/bootstrap.h"
#include "catalog/catquery.h"
#include "catalog/heap.h"                   /* SystemAttributeDefinition() */  
#include "catalog/pg_authid.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "cdb/cdbpartition.h"
#include "commands/tablecmds.h"
#include "commands/trigger.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_clause.h"			/* for sort_op_can_sort() */
#include "parser/parse_coerce.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/fmgroids.h"
#include "funcapi.h"

static Datum
attstatsslot_getattr(cqContext	*pcqCtx, 
					 TupleDesc	 tupdesc,
					 HeapTuple	 statstuple,
					 AttrNumber	 attnum, bool *isnull);



/*				---------- AMOP CACHES ----------						 */

/*
 * op_in_opclass
 *
 *		Return t iff operator 'opno' is in operator class 'opclass'.
 */
bool
op_in_opclass(Oid opno, Oid opclass)
{
	return (caql_getcount(
					NULL,
					cql("SELECT COUNT(*) FROM pg_amop "
						" WHERE amopopr = :1 "
						" AND amopclaid = :2 ",
						ObjectIdGetDatum(opno),
						ObjectIdGetDatum(opclass))) > 0);
}

/*
 * get_op_opclass_strategy
 *
 *		Get the operator's strategy number within the specified opclass,
 *		or 0 if it's not a member of the opclass.
 */
int
get_op_opclass_strategy(Oid opno, Oid opclass)
{
	HeapTuple	tp;
	Form_pg_amop amop_tup;
	int			result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_amop "
				" WHERE amopopr = :1 "
				" AND amopclaid = :2 ",
				ObjectIdGetDatum(opno),
				ObjectIdGetDatum(opclass)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		return 0;
	amop_tup = (Form_pg_amop) GETSTRUCT(tp);
	result = amop_tup->amopstrategy;

	caql_endscan(pcqCtx);

	return result;
}

/*
 * get_op_opclass_properties
 *
 *		Get the operator's strategy number, subtype, and recheck (lossy) flag
 *		within the specified opclass.
 *
 * Caller should already have verified that opno is a member of opclass,
 * therefore we raise an error if the tuple is not found.
 */
void
get_op_opclass_properties(Oid opno, Oid opclass,
						  int *strategy, Oid *subtype, bool *recheck)
{
	HeapTuple	tp;
	Form_pg_amop amop_tup;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_amop "
				" WHERE amopopr = :1 "
				" AND amopclaid = :2 ",
				ObjectIdGetDatum(opno),
				ObjectIdGetDatum(opclass)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "operator %u is not a member of opclass %u",
			 opno, opclass);
	amop_tup = (Form_pg_amop) GETSTRUCT(tp);
	*strategy = amop_tup->amopstrategy;
	*subtype = amop_tup->amopsubtype;
	*recheck = amop_tup->amopreqcheck;

	caql_endscan(pcqCtx);
}

/*
 * get_opclass_member
 *		Get the OID of the operator that implements the specified strategy
 *		with the specified subtype for the specified opclass.
 *
 * Returns InvalidOid if there is no pg_amop entry for the given keys.
 */
Oid
get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
{
	Oid			result;
	int			fetchCount;

	result  = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT amopopr FROM pg_amop "
				" WHERE amopclaid = :1 "
				" AND amopsubtype = :2 "
				" AND amopstrategy = :3 ",
				ObjectIdGetDatum(opclass),
				ObjectIdGetDatum(subtype),
				Int16GetDatum(strategy)
					));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_op_hash_function
 *		Get the OID of the datatype-specific hash function associated with
 *		a hashable equality operator.
 *
 * Returns InvalidOid if no hash function can be found.  (This indicates
 * that the operator should not have been marked oprcanhash.)
 */
Oid
get_op_hash_function(Oid opno)
{
	CatCList   *catlist;
	int			i;
	Oid			opclass = InvalidOid;

	/*
	 * Search pg_amop to see if the target operator is registered as the "="
	 * operator of any hash opclass.  If the operator is registered in
	 * multiple opclasses, assume we can use the associated hash function from
	 * any one.
	 */
	catlist = caql_begin_CacheList(
			NULL,
			cql("SELECT * FROM pg_amop "
				" WHERE amopopr = :1 "
				" ORDER BY amopopr, "
				" amopclaid ",
				ObjectIdGetDatum(opno)));

	for (i = 0; i < catlist->n_members; i++)
	{
		HeapTuple	tuple = &catlist->members[i]->tuple;
		Form_pg_amop aform = (Form_pg_amop) GETSTRUCT(tuple);

		if (aform->amopstrategy == HTEqualStrategyNumber &&
			opclass_is_hash(aform->amopclaid))
		{
			opclass = aform->amopclaid;
			break;
		}
	}

	caql_end_CacheList(catlist);

	if (OidIsValid(opclass))
	{
		/* Found a suitable opclass, get its default hash support function */
		return get_opclass_proc(opclass, InvalidOid, HASHPROC);
	}

	/* Didn't find a match... */
	return InvalidOid;
}

/*
 * get_op_btree_interpretation
 *		Given an operator's OID, find out which btree opclasses it belongs to,
 *		and what strategy number it has within each one.  The results are
 *		returned as an OID list and a parallel integer list.
 *
 * In addition to the normal btree operators, we consider a <> operator to be
 * a "member" of an opclass if its negator is the opclass' equality operator.
 * ROWCOMPARE_NE is returned as the strategy number for this case.
 */
void
get_op_btree_interpretation(Oid opno, List **opclasses, List **opstrats)
{
	Oid			lefttype,
				righttype;
	CatCList   *catlist;
	bool		op_negated;
	int			i;

	*opclasses = NIL;
	*opstrats = NIL;

	/*
	 * Get the nominal left-hand input type of the operator; we will ignore
	 * opclasses that don't have that as the expected input datatype.  This is
	 * a kluge to avoid being confused by binary-compatible opclasses (such as
	 * text_ops and varchar_ops, which share the same operators).
	 */
	op_input_types(opno, &lefttype, &righttype);
	Assert(OidIsValid(lefttype));

	/*
	 * Find all the pg_amop entries containing the operator.
	 */

	catlist = caql_begin_CacheList(
			NULL,
			cql("SELECT * FROM pg_amop "
				" WHERE amopopr = :1 "
				" ORDER BY amopopr, "
				" amopclaid ",
				ObjectIdGetDatum(opno)));

	/*
	 * If we can't find any opclass containing the op, perhaps it is a <>
	 * operator.  See if it has a negator that is in an opclass.
	 */
	op_negated = false;
	if (catlist->n_members == 0)
	{
		Oid			op_negator = get_negator(opno);

		if (OidIsValid(op_negator))
		{
			op_negated = true;
			caql_end_CacheList(catlist);

			catlist = caql_begin_CacheList(
					NULL,
					cql("SELECT * FROM pg_amop "
						" WHERE amopopr = :1 "
						" ORDER BY amopopr, "
						" amopclaid ",
						ObjectIdGetDatum(op_negator)));
		}
	}

	/* Now search the opclasses */
	for (i = 0; i < catlist->n_members; i++)
	{
		HeapTuple	op_tuple = &catlist->members[i]->tuple;
		Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
		Oid			opclass_id;
		StrategyNumber op_strategy;

		opclass_id = op_form->amopclaid;

		/* must be btree */
		if (!opclass_is_btree(opclass_id))
			continue;

		/* must match operator input type exactly */
		if (get_opclass_input_type(opclass_id) != lefttype)
			continue;

		/* Get the operator's btree strategy number */
		op_strategy = (StrategyNumber) op_form->amopstrategy;
		Assert(op_strategy >= 1 && op_strategy <= 5);

		if (op_negated)
		{
			/* Only consider negators that are = */
			if (op_strategy != BTEqualStrategyNumber)
				continue;
			op_strategy = ROWCOMPARE_NE;
		}

		*opclasses = lappend_oid(*opclasses, opclass_id);
		*opstrats = lappend_int(*opstrats, op_strategy);
	}

	caql_end_CacheList(catlist);
}


/*				---------- AMPROC CACHES ----------						 */

/*
 * get_opclass_proc
 *		Get the OID of the specified support function
 *		for the specified opclass and subtype.
 *
 * Returns InvalidOid if there is no pg_amproc entry for the given keys.
 */
Oid
get_opclass_proc(Oid opclass, Oid subtype, int16 procnum)
{
	Oid			result;
	int			fetchCount;

	result  = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT amproc FROM pg_amproc "
				" WHERE amopclaid = :1 "
				" AND amprocsubtype = :2 "
				" AND amprocnum = :3 ",
				ObjectIdGetDatum(opclass),
				ObjectIdGetDatum(subtype),
				Int16GetDatum(procnum)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}


/*				---------- ATTRIBUTE CACHES ----------					 */

/*
 * get_attname
 *		Given the relation id and the attribute number,
 *		return the "attname" field from the attribute relation.
 *
 * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
 */
char *
get_attname(Oid relid, AttrNumber attnum)
{
	char	   *result = NULL;
	int			fetchCount;

	result = caql_getcstring_plus(
					NULL,
					&fetchCount,
					NULL,
					cql("SELECT attname FROM pg_attribute "
						" WHERE attrelid = :1 "
						" AND attnum = :2 ",
						ObjectIdGetDatum(relid),
						Int16GetDatum(attnum)));
	
	if (!fetchCount)
		return NULL;

	return result;
}

/*
 * get_relid_attribute_name
 *
 * Same as above routine get_attname(), except that error
 * is handled by elog() instead of returning NULL.
 */
char *
get_relid_attribute_name(Oid relid, AttrNumber attnum)
{
	char	   *attname;

	attname = get_attname(relid, attnum);
	if (attname == NULL)
		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
			 attnum, relid);
	return attname;
}

/*
 * get_attnum
 *
 *		Given the relation id and the attribute name,
 *		return the "attnum" field from the attribute relation.
 *
 *		Returns InvalidAttrNumber if the attr doesn't exist (or is dropped).
 */
AttrNumber
get_attnum(Oid relid, const char *attname)
{
	return caql_getattnumber(relid, attname);
}

/*
 * get_atttype
 *
 *		Given the relation OID and the attribute number with the relation,
 *		return the attribute type OID.
 */
Oid
get_atttype(Oid relid, AttrNumber attnum)
{
	Oid			result;
	int			fetchCount;

	result  = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT atttypid FROM pg_attribute "
				" WHERE attrelid = :1 "
				" AND attnum = :2 ",
				ObjectIdGetDatum(relid),
				Int16GetDatum(attnum)));

	if (!fetchCount)
		return InvalidOid;

	return result;

}

/*
 * get_atttypmod
 *
 *		Given the relation id and the attribute number,
 *		return the "atttypmod" field from the attribute relation.
 */
int32
get_atttypmod(Oid relid, AttrNumber attnum)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	int32		result = -1;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_attribute "
				" WHERE attrelid = :1 "
				" AND attnum = :2 ",
				ObjectIdGetDatum(relid),
				Int16GetDatum(attnum)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);

		result = att_tup->atttypmod;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_atttypetypmod
 *
 *		A two-fer: given the relation id and the attribute number,
 *		fetch both type OID and atttypmod in a single cache lookup.
 *
 * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine
 * raises an error if it can't obtain the information.
 */
void
get_atttypetypmod(Oid relid, AttrNumber attnum,
				  Oid *typid, int32 *typmod)
{
	HeapTuple	tp;
	Form_pg_attribute att_tup;
	cqContext  *pcqCtx;

    /* CDB: Get type for sysattr even if relid is no good (e.g. SubqueryScan) */
    if (attnum < 0 &&
        attnum > FirstLowInvalidHeapAttributeNumber)
    {
        att_tup = SystemAttributeDefinition(attnum, true);
	    *typid = att_tup->atttypid;
	    *typmod = att_tup->atttypmod;
        return;
    }

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_attribute "
				" WHERE attrelid = :1 "
				" AND attnum = :2 ",
				ObjectIdGetDatum(relid),
				Int16GetDatum(attnum)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for attribute %d of relation %u",
			 attnum, relid);
	att_tup = (Form_pg_attribute) GETSTRUCT(tp);

	*typid = att_tup->atttypid;
	*typmod = att_tup->atttypmod;

	caql_endscan(pcqCtx);
}

/*				---------- INDEX CACHE ----------						 */

/*		watch this space...
 */

/*				---------- OPCLASS CACHE ----------						 */

/*
 * opclass_is_btree
 *
 *		Returns TRUE iff the specified opclass is associated with the
 *		btree index access method.
 */
bool
opclass_is_btree(Oid opclass)
{
	bool		result;
	Oid			amoid;
	int			fetchCount;

	amoid = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT opcamid FROM pg_opclass "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opclass)));

	if (!fetchCount)
		elog(ERROR, "cache lookup failed for opclass %u", opclass);

	result = (amoid == BTREE_AM_OID);

	return result;
}

/*
 * opclass_is_hash
 *
 *		Returns TRUE iff the specified opclass is associated with the
 *		hash index access method.
 */
bool
opclass_is_hash(Oid opclass)
{
	bool		result;
	Oid			amoid;
	int			fetchCount;

	amoid = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT opcamid FROM pg_opclass "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opclass)));

	if (!fetchCount)
		elog(ERROR, "cache lookup failed for opclass %u", opclass);

	result = (amoid == HASH_AM_OID);

	return result;
}

/*
 * opclass_is_default
 *
 *		Returns TRUE iff the specified opclass is the default for its
 *		index access method and input data type.
 */
bool
opclass_is_default(Oid opclass)
{
	HeapTuple	tp;
	Form_pg_opclass cla_tup;
	bool		result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_opclass "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opclass)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for opclass %u", opclass);
	cla_tup = (Form_pg_opclass) GETSTRUCT(tp);

	result = cla_tup->opcdefault;

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_opclass_input_type
 *
 *		Returns the OID of the datatype the opclass indexes.
 */
Oid
get_opclass_input_type(Oid opclass)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT opcintype FROM pg_opclass "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opclass)));
	
	if (!fetchCount)
		elog(ERROR, "cache lookup failed for opclass %u", opclass);

	return result;
}

/*				---------- OPERATOR CACHE ----------					 */

/*
 * get_opcode
 *
 *		Returns the regproc id of the routine used to implement an
 *		operator given the operator oid.
 */
RegProcedure
get_opcode(Oid opno)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oprcode FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	if (!fetchCount)
		return (RegProcedure) InvalidOid;

	return (RegProcedure) result;
}

/*
 * get_opname
 *	  returns the name of the operator with the given opno
 *
 * Note: returns a palloc'd copy of the string, or NULL if no such operator.
 */
char *
get_opname(Oid opno)
{
	char	   *result = NULL;
	int			fetchCount;

	result = caql_getcstring_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oprname FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	if (!fetchCount)
		return NULL;

	return result;
}

/*
 * op_input_types
 *
 *		Returns the left and right input datatypes for an operator
 *		(InvalidOid if not relevant).
 */
void
op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
{
	HeapTuple	tp;
	Form_pg_operator optup;
	cqContext  *pcqCtx;

	*lefttype = InvalidOid;
	*righttype = InvalidOid;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		optup = (Form_pg_operator) GETSTRUCT(tp);
		*lefttype = optup->oprleft;
		*righttype = optup->oprright;
	}
	caql_endscan(pcqCtx);
}

/*
 * op_mergejoinable
 *
 *		Returns the left and right sort operators corresponding to a
 *		mergejoinable operator, or false if the operator is not mergejoinable.
 */
bool
op_mergejoinable(Oid opno, Oid *leftOp, Oid *rightOp)
{
	HeapTuple	tp;
	bool		result = false;
	cqContext  *pcqCtx;

	if (!sort_op_can_sort(opno, true))
		return result;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);

		if (optup->oprlsortop &&
			optup->oprrsortop)
		{
			*leftOp = optup->oprlsortop;
			*rightOp = optup->oprrsortop;
			result = true;
		}
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * op_mergejoin_crossops
 *
 *		Returns the cross-type comparison operators (ltype "<" rtype and
 *		ltype ">" rtype) for an operator previously determined to be
 *		mergejoinable.	Optionally, fetches the regproc ids of these
 *		operators, as well as their operator OIDs.
 */
void
op_mergejoin_crossops(Oid opno, Oid *ltop, Oid *gtop,
					  RegProcedure *ltproc, RegProcedure *gtproc)
{
	HeapTuple	tp;
	Form_pg_operator optup;
	cqContext  *pcqCtx;

	/*
	 * Get the declared comparison operators of the operator.
	 */
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))	/* shouldn't happen */
		elog(ERROR, "cache lookup failed for operator %u", opno);
	optup = (Form_pg_operator) GETSTRUCT(tp);
	*ltop = optup->oprltcmpop;
	*gtop = optup->oprgtcmpop;

	caql_endscan(pcqCtx);

	/* Check < op provided */
	if (!OidIsValid(*ltop))
		elog(ERROR, "mergejoin operator %u has no matching < operator",
			 opno);
	if (ltproc)
		*ltproc = get_opcode(*ltop);

	/* Check > op provided */
	if (!OidIsValid(*gtop))
		elog(ERROR, "mergejoin operator %u has no matching > operator",
			 opno);
	if (gtproc)
		*gtproc = get_opcode(*gtop);
}

/*
 * op_hashjoinable
 *
 * Returns true if the operator is hashjoinable.
 */
bool
op_hashjoinable(Oid opno)
{
	HeapTuple	tp;
	bool		result = false;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_operator optup = (Form_pg_operator) GETSTRUCT(tp);

		result = optup->oprcanhash;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * op_strict
 *
 * Get the proisstrict flag for the operator's underlying function.
 */
bool
op_strict(Oid opno)
{
	RegProcedure funcid = get_opcode(opno);

	if (funcid == (RegProcedure) InvalidOid)
		elog(ERROR, "operator %u does not exist", opno);

	return func_strict((Oid) funcid);
}

/*
 * op_volatile
 *
 * Get the provolatile flag for the operator's underlying function.
 */
char
op_volatile(Oid opno)
{
	RegProcedure funcid = get_opcode(opno);

	if (funcid == (RegProcedure) InvalidOid)
		elog(ERROR, "operator %u does not exist", opno);

	return func_volatile((Oid) funcid);
}

/*
 * get_commutator
 *
 *		Returns the corresponding commutator of an operator.
 */
Oid
get_commutator(Oid opno)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oprcom FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_negator
 *
 *		Returns the corresponding negator of an operator.
 */
Oid
get_negator(Oid opno)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oprnegate FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_oprrest
 *
 *		Returns procedure id for computing selectivity of an operator.
 */
RegProcedure
get_oprrest(Oid opno)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oprrest FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	if (!fetchCount)
		return (RegProcedure) InvalidOid;

	return (RegProcedure) result;
}

/*
 * get_oprjoin
 *
 *		Returns procedure id for computing selectivity of a join.
 */
RegProcedure
get_oprjoin(Oid opno)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oprjoin FROM pg_operator "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(opno)));

	if (!fetchCount)
		return (RegProcedure) InvalidOid;

	return (RegProcedure) result;
}

/*				---------- TRIGGER CACHE ----------					 */

/*
 * get_trigger_name
 *	  returns the name of the trigger with the given triggerid
 *
 * Note: returns a palloc'd copy of the string, or NULL if no such trigger
 */
char *
get_trigger_name(Oid triggerid)
{
	char	   *result = NULL;
	int			fetchCount;

	result = caql_getcstring_plus(
					NULL,
					&fetchCount,
					NULL,
					cql("SELECT tgname FROM pg_trigger "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(triggerid)));

	if (!fetchCount)
		return NULL;

	return result;
}

/*
 * get_trigger_relid
 *		Given trigger id, return the trigger's relation oid
 */
Oid
get_trigger_relid(Oid triggerid)
{
	Oid			result;
	int			fetchCount;

	result  = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT tgrelid FROM pg_trigger "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(triggerid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_trigger_funcid
 *		Given trigger id, return the trigger's function oid
 */
Oid
get_trigger_funcid(Oid triggerid)
{
	Oid			result;
	int			fetchCount;

	result  = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT tgfoid FROM pg_trigger "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(triggerid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_trigger_type
 *		Given trigger id, return the trigger's type
 */
int32
get_trigger_type(Oid triggerid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	int32		result = -1;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_trigger "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(triggerid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for trigger %u", triggerid);

	result = ((Form_pg_trigger) GETSTRUCT(tp))->tgtype;

	caql_endscan(pcqCtx);
	return result;
}

/*
 * trigger_enabled
 *		Given trigger id, return the trigger's enabled flag
 */
bool
trigger_enabled(Oid triggerid)
{
	HeapTuple	tp;
	bool		result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_trigger "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(triggerid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for trigger %u", triggerid);

	result = ((Form_pg_trigger) GETSTRUCT(tp))->tgenabled;

	caql_endscan(pcqCtx);
	return result;
}

/*				---------- FUNCTION CACHE ----------					 */

/*
 * get_func_name
 *	  returns the name of the function with the given funcid
 *
 * Note: returns a palloc'd copy of the string, or NULL if no such function.
 */
char *
get_func_name(Oid funcid)
{
	char	   *result = NULL;
	int			fetchCount;

	result = caql_getcstring_plus(
					NULL,
					&fetchCount,
					NULL,
					cql("SELECT proname FROM pg_proc "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(funcid)));

	if (!fetchCount)
		return NULL;

	return result;
}

/*
 * get_type_name
 *	  returns the name of the type with the given oid
 *
 * Note: returns a palloc'd copy of the string, or NULL if no such type.
 */
char *
get_type_name(Oid oid)
{
       char       *result = NULL;
        int                     fetchCount;

        result = caql_getcstring_plus(
                                        NULL,
                                        &fetchCount,
                                        NULL,
                                        cql("SELECT typname FROM pg_type "
                                                " WHERE oid = :1 ",
                                                ObjectIdGetDatum(oid)));

        if (!fetchCount)
                return NULL;

        return result;
}
 
/*
 * get_func_namespace
 *		Returns the pg_namespace OID associated with a given procedure.
 *
 */
Oid
get_func_namespace(Oid funcid)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT pronamespace FROM pg_proc "
				 " WHERE oid = :1 ",
				 ObjectIdGetDatum(funcid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_func_rettype
 *		Given procedure id, return the function's result type.
 */
Oid
get_func_rettype(Oid funcid)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT prorettype FROM pg_proc "
				 " WHERE oid = :1 ",
				 ObjectIdGetDatum(funcid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_agg_transtype
 *		Given aggregate id, return the aggregate transition function's result type.
 */
Oid
get_agg_transtype(Oid aggid)
{
        Oid                     result;
        int                     fetchCount;

        result = caql_getoid_plus(
                        NULL,
                        &fetchCount,
                        NULL,
                        cql("SELECT aggtranstype FROM pg_aggregate "
                                 " WHERE aggfnoid = :1 ",
                                 ObjectIdGetDatum(aggid)));

        if (!fetchCount)
                elog(ERROR, "cache lookup failed for aggregate %u", aggid);

        return result;
}

/*
 * is_ordered_agg
 *		Given aggregate id, check if it is an ordered aggregate
 */
bool
is_agg_ordered(Oid aggid)
{
	Relation aggRelation = heap_open(AggregateRelationId, AccessShareLock);
	cqContext	cqc;
	HeapTuple aggTuple = caql_getfirst(
			caql_addrel(cqclr(&cqc), aggRelation),
			cql("SELECT * from pg_aggregate"
				" WHERE aggfnoid = :1",
				ObjectIdGetDatum(aggid)));

	if (!HeapTupleIsValid(aggTuple))
	{
		elog(ERROR, "cache lookup failed for aggregate %u", aggid);
	}

	bool isnull = false;
	bool is_ordered = false;
	is_ordered = DatumGetBool(heap_getattr(aggTuple, Anum_pg_aggregate_aggordered, RelationGetDescr(aggRelation), &isnull));

	heap_freetuple(aggTuple);
	heap_close(aggRelation, AccessShareLock);

	Assert(!isnull);

	return is_ordered;
}

/*
 * has_agg_prelimfunc
 *		Given aggregate id, check if it is has a prelim function
 */
bool has_agg_prelimfunc(Oid aggid)
{
	Relation aggRelation = heap_open(AggregateRelationId, AccessShareLock);
	cqContext	cqc;
	HeapTuple aggTuple = caql_getfirst(
			caql_addrel(cqclr(&cqc), aggRelation),
			cql("SELECT * from pg_aggregate"
				" WHERE aggfnoid = :1",
				ObjectIdGetDatum(aggid)));

	if (!HeapTupleIsValid(aggTuple))
	{
		elog(ERROR, "cache lookup failed for aggregate %u", aggid);
	}

	Form_pg_aggregate aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
	bool has_prelimfunc = (InvalidOid != aggform->aggprelimfn);
	
	heap_freetuple(aggTuple);
	heap_close(aggRelation, AccessShareLock);

	return has_prelimfunc;
}


/*
 * agg_has_prelim_or_invprelim_func
 *		Given aggregate id, check if it is has a prelim or inverse prelim function
 */
bool agg_has_prelim_or_invprelim_func(Oid aggid)
{
	Relation aggRelation = heap_open(AggregateRelationId, AccessShareLock);
	cqContext	cqc;
	HeapTuple aggTuple = caql_getfirst(
			caql_addrel(cqclr(&cqc), aggRelation),
			cql("SELECT * from pg_aggregate"
				" WHERE aggfnoid = :1",
				ObjectIdGetDatum(aggid)));

	if (!HeapTupleIsValid(aggTuple))
	{
		elog(ERROR, "cache lookup failed for aggregate %u", aggid);
	}

	Form_pg_aggregate aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
	bool has_prelimfunc = (InvalidOid != aggform->aggprelimfn);
	bool has_invprelimfunc = (InvalidOid != aggform->agginvprelimfn);

	heap_freetuple(aggTuple);
	heap_close(aggRelation, AccessShareLock);

	return has_prelimfunc || has_invprelimfunc;
}


/*
 * get_func_nargs
 *		Given procedure id, return the number of arguments.
 */
int
get_func_nargs(Oid funcid)
{
       HeapTuple       tp;
        int                     result;
        cqContext  *pcqCtx;

        pcqCtx = caql_beginscan(
                        NULL,
                        cql("SELECT * FROM pg_proc "
                                " WHERE oid = :1 ",
                                ObjectIdGetDatum(funcid)));

        tp = caql_getnext(pcqCtx);

        if (!HeapTupleIsValid(tp))
                elog(ERROR, "cache lookup failed for function %u", funcid);

        result = ((Form_pg_proc) GETSTRUCT(tp))->pronargs;

        caql_endscan(pcqCtx);
        return result;
}

/*
 * get_func_signature
 *		Given procedure id, return the function's argument and result types.
 *		(The return value is the result type.)
 *
 * The arguments are returned as a palloc'd array.
 */
Oid
get_func_signature(Oid funcid, Oid **argtypes, int *nargs)
{
	HeapTuple	tp;
	Form_pg_proc procstruct;
	Oid			result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(funcid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);

	procstruct = (Form_pg_proc) GETSTRUCT(tp);

	result = procstruct->prorettype;
	*nargs = (int) procstruct->pronargs;
	Assert(*nargs == procstruct->proargtypes.dim1);
	*argtypes = (Oid *) palloc(*nargs * sizeof(Oid));
	memcpy(*argtypes, procstruct->proargtypes.values, *nargs * sizeof(Oid));

	caql_endscan(pcqCtx);
	return result;
}

/*
 * pfree_ptr_array
 * 		Free an array of pointers, after freeing each individual element
 */
void
pfree_ptr_array(char **ptrarray, int nelements)
{
	int i;
	if (NULL == ptrarray)
		return;

	for (i = 0; i < nelements; i++)
	{
		if (NULL != ptrarray[i])
		{
			pfree(ptrarray[i]);
		}
	}
	pfree(ptrarray);
}

/*
 * get_func_output_arg_types
 *		Given procedure id, return the function's output argument types
 */
List *
get_func_output_arg_types(Oid funcid)
{
        HeapTuple       tp;
        int             numargs;
        Oid             *argtypes = NULL;
        char    **argnames = NULL;
        char    *argmodes = NULL;
        List    *l_argtypes = NIL;
        int             i;
        cqContext  *pcqCtx;

        pcqCtx = caql_beginscan(
                        NULL,
                        cql("SELECT * FROM pg_proc "
                                " WHERE oid = :1 ",
                                ObjectIdGetDatum(funcid)));

        tp = caql_getnext(pcqCtx);

        if (!HeapTupleIsValid(tp))
                elog(ERROR, "cache lookup failed for function %u", funcid);

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

        if (NULL == argmodes)
        {
                pfree_ptr_array(argnames, numargs);
                if (NULL != argtypes)
                {
                        pfree(argtypes);
                }
                caql_endscan(pcqCtx);
                return NULL;
        }

        for (i = 0; i < numargs; i++)
        {
                Oid argtype = argtypes[i];
                char argmode = argmodes[i];

                if (PROARGMODE_INOUT == argmode || PROARGMODE_OUT == argmode || PROARGMODE_TABLE == argmode)
                {
                        l_argtypes = lappend_oid(l_argtypes, argtype);
                }
        }

        pfree_ptr_array(argnames, numargs);
        pfree(argtypes);
        pfree(argmodes);

        caql_endscan(pcqCtx);
        return l_argtypes;
}

/*
 * get_func_arg_types
 *		Given procedure id, return all the function's argument types
 */
List *
get_func_arg_types(Oid funcid)
{
	cqContext *pcqCtx = caql_beginscan(
							NULL,
							cql("SELECT * FROM pg_proc "
								" WHERE oid = :1 ",
								ObjectIdGetDatum(funcid)));

	HeapTuple tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);

	oidvector args = ((Form_pg_proc) GETSTRUCT(tp))->proargtypes;
	List *result = NIL;
	for (int i = 0; i < args.dim1; i++)
	{
		result = lappend_oid(result, args.values[i]);
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_func_retset
 *		Given procedure id, return the function's proretset flag.
 */
bool
get_func_retset(Oid funcid)
{
	HeapTuple	tp;
	bool		result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(funcid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);

	result = ((Form_pg_proc) GETSTRUCT(tp))->proretset;

	caql_endscan(pcqCtx);
	return result;
}

/*
 * func_strict
 *		Given procedure id, return the function's proisstrict flag.
 */
bool
func_strict(Oid funcid)
{
	HeapTuple	tp;
	bool		result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(funcid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);

	result = ((Form_pg_proc) GETSTRUCT(tp))->proisstrict;

	caql_endscan(pcqCtx);
	return result;
}

/*
 * func_volatile
 *		Given procedure id, return the function's provolatile flag.
 */
char
func_volatile(Oid funcid)
{
	HeapTuple	tp;
	char		result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(funcid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);

	result = ((Form_pg_proc) GETSTRUCT(tp))->provolatile;

	caql_endscan(pcqCtx);
	return result;
}

/*
 * func_data_access
 *		Given procedure id, return the function's data access flag.
 */
char
func_data_access(Oid funcid)
{
	SQLDataAccess sda = GetFuncSQLDataAccess(funcid);
	switch (sda)
	{
		case SDA_NO_SQL:
			return PRODATAACCESS_NONE;
		case SDA_CONTAINS_SQL:
			return PRODATAACCESS_CONTAINS;
		case SDA_READS_SQL:
			return PRODATAACCESS_READS;
		case SDA_MODIFIES_SQL:
			return PRODATAACCESS_MODIFIES;
		default:
			elog(ERROR, "cache lookup failed for function %u", funcid);
			return '\0';
	}
}

/*				---------- RELATION CACHE ----------					 */

/*
 * get_relname_relid
 *		Given name and namespace of a relation, look up the OID.
 *
 * Returns InvalidOid if there is no such relation.
 */
Oid
get_relname_relid(const char *relname, Oid relnamespace)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT oid FROM pg_class "
				" WHERE relname = :1 "
				" AND relnamespace = :2 ",
				PointerGetDatum((char *) relname),
				ObjectIdGetDatum(relnamespace)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_relnatts
 *
 *		Returns the number of attributes for a given relation.
 */
int
get_relnatts(Oid relid)
{
	HeapTuple	tp;
	int			result = InvalidAttrNumber;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);

		result = reltup->relnatts;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_rel_name
 *		Returns the name of a given relation.
 *
 * Returns a palloc'd copy of the string, or NULL if no such relation.
 *
 * NOTE: since relation name is not unique, be wary of code that uses this
 * for anything except preparing error messages.
 */
char *
get_rel_name(Oid relid)
{
	char	   *result = NULL;
	int			fetchCount;

	result = caql_getcstring_plus(
					NULL,
					&fetchCount,
					NULL,
					cql("SELECT relname FROM pg_class "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(relid)));

	if (!fetchCount)
		return NULL;

	return result;
}


/*
 * get_rel_name_partition
 *		Returns the name of a given relation plus its parent name, if it is a partition table.
 *		If it not a partition table, it returns the relation name only.
 *
 *	Returns a palloc'd copy of the string, or NULL if no such relation.
 *	The caller is responsible for releasing the palloc'd memory.
 */
char *
get_rel_name_partition(Oid relid)
{
	char *rel_name = get_rel_name(relid);

	if (rel_name == NULL) return NULL;

	if (rel_is_child_partition(relid))
	{
		char *result;

		Oid parent_oid = rel_partition_get_master(relid);
		Assert(parent_oid != InvalidOid);

		char *parent_name = get_rel_name(parent_oid);
		Assert(parent_name);

		char *partition_name = "";

		StringInfo buffer = makeStringInfo();
		Assert(buffer);

		appendStringInfo(buffer, "\"%s\" (partition%s of relation \"%s\")",
							     rel_name, partition_name, parent_name);

		result = pstrdup(buffer->data);

		pfree(rel_name);
		pfree(parent_name);
		pfree(buffer);

		rel_name = NULL;
		parent_name = NULL;
		buffer = NULL;

		return result;
	}
	return rel_name;
}


/*
 * get_rel_namespace
 *
 *		Returns the pg_namespace OID associated with a given relation.
 */
Oid
get_rel_namespace(Oid relid)
{
	Oid			result = InvalidOid;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT relnamespace FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_rel_type_id
 *
 *		Returns the pg_type OID associated with a given relation.
 *
 * Note: not all pg_class entries have associated pg_type OIDs; so be
 * careful to check for InvalidOid result.
 */
Oid
get_rel_type_id(Oid relid)
{
	Oid			result = InvalidOid;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT reltype FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_rel_relkind
 *
 *		Returns the relkind associated with a given relation.
 */
char
get_rel_relkind(Oid relid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	char		result = '\0';

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);

		result = reltup->relkind;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_rel_reltuples
 *
 *		Returns the estimated number of tuples of a given relation.
 */
float4
get_rel_reltuples(Oid relid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	float4 result = 0;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);

		result = reltup->reltuples;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_rel_relstorage
 *
 *		Returns the relstorage associated with a given relation.
 */
char
get_rel_relstorage(Oid relid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	char		result = '\0';

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp);

		result = reltup->relstorage;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_rel_tablespace
 *
 *		Returns the pg_tablespace OID associated with a given relation.
 *
 * Note: InvalidOid might mean either that we couldn't find the relation,
 * or that it is in the database's default tablespace.
 */
Oid
get_rel_tablespace(Oid relid)
{
	Oid			result = InvalidOid;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT reltablespace FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}


/*				---------- TYPE CACHE ----------						 */

/*
 * get_typisdefined
 *
 *		Given the type OID, determine whether the type is defined
 *		(if not, it's only a shell).
 */
bool
get_typisdefined(Oid typid)
{
	HeapTuple	tp;
	bool		result = false;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		result = typtup->typisdefined;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_typlen
 *
 *		Given the type OID, return the length of the type.
 */
int16
get_typlen(Oid typid)
{
	HeapTuple	tp;
	int16		result = 0;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		result = typtup->typlen;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_typbyval
 *
 *		Given the type OID, determine whether the type is returned by value or
 *		not.  Returns true if by value, false if by reference.
 */
bool
get_typbyval(Oid typid)
{
	HeapTuple	tp;
	bool		result = false;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		result = typtup->typbyval;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_typlenbyval
 *
 *		A two-fer: given the type OID, return both typlen and typbyval.
 *
 *		Since both pieces of info are needed to know how to copy a Datum,
 *		many places need both.	Might as well get them with one cache lookup
 *		instead of two.  Also, this routine raises an error instead of
 *		returning a bogus value when given a bad type OID.
 */
void
get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
{
	HeapTuple	tp;
	Form_pg_type typtup;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for type %u", typid);
	typtup = (Form_pg_type) GETSTRUCT(tp);
	*typlen = typtup->typlen;
	*typbyval = typtup->typbyval;

	caql_endscan(pcqCtx);
}

/*
 * get_typlenbyvalalign
 *
 *		A three-fer: given the type OID, return typlen, typbyval, typalign.
 */
void
get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
					 char *typalign)
{
	HeapTuple	tp;
	Form_pg_type typtup;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for type %u", typid);
	typtup = (Form_pg_type) GETSTRUCT(tp);
	*typlen = typtup->typlen;
	*typbyval = typtup->typbyval;
	*typalign = typtup->typalign;

	caql_endscan(pcqCtx);
}

/*
 * getTypeIOParam
 *		Given a pg_type row, select the type OID to pass to I/O functions
 *
 * Formerly, all I/O functions were passed pg_type.typelem as their second
 * parameter, but we now have a more complex rule about what to pass.
 * This knowledge is intended to be centralized here --- direct references
 * to typelem elsewhere in the code are wrong, if they are associated with
 * I/O calls and not with actual subscripting operations!  (But see
 * bootstrap.c's boot_get_type_io_data() if you need to change this.)
 *
 * As of PostgreSQL 8.1, output functions receive only the value itself
 * and not any auxiliary parameters, so the name of this routine is now
 * a bit of a misnomer ... it should be getTypeInputParam.
 */
Oid
getTypeIOParam(HeapTuple typeTuple)
{
	Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);

	/*
	 * Array types get their typelem as parameter; everybody else gets their
	 * own type OID as parameter.  (As of 8.2, domains must get their own OID
	 * even if their base type is an array.)
	 */
	if (typeStruct->typtype == TYPTYPE_BASE && OidIsValid(typeStruct->typelem))
		return typeStruct->typelem;
	else
		return HeapTupleGetOid(typeTuple);
}

/*
 * get_type_io_data
 *
 *		A six-fer:	given the type OID, return typlen, typbyval, typalign,
 *					typdelim, typioparam, and IO function OID. The IO function
 *					returned is controlled by IOFuncSelector
 */
void
get_type_io_data(Oid typid,
				 IOFuncSelector which_func,
				 int16 *typlen,
				 bool *typbyval,
				 char *typalign,
				 char *typdelim,
				 Oid *typioparam,
				 Oid *func)
{
	HeapTuple	typeTuple;
	Form_pg_type typeStruct;
	cqContext  *pcqCtx;

	/*
	 * In bootstrap mode, pass it off to bootstrap.c.  This hack allows us to
	 * use array_in and array_out during bootstrap.
	 */
	if (IsBootstrapProcessingMode())
	{
		Oid			typinput;
		Oid			typoutput;

		boot_get_type_io_data(typid,
							  typlen,
							  typbyval,
							  typalign,
							  typdelim,
							  typioparam,
							  &typinput,
							  &typoutput);
		switch (which_func)
		{
			case IOFunc_input:
				*func = typinput;
				break;
			case IOFunc_output:
				*func = typoutput;
				break;
			default:
				elog(ERROR, "binary I/O not supported during bootstrap");
				break;
		}
		return;
	}

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	typeTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", typid);
	typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);

	*typlen = typeStruct->typlen;
	*typbyval = typeStruct->typbyval;
	*typalign = typeStruct->typalign;
	*typdelim = typeStruct->typdelim;
	*typioparam = getTypeIOParam(typeTuple);
	switch (which_func)
	{
		case IOFunc_input:
			*func = typeStruct->typinput;
			break;
		case IOFunc_output:
			*func = typeStruct->typoutput;
			break;
		case IOFunc_receive:
			*func = typeStruct->typreceive;
			break;
		case IOFunc_send:
			*func = typeStruct->typsend;
			break;
	}

	caql_endscan(pcqCtx);
}

#ifdef NOT_USED
char
get_typalign(Oid typid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	char		result = 'i';

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		result = typtup->typalign;
	}

	caql_endscan(pcqCtx);
	return result;
}
#endif

char
get_typstorage(Oid typid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	char		result = 'p';

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		result = typtup->typstorage;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_typdefault
 *	  Given a type OID, return the type's default value, if any.
 *
 *	  The result is a palloc'd expression node tree, or NULL if there
 *	  is no defined default for the datatype.
 *
 * NB: caller should be prepared to coerce result to correct datatype;
 * the returned expression tree might produce something of the wrong type.
 */
Node *
get_typdefault(Oid typid)
{
	HeapTuple	typeTuple;
	Form_pg_type type;
	Datum		datum;
	bool		isNull;
	Node	   *expr;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	typeTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", typid);
	type = (Form_pg_type) GETSTRUCT(typeTuple);

	/*
	 * typdefault and typdefaultbin are potentially null, so don't try to
	 * access 'em as struct fields. Must do it the hard way with
	 * caql_getattr.
	 */
	datum = caql_getattr(pcqCtx,
						 Anum_pg_type_typdefaultbin,
						 &isNull);

	if (!isNull)
	{
		/* We have an expression default */
		expr = stringToNode(TextDatumGetCString(datum));
	}
	else
	{
		/* Perhaps we have a plain literal default */
		datum = caql_getattr(pcqCtx,
							 Anum_pg_type_typdefault,
							 &isNull);

		if (!isNull)
		{
			char	   *strDefaultVal;

			/* Convert text datum to C string */
			strDefaultVal = TextDatumGetCString(datum);
			/* Convert C string to a value of the given type */
			datum = OidInputFunctionCall(type->typinput, strDefaultVal,
										 getTypeIOParam(typeTuple), -1);
			/* Build a Const node containing the value */
			expr = (Node *) makeConst(typid, -1,
									  type->typlen,
									  datum,
									  false,
									  type->typbyval);
			pfree(strDefaultVal);
		}
		else
		{
			/* No default */
			expr = NULL;
		}
	}

	caql_endscan(pcqCtx);

	return expr;
}

/*
 * getBaseType
 *		If the given type is a domain, return its base type;
 *		otherwise return the type's own OID.
 */
Oid
getBaseType(Oid typid)
{
	int32		typmod = -1;

	return getBaseTypeAndTypmod(typid, &typmod);
}

/*
 * getBaseTypeAndTypmod
 *		If the given type is a domain, return its base type and typmod;
 *		otherwise return the type's own OID, and leave *typmod unchanged.
 *
 * Note that the "applied typmod" should be -1 for every domain level
 * above the bottommost; therefore, if the passed-in typid is indeed
 * a domain, *typmod should be -1.
 */
Oid
getBaseTypeAndTypmod(Oid typid, int32 *typmod)
{
	/*
	 * We loop to find the bottom base type in a stack of domains.
	 */
	for (;;)
	{
		HeapTuple	tup;
		Form_pg_type typTup;
		cqContext  *pcqCtx;
		
		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_type "
					" WHERE oid = :1 ",
					ObjectIdGetDatum(typid)));

		tup = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(tup))
			elog(ERROR, "cache lookup failed for type %u", typid);
		typTup = (Form_pg_type) GETSTRUCT(tup);
		if (typTup->typtype != TYPTYPE_DOMAIN)
		{
			/* Not a domain, so done */
			caql_endscan(pcqCtx);
			break;
		}

		Assert(*typmod == -1);
		typid = typTup->typbasetype;
		*typmod = typTup->typtypmod;

		caql_endscan(pcqCtx);
	}

	return typid;
}

/*
 * get_typavgwidth
 *
 *	  Given a type OID and a typmod value (pass -1 if typmod is unknown),
 *	  estimate the average width of values of the type.  This is used by
 *	  the planner, which doesn't require absolutely correct results;
 *	  it's OK (and expected) to guess if we don't know for sure.
 */
int32
get_typavgwidth(Oid typid, int32 typmod)
{
	int			typlen = get_typlen(typid);
	int32		maxwidth;

	/*
	 * Easy if it's a fixed-width type
	 */
	if (typlen > 0)
		return typlen;

	/*
	 * type_maximum_size knows the encoding of typmod for some datatypes;
	 * don't duplicate that knowledge here.
	 */
	maxwidth = type_maximum_size(typid, typmod);
	if (maxwidth > 0)
	{
		/*
		 * For BPCHAR, the max width is also the only width.  Otherwise we
		 * need to guess about the typical data width given the max. A sliding
		 * scale for percentage of max width seems reasonable.
		 */
		if (typid == BPCHAROID)
			return maxwidth;
		if (maxwidth <= 32)
			return maxwidth;	/* assume full width */
		if (maxwidth < 1000)
			return 32 + (maxwidth - 32) / 2;	/* assume 50% */

		/*
		 * Beyond 1000, assume we're looking at something like
		 * "varchar(10000)" where the limit isn't actually reached often, and
		 * use a fixed estimate.
		 */
		return 32 + (1000 - 32) / 2;
	}

	/*
	 * Ooops, we have no idea ... wild guess time.
	 */
	return 32;
}

/*
 * get_typtype
 *
 *		Given the type OID, find if it is a basic type, a complex type, etc.
 *		It returns the null char if the cache lookup fails...
 */
char
get_typtype(Oid typid)
{
	HeapTuple	tp;
	cqContext  *pcqCtx;
	char		result = '\0';

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		result = typtup->typtype;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * type_is_rowtype
 *
 *		Convenience function to determine whether a type OID represents
 *		a "rowtype" type --- either RECORD or a named composite type.
 */
bool
type_is_rowtype(Oid typid)
{
	return (typid == RECORDOID || get_typtype(typid) == TYPTYPE_COMPOSITE);
}

/*
 * get_typ_typrelid
 *
 *		Given the type OID, get the typrelid (InvalidOid if not a complex
 *		type).
 */
Oid
get_typ_typrelid(Oid typid)
{
	Oid			result = InvalidOid;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT typrelid FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

/*
 * get_element_type
 *
 *		Given the type OID, get the typelem (InvalidOid if not an array type).
 *
 * NB: this only considers varlena arrays to be true arrays; InvalidOid is
 * returned if the input is a fixed-length array type.
 */
Oid
get_element_type(Oid typid)
{
	HeapTuple	tp;
	Oid			result = InvalidOid;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);

		if (typtup->typlen == -1)
			result = typtup->typelem;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_array_type
 *
 *		Given the type OID, get the corresponding array type.
 *		Returns InvalidOid if no array type can be found.
 *
 * NB: this only considers varlena arrays to be true arrays.
 */
Oid
get_array_type(Oid typid)
{
	HeapTuple	tp;
	Oid			result = InvalidOid;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(typid)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
		char	   *array_typename;
		Oid			namespaceId;
		cqContext  *namcqCtx;

		array_typename = makeArrayTypeName(NameStr(typtup->typname));
		namespaceId = typtup->typnamespace;

		namcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_type "
					" WHERE typname = :1 "
					" AND typnamespace = :2 ",
					PointerGetDatum(array_typename),
					ObjectIdGetDatum(namespaceId)));

		tp = caql_getnext(namcqCtx);

		pfree(array_typename);

		if (HeapTupleIsValid(tp))
		{
			typtup = (Form_pg_type) GETSTRUCT(tp);
			if (typtup->typlen == -1 && typtup->typelem == typid)
				result = HeapTupleGetOid(tp);
		}
		caql_endscan(namcqCtx);
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_base_element_type
 *		Given the type OID, get the typelem, looking "through" any domain
 *		to its underlying array type.
 *
 * This is equivalent to get_element_type(getBaseType(typid)), but avoids
 * an extra cache lookup.  Note that it fails to provide any information
 * about the typmod of the array.
 */
Oid
get_base_element_type(Oid typid)
{
	/*
	 * We loop to find the bottom base type in a stack of domains.
	 */
	for (;;)
	{
		HeapTuple	tup;
		Form_pg_type typTup;
		cqContext  *pcqCtx;
		
		pcqCtx = caql_beginscan(
				NULL,
				cql("SELECT * FROM pg_type "
					" WHERE oid = :1 ",
					ObjectIdGetDatum(typid)));

		tup = caql_getnext(pcqCtx);

		if (!HeapTupleIsValid(tup))
		{
			caql_endscan(pcqCtx);
			break;
		}

		typTup = (Form_pg_type) GETSTRUCT(tup);
		if (typTup->typtype != TYPTYPE_DOMAIN)
		{
			/* Not a domain, so stop descending */
			Oid			result;

			/* This test must match get_element_type */
			if (typTup->typlen == -1)
				result = typTup->typelem;
			else
				result = InvalidOid;

			caql_endscan(pcqCtx);
			return result;
		}

		typid = typTup->typbasetype;
		caql_endscan(pcqCtx);
	}

	/* Like get_element_type, silently return InvalidOid for bogus input */
	return InvalidOid;
}

/*
 * getTypeInputInfo
 *
 *		Get info needed for converting values of a type to internal form
 */
void
getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
{
	HeapTuple	typeTuple;
	Form_pg_type pt;
	cqContext  *pcqCtx;
		
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(type)));

	typeTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", type);
	pt = (Form_pg_type) GETSTRUCT(typeTuple);

	if (!pt->typisdefined)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("type %s is only a shell",
						format_type_be(type)),
								   errOmitLocation(true)));
	if (!OidIsValid(pt->typinput))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("no input function available for type %s",
						format_type_be(type)),
								   errOmitLocation(true)));

	*typInput = pt->typinput;
	*typIOParam = getTypeIOParam(typeTuple);

	caql_endscan(pcqCtx);
}

/*
 * getTypeOutputInfo
 *
 *		Get info needed for printing values of a type
 */
void
getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
{
	HeapTuple	typeTuple;
	Form_pg_type pt;
	cqContext  *pcqCtx;
		
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(type)));

	typeTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", type);
	pt = (Form_pg_type) GETSTRUCT(typeTuple);

	if (!pt->typisdefined)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("type %s is only a shell",
						format_type_be(type)),
								   errOmitLocation(true)));
	if (!OidIsValid(pt->typoutput))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("no output function available for type %s",
						format_type_be(type)),
								   errOmitLocation(true)));

	*typOutput = pt->typoutput;
	*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);

	caql_endscan(pcqCtx);
}

/*
 * getTypeBinaryInputInfo
 *
 *		Get info needed for binary input of values of a type
 */
void
getTypeBinaryInputInfo(Oid type, Oid *typReceive, Oid *typIOParam)
{
	HeapTuple	typeTuple;
	Form_pg_type pt;
	cqContext  *pcqCtx;
		
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(type)));

	typeTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", type);
	pt = (Form_pg_type) GETSTRUCT(typeTuple);

	if (!pt->typisdefined)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("type %s is only a shell",
						format_type_be(type)),
								   errOmitLocation(true)));
	if (!OidIsValid(pt->typreceive))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("no binary input function available for type %s",
						format_type_be(type)),
								   errOmitLocation(true)));

	*typReceive = pt->typreceive;
	*typIOParam = getTypeIOParam(typeTuple);

	caql_endscan(pcqCtx);
}

/*
 * getTypeBinaryOutputInfo
 *
 *		Get info needed for binary output of values of a type
 */
void
getTypeBinaryOutputInfo(Oid type, Oid *typSend, bool *typIsVarlena)
{
	HeapTuple	typeTuple;
	Form_pg_type pt;
	cqContext  *pcqCtx;
		
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_type "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(type)));

	typeTuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", type);
	pt = (Form_pg_type) GETSTRUCT(typeTuple);

	if (!pt->typisdefined)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("type %s is only a shell",
						format_type_be(type)),
								   errOmitLocation(true)));
	if (!OidIsValid(pt->typsend))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("no binary output function available for type %s",
						format_type_be(type)),
								   errOmitLocation(true)));

	*typSend = pt->typsend;
	*typIsVarlena = (!pt->typbyval) && (pt->typlen == -1);

	caql_endscan(pcqCtx);
}


/*				---------- STATISTICS CACHE ----------					 */

/*
 * get_attavgwidth
 *
 *	  Given the table and attribute number of a column, get the average
 *	  width of entries in the column.  Return zero if no data available.
 */
int32
get_attavgwidth(Oid relid, AttrNumber attnum)
{
	HeapTuple	tp;
	int32		result = 0;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_statistic "
				" WHERE starelid = :1 "
				" AND staattnum = :2 ",
				ObjectIdGetDatum(relid),
				Int16GetDatum(attnum)));

	tp = caql_getnext(pcqCtx);

	if (HeapTupleIsValid(tp))
	{
		int32		stawidth = ((Form_pg_statistic) GETSTRUCT(tp))->stawidth;

		if (stawidth > 0)
			result = stawidth;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_attdistinct
 *
 *	  Given the table and attribute number of a column, get the number of
 *	  distinct values in the column.  Return zero if no data available.
 */
float4
get_attdistinct(Oid relid, AttrNumber attnum)
{
	cqContext *pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_statistic "
				" WHERE starelid = :1 "
				" AND staattnum = :2 ",
				ObjectIdGetDatum(relid),
				Int16GetDatum(attnum)));

	HeapTuple tp = caql_getnext(pcqCtx);

	float4 result = 0;
	if (HeapTupleIsValid(tp))
	{
		result = ((Form_pg_statistic) GETSTRUCT(tp))->stadistinct;
	}

	caql_endscan(pcqCtx);
	return result;
}

/*
 * get_attstatsslot
 *
 *		Extract the contents of a "slot" of a pg_statistic tuple.
 *		Returns TRUE if requested slot type was found, else FALSE.
 *
 * Unlike other routines in this file, this takes a pointer to an
 * already-looked-up tuple in the pg_statistic cache.  We do this since
 * most callers will want to extract more than one value from the cache
 * entry, and we don't want to repeat the cache lookup unnecessarily.
 *
 * statstuple: pg_statistics tuple to be examined.
 * atttype: type OID of attribute (can be InvalidOid if values == NULL).
 * atttypmod: typmod of attribute (can be 0 if values == NULL).
 * reqkind: STAKIND code for desired statistics slot kind.
 * reqop: STAOP value wanted, or InvalidOid if don't care.
 * values, nvalues: if not NULL, the slot's stavalues are extracted.
 * numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
 *
 * If assigned, values and numbers are set to point to palloc'd arrays.
 * If the attribute type is pass-by-reference, the values referenced by
 * the values array are themselves palloc'd.  The palloc'd stuff can be
 * freed by calling free_attstatsslot.
 */
extern bool get_attstatsslot_desc(TupleDesc tupdesc, HeapTuple statstuple,
				 Oid atttype, int32 atttypmod,
				 int reqkind, Oid reqop,
				 Datum **values, int *nvalues,
				 float4 **numbers, int *nnumbers);

bool 
get_attstatsslot(HeapTuple statstuple,
		 Oid atttype, int32 atttypmod,
				 int reqkind, Oid reqop,
				 Datum **values, int *nvalues,
				 float4 **numbers, int *nnumbers)
{
	return get_attstatsslot_desc(NULL, statstuple,
			atttype, atttypmod, reqkind, reqop,
			values, nvalues, numbers, nnumbers
			);
}

/* get an attribute any way you can! */
static Datum
attstatsslot_getattr(cqContext	*pcqCtx, 
					 TupleDesc	 tupdesc,
					 HeapTuple	 statstuple,
					 AttrNumber	 attnum, bool *isnull)
{
	Datum		val;

	if (pcqCtx)
		val = caql_getattr(pcqCtx, attnum, isnull);
	else
	{
		if(tupdesc)
			val = heap_getattr(statstuple, attnum,
							   tupdesc, isnull);
		else
			val = SysCacheGetAttr(STATRELATT, statstuple,
								  attnum,
								  isnull);
	}
		
	return val;
}

bool
get_attstatsslot_desc(TupleDesc tupdesc, HeapTuple statstuple,
				 Oid atttype, int32 atttypmod,
				 int reqkind, Oid reqop,
				 Datum **values, int *nvalues,
				 float4 **numbers, int *nnumbers)
{
	Form_pg_statistic stats = (Form_pg_statistic) GETSTRUCT(statstuple);
	int			i,
				j;
	Datum		val;
	bool		isnull;
	ArrayType  *statarray;
	int			narrayelem;
	HeapTuple	typeTuple;
	Form_pg_type typeForm;

	for (i = 0; i < STATISTIC_NUM_SLOTS; i++)
	{
		if ((&stats->stakind1)[i] == reqkind &&
			(reqop == InvalidOid || (&stats->staop1)[i] == reqop))
			break;
	}
	if (i >= STATISTIC_NUM_SLOTS)
		return false;			/* not there */

	if (values)
	{
		*values = NULL;
		*nvalues = 0;

		val = attstatsslot_getattr(NULL, 
								   tupdesc, 
								   statstuple, 
								   Anum_pg_statistic_stavalues1 + i, 
								   &isnull);

		if (isnull)
			elog(ERROR, "stavalues is null");
		statarray = DatumGetArrayTypeP(val);

		/**
		 * Could be an empty array.
		 */
		if (ARR_NDIM(statarray) > 0)
		{
			cqContext  *typcqCtx;

			/* Need to get info about the array element type */
			typcqCtx = caql_beginscan(
					NULL,
					cql("SELECT * FROM pg_type "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(atttype)));

			typeTuple = caql_getnext(typcqCtx);

			if (!HeapTupleIsValid(typeTuple))
				elog(ERROR, "cache lookup failed for type %u", atttype);
			typeForm = (Form_pg_type) GETSTRUCT(typeTuple);

			/* Deconstruct array into Datum elements; NULLs not expected */
			deconstruct_array(statarray,
					atttype,
					typeForm->typlen,
					typeForm->typbyval,
					typeForm->typalign,
					values, NULL, nvalues);

			/*
			 * If the element type is pass-by-reference, we now have a bunch of
			 * Datums that are pointers into the syscache value.  Copy them to
			 * avoid problems if syscache decides to drop the entry.
			 */
			if (!typeForm->typbyval)
			{
				for (j = 0; j < *nvalues; j++)
				{
					(*values)[j] = datumCopy((*values)[j],
							typeForm->typbyval,
							typeForm->typlen);
				}
			}

			caql_endscan(typcqCtx);
		}
		/*
		 * Free statarray if it's a detoasted copy.
		 */
		if ((Pointer) statarray != DatumGetPointer(val))
			pfree(statarray);
	}

	if (numbers)
	{
		*numbers = NULL;
		*nnumbers = 0;

		val = attstatsslot_getattr(NULL, 
								   tupdesc, 
								   statstuple, 
								   Anum_pg_statistic_stanumbers1 + i, 
								   &isnull);

		if (isnull)
			elog(ERROR, "stanumbers is null");
		statarray = DatumGetArrayTypeP(val);

		/**
		 * Could be an empty array.
		 */
		if (ARR_NDIM(statarray) > 0)
		{
			/*
			 * We expect the array to be a 1-D float4 array; verify that. We don't
			 * need to use deconstruct_array() since the array data is just going
			 * to look like a C array of float4 values.
			 */
			narrayelem = ARR_DIMS(statarray)[0];
			if (ARR_NDIM(statarray) != 1 || narrayelem <= 0 ||
					ARR_HASNULL(statarray) ||
					ARR_ELEMTYPE(statarray) != FLOAT4OID)
				elog(ERROR, "stanumbers is not a 1-D float4 array");
			*numbers = (float4 *) palloc(narrayelem * sizeof(float4));
			*nnumbers = narrayelem;
			memcpy(*numbers, ARR_DATA_PTR(statarray), narrayelem * sizeof(float4));
		}

		/*
		 * Free statarray if it's a detoasted copy.
		 */
		if ((Pointer) statarray != DatumGetPointer(val))
			pfree(statarray);
	}

	return true;
}

/*
 * free_attstatsslot
 *		Free data allocated by get_attstatsslot
 *
 * atttype need be valid only if values != NULL.
 */
void
free_attstatsslot(Oid atttype,
				  Datum *values, int nvalues,
				  float4 *numbers, int nnumbers)
{
	if (values)
	{
		if (!get_typbyval(atttype))
		{
			int			i;

			for (i = 0; i < nvalues; i++)
				pfree(DatumGetPointer(values[i]));
		}
		pfree(values);
	}
	if (numbers)
		pfree(numbers);
}

/*
 * get_att_stats
 *		Get attribute statistics. Return a copy of the HeapTuple object, or NULL
 *		if no stats found for attribute
 * 
 */
HeapTuple
get_att_stats(Oid relid, AttrNumber attrnum)
{
		return (
			caql_getfirst(
					NULL,
					cql("SELECT * FROM pg_statistic "
						" WHERE starelid = :1 "
						" AND staattnum = :2 ",
						ObjectIdGetDatum(relid),
						Int16GetDatum(attrnum))));
}

/*				---------- PG_NAMESPACE CACHE ----------				 */

/*
 * get_namespace_name
 *		Returns the name of a given namespace
 *
 * Returns a palloc'd copy of the string, or NULL if no such namespace.
 */
char *
get_namespace_name(Oid nspid)
{
	char	   *result = NULL;
	int			fetchCount;

	result = caql_getcstring_plus(
					NULL,
					&fetchCount,
					NULL,
					cql("SELECT nspname FROM pg_namespace "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(nspid)));

	if (!fetchCount)
		return NULL;

	return result;
}

/*				---------- PG_AUTHID CACHE ----------					 */

/*
 * get_roleid
 *	  Given a role name, look up the role's OID.
 *	  Returns InvalidOid if no such role.
 */
Oid
get_roleid(const char *rolname)
{
	Oid			result;
	int			fetchCount;

	result = caql_getoid_plus(
			NULL,
			&fetchCount,
			NULL,
			cql("SELECT * FROM pg_authid "
				" WHERE rolname = :1 ",
				PointerGetDatum((char *) rolname)));

	if (!fetchCount)
		return InvalidOid;

	return result;
}

char *
get_rolname(Oid roleid)
{
	HeapTuple	ht;
	Form_pg_authid auth_rec;
	char		*result = NULL;

	ht = SearchSysCache(AUTHOID,
							ObjectIdGetDatum(roleid),
							0, 0, 0);
	if (!HeapTupleIsValid(ht))
		return result;

	auth_rec = (Form_pg_authid) GETSTRUCT(ht);

	result = pstrdup(NameStr(auth_rec->rolname));

	ReleaseSysCache(ht);
	return result;
}

/*
 * get_relation_storage_type
 */
char
get_relation_storage_type(Oid relid)
{
	HeapTuple classtuple;
	Datum relstorage;
	char storageChar;

	/* find relid in pg_class */
	classtuple = SearchSysCache(RELOID, ObjectIdGetDatum(relid), 0, 0, 0);
	if (!HeapTupleIsValid(classtuple))
	{
		elog(ERROR, "cache lookup failed for relation %u", relid);
	}
	relstorage = SysCacheGetAttr(RELOID, classtuple, Anum_pg_class_relstorage, NULL);
	storageChar = DatumGetChar(relstorage);
	ReleaseSysCache(classtuple);

	return storageChar;
}

/*
 * get_roleid_checked
 *	  Given a role name, look up the role's OID.
 *	  ereports if no such role.
 */
Oid
get_roleid_checked(const char *rolname)
{
	Oid			roleid;

	roleid = get_roleid(rolname);
	if (!OidIsValid(roleid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_OBJECT),
				 errmsg("role \"%s\" does not exist", rolname),
						   errOmitLocation(true)));
	return roleid;
}


/*
 * relation_oids
 *	  Extract all relation oids from the catalog.
 */
List *
relation_oids()
{
	List			*relationOids = NIL;
	Relation		pgclass = NULL;
	HeapScanDesc 	scan = NULL;
	HeapTuple		tuple = NULL;

	pgclass = heap_open(RelationRelationId, AccessShareLock);

	scan = heap_beginscan(pgclass, SnapshotNow, 0 /* key length */, NULL);

	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		Form_pg_class pgclassEntry = (Form_pg_class) GETSTRUCT(tuple);

		switch (pgclassEntry->relstorage)
		{
			case RELSTORAGE_HEAP:
			case RELSTORAGE_AOROWS:
			case RELSTORAGE_PARQUET:
			case RELSTORAGE_EXTERNAL:
			{
				Oid relOid = HeapTupleGetOid(tuple);
				relationOids = lappend_oid(relationOids, relOid);
				break;
			}
			default:
				break;
		}
	}

	heap_endscan(scan);
	heap_close(pgclass, AccessShareLock);
	return relationOids;
}

/*
 * operator_oids
 *	  Extract all operator oids from the catalog.
 */
List *
operator_oids()
{
	List			*operatorOids = NIL;
	Relation		operatortable = NULL;
	HeapScanDesc 	scan = NULL;
	HeapTuple		tuple = NULL;

	operatortable = heap_open(OperatorRelationId, AccessShareLock);

	scan = heap_beginscan(operatortable, SnapshotNow, 0 /* key length */, NULL);

	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		Oid opOid = HeapTupleGetOid(tuple);
		operatorOids = lappend_oid(operatorOids, opOid);
	}

	heap_endscan(scan);
	heap_close(operatortable, AccessShareLock);
	return operatorOids;
}

/*
 * function_oids
 *	  Extract all function oids from the catalog.
 */
List *
function_oids()
{
	List			*functionOids = NIL;
	Relation		functiontable = NULL;
	HeapScanDesc 	scan = NULL;
	HeapTuple		tuple = NULL;

	functiontable = heap_open(ProcedureRelationId, AccessShareLock);

	scan = heap_beginscan(functiontable, SnapshotNow, 0 /* key length */, NULL);

	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
	{
		Oid funcOid = HeapTupleGetOid(tuple);
		functionOids = lappend_oid(functionOids, funcOid);
	}

	heap_endscan(scan);
	heap_close(functiontable, AccessShareLock);
	return functionOids;
}

/*
 * relation_exists
 *	  Is there a relation with the given oid
 */
bool
relation_exists(Oid oid)
{
	return SearchSysCacheExists(RELOID, oid, 0, 0, 0);
}

/*
 * index_exists
 *	  Is there an index with the given oid
 */
bool
index_exists(Oid oid)
{
	return SearchSysCacheExists(INDEXRELID, oid, 0, 0, 0);
}

/*
 * type_exists
 *	  Is there a type with the given oid
 */
bool
type_exists(Oid oid)
{
	return SearchSysCacheExists(TYPEOID, oid, 0, 0, 0);
}

/*
 * operator_exists
 *	  Is there an operator with the given oid
 */
bool
operator_exists(Oid oid)
{
	return SearchSysCacheExists(OPEROID, oid, 0, 0, 0);
}

/*
 * function_exists
 *	  Is there a function with the given oid
 */
bool
function_exists(Oid oid)
{
	return SearchSysCacheExists(PROCOID, oid, 0, 0, 0);
}

/*
 * aggregate_exists
 *	  Is there an aggregate with the given oid
 */
bool
aggregate_exists(Oid oid)
{
	return SearchSysCacheExists(AGGFNOID, oid, 0, 0, 0);
}

// Get oid of aggregate with given name and argument type
Oid
get_aggregate(const char *aggname, Oid oidType)
{
	HeapTuple htup = NULL;
	
	// lookup pg_proc for functions with the given name and arg type
	cqContext *pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_proc "
				" WHERE proname = :1",
				PointerGetDatum((char *) aggname)));

	Oid oidResult = InvalidOid;
	while (HeapTupleIsValid(htup = caql_getnext(pcqCtx)))
	{
		Oid oidProc = HeapTupleGetOid(htup);
		
		Form_pg_proc proctuple = (Form_pg_proc) GETSTRUCT(htup);

		// skip functions with the wrong number of type of arguments
		if (1 != proctuple->pronargs || oidType != proctuple->proargtypes.values[0])
		{
			continue;
		}

		if (caql_getcount(
					NULL,
					cql("SELECT COUNT(*) FROM pg_aggregate "
						" WHERE aggfnoid = :1 ",
						ObjectIdGetDatum(oidProc))) > 0)
		{
			oidResult = oidProc;
			break;
		}
	}
	
	caql_endscan(pcqCtx);

	return oidResult;
}

/*
 * trigger_exists
 *	  Is there a trigger with the given oid
 */
bool
trigger_exists(Oid oid)
{
	return (caql_getcount(
					NULL,
					cql("SELECT COUNT(*) FROM pg_trigger "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(oid))) > 0);
}

/*
 * get_relation_keys
 *	  Return a list of relation keys
 */
List *
get_relation_keys(Oid relid)
{
	List *keys = NIL;

	// lookup unique constraints for relation from the catalog table
	ScanKeyData skey[1];
	ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, relid);

	Relation rel = heap_open(ConstraintRelationId, AccessShareLock);
	SysScanDesc scan = systable_beginscan
						(
						rel, 
						ConstraintRelidIndexId, 
						true, 
						SnapshotNow, 
						1, 
						skey
						);
	
	HeapTuple	htup = NULL;

	while (HeapTupleIsValid(htup = systable_getnext(scan)))
	{
		Form_pg_constraint contuple = (Form_pg_constraint) GETSTRUCT(htup);

		// skip non-unique constraints
		if (CONSTRAINT_UNIQUE != contuple->contype &&
			CONSTRAINT_PRIMARY != contuple->contype)
		{
			continue;
		}
			
		// store key set in an array
		List *key = NIL;
		
		bool null = false;
		Datum dat = 
				heap_getattr(htup, Anum_pg_constraint_conkey, RelationGetDescr(rel), &null);
		
		Datum *dats = NULL;
		int numKeys = 0;

		// extract key elements
		deconstruct_array(DatumGetArrayTypeP(dat), INT2OID, 2, true, 's', &dats, NULL, &numKeys);
			
		for (int i = 0; i < numKeys; i++)
		{
			int16 key_elem =  DatumGetInt16(dats[i]);
			key = lappend_int(key, key_elem);
		}
		
		keys = lappend(keys, key);
	}

	systable_endscan(scan);
	heap_close(rel, AccessShareLock);

	return keys;
}

/*
 * check_constraint_exists
 *	  Is there a check constraint with the given oid
 */
bool
check_constraint_exists(Oid oidCheckconstraint)
{
	return (caql_getcount(
					NULL,
					cql("SELECT COUNT(*) FROM pg_constraint "
						" WHERE oid = :1 ",
						ObjectIdGetDatum(oidCheckconstraint))) > 0);
}

/*
 * get_check_constraint_relid
 *		Given check constraint id, return the check constraint's relation oid
 */
Oid
get_check_constraint_relid(Oid oidCheckconstraint)
{
	Oid	result = InvalidOid;
	int	iFetchCount = 0;

	result  = caql_getoid_plus(
			NULL,
			&iFetchCount,
			NULL,
			cql("SELECT conrelid FROM pg_constraint "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(oidCheckconstraint)));

	if (0 == iFetchCount)
	{
		return InvalidOid;
	}

	return result;
}

/*
 * get_check_constraint_oids
 *	 Extract all check constraint oid for a given relation.
 */
List *
get_check_constraint_oids(Oid oidRel)
{
	List *plConstraints = NIL;
	HeapTuple htup = NULL;
	cqContext *pcqCtx = NULL;

	// lookup constraints for relation from the catalog table
	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_constraint "
				" WHERE conrelid = :1 ",
				ObjectIdGetDatum(oidRel)));

	while (HeapTupleIsValid(htup = caql_getnext(pcqCtx)))
	{
		Form_pg_constraint contuple = (Form_pg_constraint) GETSTRUCT(htup);

		// only consider check constraints
		if (CONSTRAINT_CHECK != contuple->contype)
		{
			continue;
		}

		plConstraints = lappend_oid(plConstraints, HeapTupleGetOid(htup));
	}

	caql_endscan(pcqCtx);

	return plConstraints;
}

/*
 * get_check_constraint_name
 *        returns the name of the check constraint with the given oidConstraint.
 *
 * Note: returns a palloc'd copy of the string, or NULL if no such constraint.
 */
char *
get_check_constraint_name(Oid oidCheckconstraint)
{
	char *szResult = NULL;
	int iFetchCount = 0;
	szResult = caql_getcstring_plus
				(
				NULL,
				&iFetchCount,
				NULL,
				cql("SELECT conname FROM pg_constraint "
					" WHERE oid = :1 ",
					ObjectIdGetDatum(oidCheckconstraint)
					)
				);

	if (0 == iFetchCount)
	{
		return NULL;
	}

	return szResult;
}

/*
 * get_check_constraint_expr_tree
 *        returns the expression node tree representing the check constraint
 *        with the given oidConstraint.
 *
 * Note: returns a palloc'd expression node tree, or NULL if no such constraint.
 */
Node *
get_check_constraint_expr_tree(Oid oidCheckconstraint)
{
	char *szResult = NULL;
	int iFetchCount = 0;
	szResult = caql_getcstring_plus
				(
				NULL,
				&iFetchCount,
				NULL,
				cql("SELECT conbin FROM pg_constraint "
					" WHERE oid = :1 ",
					ObjectIdGetDatum(oidCheckconstraint)
					)
				);

	if (0 == iFetchCount)
	{
		return NULL;
	}

	return stringToNode(szResult);
}

/*
 * get_cast_func
 *        finds the cast function between the given source and destination type,
 *        and records its oid and properties in the output parameters.
 *        Returns true if a cast exists, false otherwise.
 */
bool
get_cast_func(Oid oidSrc, Oid oidDest, bool *is_binary_coercible, Oid *oidCastFunc)
{
	if (IsBinaryCoercible(oidSrc, oidDest))
	{
		*is_binary_coercible = true;
		*oidCastFunc = 0;
		return true;
	}
	
	*is_binary_coercible = false;
	
	return find_coercion_pathway(oidDest, oidSrc, COERCION_IMPLICIT, oidCastFunc);
}

/*
 * get_comparison_type
 *      Retrieve comparison type  
 */
CmpType
get_comparison_type
	(
	Oid oidOp,
	Oid oidLeft,
	Oid oidRight
	)
{
	// find the equality comparison between the operands
	
	cqContext *pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_operator "
				" WHERE oprleft = :1 and oprright = :2",
				ObjectIdGetDatum(oidLeft),
				ObjectIdGetDatum(oidRight)));

	Oid	oidEq = InvalidOid;
	
	HeapTuple ht = NULL;
	Form_pg_operator optup = NULL;
	
	while (HeapTupleIsValid(ht = caql_getnext(pcqCtx)))
	{		
		optup = (Form_pg_operator) GETSTRUCT(ht);

		if (optup->oprrest == F_EQSEL)
		{
			oidEq = HeapTupleGetOid(ht);
			break;
		}
	}
	
	if (InvalidOid == oidEq)
	{
		// no equality found between specified types, hence not a special comparison operator
		caql_endscan(pcqCtx);
		return CmptOther;
	}
	
	int cmp_oids[][2] = 
	{
	{oidEq, CmptEq},
	{get_negator(oidEq), CmptNEq},
	{optup->oprltcmpop, CmptLT},
	{optup->oprgtcmpop, CmptGT},
	{get_negator(optup->oprltcmpop), CmptGEq},
	{get_negator(optup->oprgtcmpop), CmptLEq}
	};
	
	for (int ul = 0; ul < 6; ul++)
	{
		int *map_elem = cmp_oids[ul];
		if (map_elem[0] == oidOp)
		{
			caql_endscan(pcqCtx);
			return map_elem[1];
		}
	}

	caql_endscan(pcqCtx);
	return CmptOther;
}

/*
 * get_comparison_operator
 *      Retrieve comparison operator between given types  
 */
Oid
get_comparison_operator
	(
	Oid oidLeft,
	Oid oidRight,
	CmpType cmpt
	)
{
	// find the equality comparison between the operands
	cqContext *pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_operator "
				" WHERE oprleft = :1 and oprright = :2",
				ObjectIdGetDatum(oidLeft),
				ObjectIdGetDatum(oidRight)));

	Oid	oidEq = InvalidOid;
	
	HeapTuple ht = NULL;
	Form_pg_operator optup = NULL;
	
	while (HeapTupleIsValid(ht = caql_getnext(pcqCtx)))
	{		
		optup = (Form_pg_operator) GETSTRUCT(ht);

		if (optup->oprrest == F_EQSEL)
		{
			oidEq = HeapTupleGetOid(ht);
			break;
		}
	}
	
	if (InvalidOid == oidEq)
	{
		// no equality found between specified types, hence not a special comparison operator
		caql_endscan(pcqCtx);
		return CmptOther;
	}
	
	int cmp_oids[][2] = 
	{
	{oidEq, CmptEq},
	{get_negator(oidEq), CmptNEq},
	{optup->oprltcmpop, CmptLT},
	{optup->oprgtcmpop, CmptGT},
	{get_negator(optup->oprltcmpop), CmptGEq},
	{get_negator(optup->oprgtcmpop), CmptLEq}
	};
	
	for (int ul = 0; ul < 6; ul++)
	{
		int *map_elem = cmp_oids[ul];
		if (map_elem[1] == cmpt)
		{
			caql_endscan(pcqCtx);
			return map_elem[0];
		}
	}

	caql_endscan(pcqCtx);
	
	return InvalidOid;
}

/*
 * has_subclass_fast
 *
 * In the current implementation, has_subclass returns whether a
 * particular class *might* have a subclass. It will not return the
 * correct result if a class had a subclass which was later dropped.
 * This is because relhassubclass in pg_class is not updated when a
 * subclass is dropped, primarily because of concurrency concerns.
 *
 * Currently has_subclass is only used as an efficiency hack to skip
 * unnecessary inheritance searches, so this is OK.
 */
bool
has_subclass_fast(Oid relationId)
{
	HeapTuple	tuple;
	bool		result;
	cqContext  *pcqCtx;

	pcqCtx = caql_beginscan(
			NULL,
			cql("SELECT * FROM pg_class "
				" WHERE oid = :1 ",
				ObjectIdGetDatum(relationId)));
	
	tuple = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(tuple))
		elog(ERROR, "cache lookup failed for relation %u", relationId);

	result = ((Form_pg_class) GETSTRUCT(tuple))->relhassubclass;

	caql_endscan(pcqCtx);
	return result;
}

/*
 * has_subclass
 *
 * Performs the exhaustive check whether a relation has a subclass. This is 
 * different from has_subclass_fast, in that the latter can return true if a relation.
 * *might* have a subclass. See comments in has_subclass_fast for more details.
 * 
 */
bool
has_subclass(Oid relationId)
{
	if (!has_subclass_fast(relationId))
	{
		return false;
	}
	
	return (0 < caql_getcount(
					NULL,
					cql("SELECT COUNT(*) FROM pg_inherits "
						" WHERE inhparent = :1 ",
						ObjectIdGetDatum(relationId))));
}

/*
 * get_operator_opclasses
 *		Get the oid of classes the given operator belongs to
 */
List *
get_operator_opclasses(Oid opno)
{
	cqContext *pcqCtx = caql_beginscan(
							NULL,
							cql("SELECT * FROM pg_amop "
								" WHERE amopopr = :1 ",
								ObjectIdGetDatum(opno)));

	HeapTuple htup = NULL;
	List *opclass_oids = NIL;
	while (HeapTupleIsValid(htup = caql_getnext(pcqCtx)))
	{		
		Form_pg_amop amop_tuple = (Form_pg_amop) GETSTRUCT(htup);

		opclass_oids = lappend_oid(opclass_oids, amop_tuple->amopclaid);
	}
	
	caql_endscan(pcqCtx);
	
	return opclass_oids;
} 

/*
 * get_index_opclasses
 *		Get the oid of classes for the index keys
 */
List *
get_index_opclasses(Oid oidIndex)
{
	cqContext *pcqCtx = caql_beginscan(
							NULL,
							cql("SELECT * FROM pg_index "
								" WHERE indexrelid = :1 ",
								ObjectIdGetDatum(oidIndex)));

	HeapTuple htup = caql_getnext(pcqCtx);

	if (!HeapTupleIsValid(htup))
	{
		elog(ERROR, "Index %u not found", oidIndex);
	}
	
	List *opclass_oids = NIL;

	/*
	* use caql_getattr() to retrieve number of index attributes, and the oid vector of indclass
	*/
    	bool isnull = false;
    	int indnatts = DatumGetInt16(caql_getattr(pcqCtx, Anum_pg_index_indnatts, &isnull));
	Assert(!isnull);

    	Datum indclassDatum = caql_getattr(pcqCtx, Anum_pg_index_indclass, &isnull);
    	if (isnull)
    	{
		return opclass_oids;
    	}
    	oidvector *indclass = (oidvector *) DatumGetPointer(indclassDatum);

	for (int i = 0; i < indnatts; i++)
	{
		Oid oidOpClass = indclass->values[i];
		opclass_oids = lappend_oid(opclass_oids, oidOpClass);
	}
	
	caql_endscan(pcqCtx);
	return opclass_oids;
}

/*
 *  has_parquet_children
 *  Check if relation has a Parquet child relation
 */
bool
has_parquet_children(Oid relationId)
{
	Assert(InvalidOid != relationId);
	List *child_oids = find_all_inheritors(relationId);
	ListCell *lc = NULL;
	
	foreach (lc, child_oids)
	{
		Oid oidChild = lfirst_oid(lc);
		Relation rel = RelationIdGetRelation(oidChild);
		Assert(NULL != rel);
		if (RELSTORAGE_PARQUET == rel->rd_rel->relstorage)
		{
			list_free(child_oids);
			RelationClose(rel);
			return true;
		}

		RelationClose(rel);
	}
	list_free(child_oids);
	return false;
}

/*
 *  relation_policy
 *  Return the distribution policy of a table. 
 */
GpPolicy *
relation_policy(Relation rel)
{
	Assert(NULL != rel);

	/* not a partitioned table */
	return rel->rd_cdbpolicy;
}

/*
 *  child_distribution_mismatch
 *  Return true if the table is partitioned and one of its children has a
 *  different distribution policy. The only allowed mismatch is for the parent
 *  to be hash distributed, and its child part to be randomly distributed.
 */
bool
child_distribution_mismatch(Relation rel)
{
	Assert(NULL != rel);
	if (PART_STATUS_NONE == rel_part_status(rel->rd_id))
	{
		/* not a partitioned table */
		return false;
	}

	GpPolicy *rootPolicy = rel->rd_cdbpolicy;
	Assert(NULL != rootPolicy && "Partitioned tables cannot be master-only");

	if (POLICYTYPE_PARTITIONED == rootPolicy->ptype && 0 == rootPolicy->nattrs)
	{
		/* root partition policy already marked as Random, no mismatch possible as
		 * all children must be random as well */
		return false;
	}

	List *child_oids = find_all_inheritors(rel->rd_id);
	ListCell *lc = NULL;

	foreach (lc, child_oids)
	{
		Oid oidChild = lfirst_oid(lc);
		Relation relChild = RelationIdGetRelation(oidChild);
		Assert(NULL != relChild);

		GpPolicy *childPolicy = relChild->rd_cdbpolicy;
		if (POLICYTYPE_PARTITIONED == childPolicy->ptype && 0 == childPolicy->nattrs)
		{
			/* child partition is Random, and parent is not */
			RelationClose(relChild);
			return true;
		}

		RelationClose(relChild);
	}

	list_free(child_oids);

	/* all children match the root's distribution policy */
	return false;
}

/*
 *  child_triggers
 *  Return true if the table is partitioned and any of the child partitions
 *  have a trigger of the given type.
 */
bool
child_triggers(Oid relationId, int32 triggerType)
{
	Assert(InvalidOid != relationId);
	if (PART_STATUS_NONE == rel_part_status(relationId))
	{
		/* not a partitioned table */
		return false;
	}

	List *childOids = find_all_inheritors(relationId);
	ListCell *lc = NULL;

	bool found = false;
	foreach (lc, childOids)
	{
		Oid oidChild = lfirst_oid(lc);
		Relation relChild = RelationIdGetRelation(oidChild);
		Assert(NULL != relChild);

		if (0 < relChild->rd_rel->reltriggers && NULL == relChild->trigdesc)
		{
			RelationBuildTriggers(relChild);
			if (NULL == relChild->trigdesc)
			{
				relChild->rd_rel->reltriggers = 0;
			}
		}

		for (int i = 0; i < relChild->rd_rel->reltriggers && !found; i++)
		{
			Trigger trigger = relChild->trigdesc->triggers[i];
			found = trigger_enabled(trigger.tgoid) &&
					(get_trigger_type(trigger.tgoid) & triggerType) == triggerType;
		}

		RelationClose(relChild);
		if (found)
		{
			break;
		}
	}

	list_free(childOids);
	
	/* no child triggers matching the given type */
	return found;
}
