/*
*	writeset.h (wb)
*	
*	Contains data structures and prototypes relating to write sets and
*	write set processing
*
*/

#ifndef WRITESET_H
#define WRITESET_H

#include "access/attnum.h"
#include "access/htup.h"
#include "lib/dllist.h"
#include "executor/tuptable.h"


#define TUPLE_LIMIT 50
#define WS_BUF_SIZE 8192

/* (mc) allow the following for debugging purposes */

/*  swu comment out
#define WS_DEBUG_LOCAL
#define WS_DEBUG_REMOTE
#define WS_SER_DEBUG

#define WS_PRINT
#define WS_PRINT_LOW_LEVEL*/


typedef struct
{
	Dllist 	*list;
	int		size;
} SizedList;

/*
* IdxInfo contains informatioon about prim.key index
* and is used by the remote bknd to find target tuples
*
*	indexName - name of the index
*	indexOid - oid of the index
*	numKeys - number of keys of the index
*	attrNums - attribute numbers of the pkey attributes
*				in the indexed relation
*	equalProcs - procedure oids for the '=' operation
*				for the different index attribute types
*				Used by remote bknd to de index scan
*
* XXX -- surely this functionality already exists? -neil
*
*/

typedef struct
{
	char			indexName[NAMEDATALEN];
	Oid				indexOid;
	int 			numKeys;
	AttrNumber		attrNums[INDEX_MAX_KEYS];
	RegProcedure	equalProcs[INDEX_MAX_KEYS];
} IdxInfo;

/*
*	RelInfo contains info about a target relationm
*
*	name - the target relation name
*	relOid - the target relation oid
*	indexinfo - primary key index info
*	queryList - list of query info structs containing
*				queries that modify this relation
*/
typedef struct
{
	char		name[NAMEDATALEN+1];
	Oid			relOid;
	IdxInfo		indexinfo;
	SizedList	querylist;
} RelInfo;

/*
*	TupleCollection contains info relating to tuple-level
*	replication
*
*	rel - points back to the associated relation info object
*	numAttrs - total number of attributes in the relation
*	changeArray - contains 1 char for each attribute, indicates wheter
*					the attr has been changed by the query or not
*					'r' means changed, ' ' means unchanged
*	maxTuples - the maximum number of tuples this struct can contain
*	numTuples - the number of tuples this struct contains at the moment
*
*	pkey_values - array of strings containing the primary key values
*					of each tuple in the collection
  *	newtup_data - array of strings containing the modified attribute's
*					new values for each tuple in the collection
*/
typedef struct
{
	RelInfo 	*rel;
	
	int			numAttrs;
	char		*changeArray;

	int 		maxTuples;
	int			numTuples;

	char		**pkey_values;
	char		**newtup_data;
} TupleCollection;

/*
* CmdInfo contains general info  about a query
*
*	cmd - the query type
*	sect - the query's execution section
*	stmt - the query string 
*/
typedef struct
{
	CmdType cmd;
	int		sect;//(oi)
	char 	*stmt;
} CmdInfo;

/*
* QueryInfo contains  info about a query
*
*	info - misc info about query
*	tcoll - all tuples modified by this query
*/
typedef struct
{
	CmdInfo			info;
	TupleCollection	tcoll;
} QueryInfo;


/* (mc) */
typedef enum WSType
{
	QUERY_WS,
	UTILITY_WS,
	UNKNOWN_WS
} WSType;
/**/

/*
* Write set structure
*
*	targetrels - list of RelationInfo structs of all relations
*					modified in the current write set
*	currQuery - the currently processed query info struct
*				(see WriteSetAddQuery)
*	critSect - local backend: is used to distribute the execution 
*				section numbers when the write set is marshaled
*			   remote backend: holds the highest excecution section
*				number in the current write set.				
*/
typedef  struct
{
	WSType		wsType; 	/* (mc) either utility or query */
	SizedList 	targetrels;
	CmdInfo		*currQuery;
	int			critSect; 
} WriteSet;

/*Per backend writeset (wb)*/
extern WriteSet MyWriteSet;

/* (mc) */
extern WriteSet MyPeerWriteSet;
/**/

typedef  struct
{
	uint32		hostid;
	uint32		xid;
} TxnId;

typedef WriteSet *WriteSetPtr;


/* DAR HACK these global structs used to be in miscadm.h and
    maybe one day they will be there again */

/* (mc) not required for a Master/Slave approach
extern bool  may_not_abort_right_now;
extern int WriteSetWaitOnLock(char **relNames, int granted[],
							  int numNames);
*/
extern void WriteSetInit(WriteSetPtr ws);
extern void WriteSetFree(WriteSetPtr ws);
extern void WriteSetAddQuery(WriteSetPtr ws, char *query, CmdType cmd, char* relname);
extern void WriteSetAddUtility(WriteSetPtr ws, char *query);
extern bool sendComplementaryWS(Node *utilityStmt, int *TableOrView);
extern char *WriteSetFormCompUtility(Node *utilityStmt, int TableOrView);
extern  bool WriteSetAllowUtility(bool isMaster, Node *utilityStmt, bool *replicate);

extern void WriteSetCollectTuple(ItemPointer origTuple, TupleTableSlot *slot, CmdInfo *currQuery);

extern HeapTuple WriteSetFormTuple(Relation rel, HeapTuple oldTuple, 
												char *newtup_data, TupleDesc tdesc);
extern void WriteSetGetDatum(Datum *values, char *data, int numTargets, 
											AttrNumber *TargetNums, TupleDesc tdesc);
extern void WriteSetGetChangedAtts(List *targetlist, char *changeArray, int numAttrs);
extern void WriteSetSerialize(WriteSetPtr ws, ebufptr extbuf);
extern void WriteSetUnserialize(WriteSetPtr ws, bufsockptr bsock);
extern void WriteSetProcess(WriteSetPtr ws, bool doTxnDelim);
extern void WriteSetOnExit(int dummy, WriteSetPtr ws);

//#ifdef WS_PRINT
void printWriteSet(WriteSetPtr ws, const char *comment);
//#endif
/* (mc) */
void WriteSetVerifyTuples(WriteSetPtr ws);

/*  swu */
extern Datum get_writeset(PG_FUNCTION_ARGS);
extern Datum put_writeset(PG_FUNCTION_ARGS);
#endif
