/*-------------------------------------------------------------------------
 *
 * not_in.c
 *	  Executes the "not_in" operator for any data type
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/utils/adt/not_in.c,v 1.45 2006/03/23 00:19:30 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
/*
 *
 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 * X HACK WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! X
 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 *
 * This code is the OLD not-in code that is HACKED
 * into place until operators that can have arguments as
 * columns are ******REALLY****** implemented!!!!!!!!!!!
 *
 */

#include "postgres.h"

#include "access/heapam.h"
#include "catalog/namespace.h"
#include "parser/parse_relation.h"
#include "utils/builtins.h"


/* ----------------------------------------------------------------
 *
 * ----------------------------------------------------------------
 */
Datum
int4notin(PG_FUNCTION_ARGS)
{
	int32		not_in_arg = PG_GETARG_INT32(0);
	text	   *relation_and_attr = PG_GETARG_TEXT_P(1);
	List	   *names;
	int			nnames;
	RangeVar   *relrv;
	char	   *attribute;
	Relation	relation_to_scan;
	int32		integer_value;
	HeapTuple	current_tuple;
	HeapScanDesc scan_descriptor;
	bool		isNull,
				retval;
	int			attrid;
	Datum		value;

	/* Parse the argument */

	names = textToQualifiedNameList(relation_and_attr);
	nnames = list_length(names);
	if (nnames < 2)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_NAME),
				 errmsg("invalid name syntax"),
				 errhint("Must provide \"relationname.columnname\".")));
	attribute = strVal(llast(names));
	names = list_truncate(names, nnames - 1);
	relrv = makeRangeVarFromNameList(names);

	/* Open the relation and get a relation descriptor */
	relation_to_scan = heap_openrv(relrv, AccessShareLock);

	/* Find the column to search */
	attrid = attnameAttNum(relation_to_scan, attribute, true);
	if (attrid == InvalidAttrNumber)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("column \"%s\" of relation \"%s\" does not exist",
						attribute,
						RelationGetRelationName(relation_to_scan))));

	scan_descriptor = heap_beginscan(relation_to_scan, SnapshotNow,
									 0, (ScanKey) NULL);

	retval = true;

	/* do a scan of the relation, and do the check */
	while ((current_tuple = heap_getnext(scan_descriptor, ForwardScanDirection)) != NULL)
	{
		value = heap_getattr(current_tuple,
							 (AttrNumber) attrid,
							 RelationGetDescr(relation_to_scan),
							 &isNull);
		if (isNull)
			continue;
		integer_value = DatumGetInt32(value);
		if (not_in_arg == integer_value)
		{
			retval = false;
			break;				/* can stop scanning now */
		}
	}

	/* close the relation */
	heap_endscan(scan_descriptor);
	heap_close(relation_to_scan, AccessShareLock);

	PG_RETURN_BOOL(retval);
}

Datum
oidnotin(PG_FUNCTION_ARGS)
{
	Oid			the_oid = PG_GETARG_OID(0);

#ifdef NOT_USED
	text	   *relation_and_attr = PG_GETARG_TEXT_P(1);
#endif

	if (the_oid == InvalidOid)
		PG_RETURN_BOOL(false);
	/* XXX assume oid maps to int4 */
	return int4notin(fcinfo);
}
