/*-------------------------------------------------------------------------
 *
 * amvalidate.c
 *	  Support routines for index access methods' amvalidate functions.
 *
 * Copyright (c) 2016-2020, PostgreSQL Global Development Group
 *
 *
 * IDENTIFICATION
 *	  src/backend/access/index/amvalidate.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/amvalidate.h"
#include "access/htup_details.h"
#include "catalog/pg_am.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "parser/parse_coerce.h"
#include "utils/syscache.h"


/*
 * identify_opfamily_groups() returns a List of OpFamilyOpFuncGroup structs,
 * one for each combination of lefttype/righttype present in the family's
 * operator and support function lists.  If amopstrategy K is present for
 * this datatype combination, we set bit 1 << K in operatorset, and similarly
 * for the support functions.  With uint64 fields we can handle operator and
 * function numbers up to 63, which is plenty for the foreseeable future.
 *
 * The given CatCLists are expected to represent a single opfamily fetched
 * from the AMOPSTRATEGY and AMPROCNUM caches, so that they will be in
 * order by those caches' second and third cache keys, namely the datatypes.
 */
List *
identify_opfamily_groups(CatCList *oprlist, CatCList *proclist)
{
	List	   *result = NIL;
	OpFamilyOpFuncGroup *thisgroup;
	Form_pg_amop oprform;
	Form_pg_amproc procform;
	int			io,
				ip;

	/* We need the lists to be ordered; should be true in normal operation */
	if (!oprlist->ordered || !proclist->ordered)
		elog(ERROR, "cannot validate operator family without ordered data");

	/*
	 * Advance through the lists concurrently.  Thanks to the ordering, we
	 * should see all operators and functions of a given datatype pair
	 * consecutively.
	 */
	thisgroup = NULL;
	io = ip = 0;
	if (io < oprlist->n_members)
	{
		oprform = (Form_pg_amop) GETSTRUCT(&oprlist->members[io]->tuple);
		io++;
	}
	else
		oprform = NULL;
	if (ip < proclist->n_members)
	{
		procform = (Form_pg_amproc) GETSTRUCT(&proclist->members[ip]->tuple);
		ip++;
	}
	else
		procform = NULL;

	while (oprform || procform)
	{
		if (oprform && thisgroup &&
			oprform->amoplefttype == thisgroup->lefttype &&
			oprform->amoprighttype == thisgroup->righttype)
		{
			/* Operator belongs to current group; include it and advance */

			/* Ignore strategy numbers outside supported range */
			if (oprform->amopstrategy > 0 && oprform->amopstrategy < 64)
				thisgroup->operatorset |= ((uint64) 1) << oprform->amopstrategy;

			if (io < oprlist->n_members)
			{
				oprform = (Form_pg_amop) GETSTRUCT(&oprlist->members[io]->tuple);
				io++;
			}
			else
				oprform = NULL;
			continue;
		}

		if (procform && thisgroup &&
			procform->amproclefttype == thisgroup->lefttype &&
			procform->amprocrighttype == thisgroup->righttype)
		{
			/* Procedure belongs to current group; include it and advance */

			/* Ignore function numbers outside supported range */
			if (procform->amprocnum > 0 && procform->amprocnum < 64)
				thisgroup->functionset |= ((uint64) 1) << procform->amprocnum;

			if (ip < proclist->n_members)
			{
				procform = (Form_pg_amproc) GETSTRUCT(&proclist->members[ip]->tuple);
				ip++;
			}
			else
				procform = NULL;
			continue;
		}

		/* Time for a new group */
		thisgroup = (OpFamilyOpFuncGroup *) palloc(sizeof(OpFamilyOpFuncGroup));
		if (oprform &&
			(!procform ||
			 (oprform->amoplefttype < procform->amproclefttype ||
			  (oprform->amoplefttype == procform->amproclefttype &&
			   oprform->amoprighttype < procform->amprocrighttype))))
		{
			thisgroup->lefttype = oprform->amoplefttype;
			thisgroup->righttype = oprform->amoprighttype;
		}
		else
		{
			thisgroup->lefttype = procform->amproclefttype;
			thisgroup->righttype = procform->amprocrighttype;
		}
		thisgroup->operatorset = thisgroup->functionset = 0;
		result = lappend(result, thisgroup);
	}

	return result;
}

/*
 * Validate the signature (argument and result types) of an opclass support
 * function.  Return true if OK, false if not.
 *
 * The "..." represents maxargs argument-type OIDs.  If "exact" is true, they
 * must match the function arg types exactly, else only binary-coercibly.
 * In any case the function result type must match restype exactly.
 */
bool
check_amproc_signature(Oid funcid, Oid restype, bool exact,
					   int minargs, int maxargs,...)
{
	bool		result = true;
	HeapTuple	tp;
	Form_pg_proc procform;
	va_list		ap;
	int			i;

	tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
	if (!HeapTupleIsValid(tp))
		elog(ERROR, "cache lookup failed for function %u", funcid);
	procform = (Form_pg_proc) GETSTRUCT(tp);

	if (procform->prorettype != restype || procform->proretset ||
		procform->pronargs < minargs || procform->pronargs > maxargs)
		result = false;

	va_start(ap, maxargs);
	for (i = 0; i < maxargs; i++)
	{
		Oid			argtype = va_arg(ap, Oid);

		if (i >= procform->pronargs)
			continue;
		if (exact ? (argtype != procform->proargtypes.values[i]) :
			!IsBinaryCoercible(argtype, procform->proargtypes.values[i]))
			result = false;
	}
	va_end(ap);

	ReleaseSysCache(tp);
	return result;
}

/*
 * Validate the signature of an opclass options support function, that should
 * be 'void(internal)'.
 */
bool
check_amoptsproc_signature(Oid funcid)
{
	return check_amproc_signature(funcid, VOIDOID, true, 1, 1, INTERNALOID);
}

/*
 * Validate the signature (argument and result types) of an opclass operator.
 * Return true if OK, false if not.
 *
 * Currently, we can hard-wire this as accepting only binary operators.  Also,
 * we can insist on exact type matches, since the given lefttype/righttype
 * come from pg_amop and should always match the operator exactly.
 */
bool
check_amop_signature(Oid opno, Oid restype, Oid lefttype, Oid righttype)
{
	bool		result = true;
	HeapTuple	tp;
	Form_pg_operator opform;

	tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno));
	if (!HeapTupleIsValid(tp))	/* shouldn't happen */
		elog(ERROR, "cache lookup failed for operator %u", opno);
	opform = (Form_pg_operator) GETSTRUCT(tp);

	if (opform->oprresult != restype || opform->oprkind != 'b' ||
		opform->oprleft != lefttype || opform->oprright != righttype)
		result = false;

	ReleaseSysCache(tp);
	return result;
}

/*
 * Is the datatype a legitimate input type for the btree opfamily?
 */
bool
opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid)
{
	bool		result = false;
	CatCList   *opclist;
	int			i;

	/*
	 * We search through all btree opclasses to see if one matches.  This is a
	 * bit inefficient but there is no better index available.  It also saves
	 * making an explicit check that the opfamily belongs to btree.
	 */
	opclist = SearchSysCacheList1(CLAAMNAMENSP, ObjectIdGetDatum(BTREE_AM_OID));

	for (i = 0; i < opclist->n_members; i++)
	{
		HeapTuple	classtup = &opclist->members[i]->tuple;
		Form_pg_opclass classform = (Form_pg_opclass) GETSTRUCT(classtup);

		if (classform->opcfamily == opfamilyoid &&
			classform->opcintype == datatypeoid)
		{
			result = true;
			break;
		}
	}

	ReleaseCatCacheList(opclist);

	return result;
}
