/*
 * PostgreSQL Tagged Types
 * Written by Martijn van Oosterhout (C) Aug 2005
 * kleptog@svana.org
 * http://svana.org/kleptog/pgsql/taggedtypes.html
 *
 * See COPYING file for licence details
 *
 *	$PostgreSQL: $
 *
 * Header file, common definitions
 */

#include "postgres.h"
#include "parser/parse_type.h"   /* parseTypeString */
#include "executor/spi.h"
#include "funcapi.h"

#include "nodes/makefuncs.h"   /* makeRangeVar */
#include "utils/fmgroids.h"    /* F_OIDEQ and F_TEXTEQ */
#include "catalog/pg_operator.h"   /* Form_pg_operator */

#include "taggedtypesuser.h"

//#define DEBUG

#ifndef DEBUG
#undef elog
#define elog(...)    do { } while(0)
#endif

// Per backend limit, until get full dynamic storage sorted out

#define TAGGED_TABLE_NAMESPACE	"taggedtypes"
#define TAGGED_TABLE_NAME	"taggedtypes"
#define TAGGED_OPERATOR_NAME	"taggedoperators"

#define TAGGED_TABLE_FULLNAME   TAGGED_TABLE_NAMESPACE "." TAGGED_TABLE_NAME
#define TAGGED_OPERATOR_FULLNAME	TAGGED_TABLE_NAMESPACE "." TAGGED_OPERATOR_NAME

#define TAGGED_TYPE_CACHE	8
#define TAGGED_OPERATOR_CACHE	16

typedef struct taggedtyped  // Datum type (byval)
{
	Oid		tag;
	Datum		val;
}	taggedtyped;

typedef struct taggedtypef  // Fixed length
{
	Oid		tag;
	char		val[4];
}	taggedtypef;

typedef struct taggedtypev  // Variable length
{
	int4		len;
	Oid		tag;
	char		val[4];
}	taggedtypev;

struct TaggedTypeInfo
{
	int	timestamp;	/* For LRU algorithm */
	
	/* These first four represent the column in the taggedtypes table */
	Oid	tagtype;        /* OID of tagged type */
	Oid	basetype;       /* OID of base type */
	int32	typmod;         /* typmod from base type */
	Oid	tagtable;       /* OID of tagtable */
	
	/* These two are stored info relating to the base type */
	Oid	typinput;
	Oid	typoutput;
	int16	typlen;  
	bool	typbyval;
	Oid	typapplytypmod;  /* function to apply typmod (for numeric etc) */
};

struct TaggedOperatorInfo
{
	int	timestamp;	/* For LRU algorithm */
	
	/* These first three represent the column in the taggedoperators table */
	Oid	tagoper;        /* OID of tagged operator */
	Oid	baseoper;       /* OID of base operator */
	Oid	tagfunc;	/* OID of tagged function */
	
	/* These are from the pg_operator table */
	Oid	basefunc;	/* OID of base function */
};

typedef int TaggedTypeClass;

#define isTaggedTypeDatum( ttc ) (ttc == 0)
#define isTaggedTypeFixed( ttc ) (ttc > 0)
#define isTaggedTypeVar( ttc )   (ttc == -1)

// Turns a text into a char*
static inline char *text_to_charp( text * t )
{
  char *s = (char*) palloc( VARSIZE( t ) );
  
  memcpy( s, VARDATA( t ), VARSIZE( t ) - VARHDRSZ );
  s[ VARSIZE( t ) - VARHDRSZ ] = 0;
  
  return s;
}

