/*-------------------------------------------------------------------------
 *
 * index.h
 *	  prototypes for catalog/index.c.
 *
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.71 2006/08/25 04:06:55 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
#ifndef INDEX_H
#define INDEX_H

#include "access/relscan.h"     /* Relation, Snapshot */
#include "executor/tuptable.h"  /* TupTableSlot */

struct EState;                  /* #include "nodes/execnodes.h" */

#define DEFAULT_INDEX_TYPE	"btree"

/* ----------------
 *	  IndexInfo information
 *
 *		this struct holds the information needed to construct new index
 *		entries for a particular index.  Used for both index_build and
 *		retail creation of index entries.
 *
 *    NumIndexAttrs   total number of columns in this index
 *    NumIndexKeyAttrs  number of key columns in index
 *		KeyAttrNumbers		underlying-rel attribute numbers used as keys
 *		          (zeroes indicate expressions). It also contains
 *		          info about included columns.
 *		Expressions			expr trees for expression entries, or NIL if none
 *		ExpressionsState	exec state for expressions, or NIL if none
 *		Predicate			partial-index predicate, or NIL if none
 *		PredicateState		exec state for predicate, or NIL if none
 *		Unique				is it a unique index?
 *		Concurrent			are we doing a concurrent index build?
 *
 *      CDB: Moved this declaration from nodes/execnodes.h into catalog/index.h
 * ----------------
 */
typedef struct IndexInfo
{
	NodeTag		type;
	int   ii_NumIndexAttrs;     /* total number of columns in index */
	int   ii_NumIndexKeyAttrs;  /* number of key columns in index */
	AttrNumber	ii_KeyAttrNumbers[INDEX_MAX_KEYS];
	List	   *ii_Expressions; /* list of Expr */
	List	   *ii_ExpressionsState;	/* list of ExprState */
	List	   *ii_Predicate;	/* list of Expr */
	List	   *ii_PredicateState;		/* list of ExprState */
	bool		ii_Unique;
	bool		ii_Concurrent;

	/* Additional info needed by index creation.
	 * Used for
	 * (1) bitmap indexes to store oids that are needed for lov heap and lov index.
	 * (2) append-only tables to store oids for their block directory relations
	 *     and indexes
	 */
	void       *opaque;

} IndexInfo;

typedef struct IndexInfoOpaque
{
	Oid        comptypeOid; /* the complex type oid for the lov heap. */
	Oid        heapOid;  /* Oid for the lov heap in the bitmap index. */
	Oid        indexOid; /* Oid for the lov index in the bitmap index. */
	Oid        heapRelfilenode; /* Oid for the relfilenode of the lov heap in the bitmap index. */
	Oid        indexRelfilenode;/* Oid for the relfilenode of the lov index in the bitmap index. */
	Oid        blkdirRelOid; /* Oid for block directory relation */
	Oid        blkdirIdxOid; /* Oid for block directory index */
	Oid        blkdirComptypeOid; /* complex type Oid for block directry relation */
} IndexInfoOpaque;

/* Use for magma index info */
typedef struct MagmaIndexInfo
{
	char *indexName;
	int2vector *indkey;  // index on these columns
	char *indexType;  // index type, default is btree
	int  keynums;  // number of key columns in index
	bool unique;
	bool primary;
} MagmaIndexInfo;

/* Typedef for callback function for IndexBuildScan */
typedef void (*IndexBuildCallback) (Relation index,
									ItemPointer tupleId,
									Datum *values,
									bool *isnull,
									bool tupleIsAlive,
									void *state);


extern Oid index_create(Oid heapRelationId,
			 const char *indexRelationName,
			 Oid indexRelationId,
			 struct IndexInfo *indexInfo,
			 Oid accessMethodObjectId,
			 Oid tableSpaceId,
			 Oid *classObjectId,
			 Datum reloptions,
			 bool isprimary,
			 bool isconstraint,
			 Oid *constrOid,
			 bool allow_system_table_mods,
			 bool skip_build,
			 bool concurrent,
			 const char *altConName);

extern void ext_constraint_create(Oid extRelationId,
                                  struct IndexInfo *constraintInfo,
                                  bool isPrimary,
                                  bool allowSystemTableMods);

extern void index_drop(Oid indexId);

extern struct IndexInfo *BuildIndexInfo(Relation index);

extern void FormIndexDatum(struct IndexInfo *indexInfo,
			   TupleTableSlot *slot,
			   struct EState *estate,
			   Datum *values,
			   bool *isnull);

extern void index_build(Relation heapRelation,
			Relation indexRelation,
			struct IndexInfo *indexInfo,
			bool isprimary);

extern double IndexBuildScan(Relation heapRelation,
				   Relation indexRelation,
				   struct IndexInfo *indexInfo,
				   IndexBuildCallback callback,
				   void *callback_state);

extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);

extern Oid reindex_index(Oid indexId, Oid newrelfilenode, List **extra_oids);
extern bool reindex_relation(Oid relid, bool toast_too, bool aoseg_too, bool aoblkdir_too,
							 List **oidmap, bool build_map);

extern Oid IndexGetRelation(Oid indexId);

#endif   /* INDEX_H */
