diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c
index 05dbe87..f439403 100644
--- a/contrib/bloom/blutils.c
+++ b/contrib/bloom/blutils.c
@@ -36,8 +36,8 @@
 
 PG_FUNCTION_INFO_V1(blhandler);
 
-/* Kind of relation optioms for bloom index */
-static relopt_kind bl_relopt_kind;
+/* Catalog of relation options for bloom index */
+static options_catalog bl_relopt_catalog;
 
 static int32 myRand(void);
 static void mySrand(uint32 seed);
@@ -51,15 +51,18 @@ _PG_init(void)
 	int			i;
 	char		buf[16];
 
-	bl_relopt_kind = add_reloption_kind();
+	bl_relopt_catalog.definitions = NULL;
+	bl_relopt_catalog.num = 0;
+	bl_relopt_catalog.max = 0;
+	bl_relopt_catalog.need_initialization = 1;
 
-	add_int_reloption(bl_relopt_kind, "length",
+	add_int_reloption(0, &bl_relopt_catalog, "length",
 					  "Length of signature in uint16 type", 5, 1, 256);
 
 	for (i = 0; i < INDEX_MAX_KEYS; i++)
 	{
 		snprintf(buf, 16, "col%d", i + 1);
-		add_int_reloption(bl_relopt_kind, buf,
+		add_int_reloption(0, &bl_relopt_catalog, buf,
 					  "Number of bits for corresponding column", 2, 1, 2048);
 	}
 }
@@ -104,6 +107,7 @@ blhandler(PG_FUNCTION_ARGS)
 	amroutine->amcostestimate = blcostestimate;
 	amroutine->amoptions = bloptions;
 	amroutine->amvalidate = blvalidate;
+	amroutine->amattoptions = NULL;
 
 	PG_RETURN_POINTER(amroutine);
 }
@@ -457,7 +461,7 @@ bloptions(Datum reloptions, bool validate)
 		tab[i + 1].offset = offsetof(BloomOptions, bitSize[i]);
 	}
 
-	options = parseRelOptions(reloptions, validate, bl_relopt_kind, &numoptions);
+	options = parseRelOptions(reloptions, validate, &bl_relopt_catalog, 0, &numoptions);
 	rdopts = allocateReloptStruct(sizeof(BloomOptions), options, numoptions);
 	fillRelOptions((void *) rdopts, sizeof(BloomOptions), options, numoptions,
 				   validate, tab, INDEX_MAX_KEYS + 1);
diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h
index d524f0f..a05350f 100644
--- a/contrib/intarray/_int.h
+++ b/contrib/intarray/_int.h
@@ -47,15 +47,24 @@
 
 
 /* bigint defines */
-#define SIGLENINT  63			/* >122 => key will toast, so very slow!!! */
-#define SIGLEN	( sizeof(int)*SIGLENINT )
-#define SIGLENBIT (SIGLEN*BITS_PER_BYTE)
+//#define SIGLENINT  63			/* >122 => key will toast, so very slow!!! */
+//#define SIGLEN	( sizeof(int)*SIGLENINT )
+//#define SIGLENBIT (SIGLEN*BITS_PER_BYTE)
 
-typedef char BITVEC[SIGLEN];
+
+#define SIGLEN_BYTES(i) (sizeof(int)*i)	   /* array signature length in bytes */
+#define SIGLEN_BITS(i) \
+			(SIGLEN_BYTES(i)*BITS_PER_BYTE) /* array signature length in bits */
+
+
+//typedef char BITVEC[SIGLEN];
 typedef char *BITVECP;
 
-#define LOOPBYTE \
-			for(i=0;i<SIGLEN;i++)
+//#define LOOPBYTE \
+//			for(i=0;i<SIGLEN;i++)
+
+#define LOOPBYTE_NEW(siglenint) \
+			for(i=0;i<SIGLEN_BYTES(siglenint);i++)
 
 /* beware of multiple evaluation of arguments to these macros! */
 #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
@@ -63,8 +72,12 @@ typedef char *BITVECP;
 #define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
 #define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITS_PER_BYTE ) )
 #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
-#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
-#define HASH(sign, val) SETBIT((sign), HASHVAL(val))
+
+//#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
+#define HASHVAL_NEW(val, siglenint) (((unsigned int)(val)) % (unsigned int)(SIGLEN_BITS(siglenint)))
+
+//#define HASH(sign, val) SETBIT((sign), HASHVAL(val))
+#define HASH_NEW(sign, val, siglenint) SETBIT((sign), HASHVAL_NEW(val, siglenint))
 
 /*
  * type of index key
@@ -76,12 +89,23 @@ typedef struct
 	char		data[FLEXIBLE_ARRAY_MEMBER];
 } GISTTYPE;
 
+/* intarray opclass options */
+typedef struct IntArrayOpclassOptions
+{
+	int32		vl_len_;		/* varlena header (do not touch directly!) */
+	int			sig_len_int;	/* FIXME comment */
+}	IntArrayOpclassOptions;
+
+
 #define ALLISTRUE		0x04
 
 #define ISALLTRUE(x)	( ((GISTTYPE*)x)->flag & ALLISTRUE )
 
 #define GTHDRSIZE		(VARHDRSZ + sizeof(int32))
-#define CALCGTSIZE(flag) ( GTHDRSIZE+(((flag) & ALLISTRUE) ? 0 : SIGLEN) )
+
+#define GT_EMPTY_SIZE	GTHDRSIZE
+
+#define GT_SIZE(siglenint) (GTHDRSIZE + SIGLEN_BYTES(siglenint))
 
 #define GETSIGN(x)		( (BITVECP)( (char*)x+GTHDRSIZE ) )
 
@@ -94,6 +118,7 @@ typedef void (*formfloat) (ArrayType *, float *);
 /*
  * useful functions
  */
+extern void _PG_init(void);
 bool		isort(int32 *a, int len);
 ArrayType  *new_intArrayType(int num);
 ArrayType  *copy_intArrayType(ArrayType *a);
@@ -109,7 +134,7 @@ bool		inner_int_contains(ArrayType *a, ArrayType *b);
 ArrayType  *inner_int_union(ArrayType *a, ArrayType *b);
 ArrayType  *inner_int_inter(ArrayType *a, ArrayType *b);
 void		rt__int_size(ArrayType *a, float *size);
-void		gensign(BITVEC sign, int *a, int len);
+//void		gensign(BITVECP sign, int *a, int len, void *options);
 
 
 /*****************************************************************************
@@ -155,7 +180,7 @@ typedef struct QUERYTYPE
 #define PG_GETARG_QUERYTYPE_P(n)	  DatumGetQueryTypeP(PG_GETARG_DATUM(n))
 #define PG_GETARG_QUERYTYPE_P_COPY(n) DatumGetQueryTypePCopy(PG_GETARG_DATUM(n))
 
-bool		signconsistent(QUERYTYPE *query, BITVEC sign, bool calcnot);
+bool		signconsistent(QUERYTYPE *query, BITVECP sign, bool calcnot, void *options);
 bool		execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot);
 
 bool		gin_bool_consistent(QUERYTYPE *query, bool *check);
diff --git a/contrib/intarray/_int_bool.c b/contrib/intarray/_int_bool.c
index 5d9e676..02d09f6 100644
--- a/contrib/intarray/_int_bool.c
+++ b/contrib/intarray/_int_bool.c
@@ -233,7 +233,7 @@ typedef struct
  * is there value 'val' in (sorted) array or not ?
  */
 static bool
-checkcondition_arr(void *checkval, ITEM *item)
+checkcondition_arr(void *checkval, ITEM *item, void *options)
 {
 	int32	   *StopLow = ((CHKVAL *) checkval)->arrb;
 	int32	   *StopHigh = ((CHKVAL *) checkval)->arre;
@@ -254,43 +254,48 @@ checkcondition_arr(void *checkval, ITEM *item)
 	return false;
 }
 
+
 static bool
-checkcondition_bit(void *checkval, ITEM *item)
+checkcondition_bit(void *checkval, ITEM *item, void *options)
 {
-	return GETBIT(checkval, HASHVAL(item->val));
+	  IntArrayOpclassOptions* attoptions;
+
+	attoptions = (IntArrayOpclassOptions*) options;
+	return GETBIT(checkval, HASHVAL_NEW(item->val, attoptions->sig_len_int));
 }
 
+
 /*
  * evaluate boolean expression, using chkcond() to test the primitive cases
  */
 static bool
-execute(ITEM *curitem, void *checkval, bool calcnot,
-		bool (*chkcond) (void *checkval, ITEM *item))
+execute(ITEM *curitem, void *checkval, bool calcnot, void *options,
+		bool (*chkcond) (void *checkval, ITEM *item, void *options))
 {
 	/* since this function recurses, it could be driven to stack overflow */
 	check_stack_depth();
 
 	if (curitem->type == VAL)
-		return (*chkcond) (checkval, curitem);
+		return (*chkcond) (checkval, curitem, options);
 	else if (curitem->val == (int32) '!')
 	{
 		return (calcnot) ?
-			((execute(curitem - 1, checkval, calcnot, chkcond)) ? false : true)
+			((execute(curitem - 1, checkval, calcnot, options, chkcond)) ? false : true)
 			: true;
 	}
 	else if (curitem->val == (int32) '&')
 	{
-		if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
-			return execute(curitem - 1, checkval, calcnot, chkcond);
+		if (execute(curitem + curitem->left, checkval, calcnot, options, chkcond))
+			return execute(curitem - 1, checkval, calcnot, options, chkcond);
 		else
 			return false;
 	}
 	else
 	{							/* |-operator */
-		if (execute(curitem + curitem->left, checkval, calcnot, chkcond))
+		if (execute(curitem + curitem->left, checkval, calcnot, options, chkcond))
 			return true;
 		else
-			return execute(curitem - 1, checkval, calcnot, chkcond);
+			return execute(curitem - 1, checkval, calcnot, options, chkcond);
 	}
 }
 
@@ -298,10 +303,10 @@ execute(ITEM *curitem, void *checkval, bool calcnot,
  * signconsistent & execconsistent called by *_consistent
  */
 bool
-signconsistent(QUERYTYPE *query, BITVEC sign, bool calcnot)
+signconsistent(QUERYTYPE *query, BITVECP sign, bool calcnot, void *options)
 {
 	return execute(GETQUERY(query) + query->size - 1,
-				   (void *) sign, calcnot,
+				   (void *) sign, calcnot, options,
 				   checkcondition_bit);
 }
 
@@ -315,7 +320,7 @@ execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot)
 	chkval.arrb = ARRPTR(array);
 	chkval.arre = chkval.arrb + ARRNELEMS(array);
 	return execute(GETQUERY(query) + query->size - 1,
-				   (void *) &chkval, calcnot,
+				   (void *) &chkval, calcnot, NULL,
 				   checkcondition_arr);
 }
 
@@ -326,7 +331,7 @@ typedef struct
 } GinChkVal;
 
 static bool
-checkcondition_gin(void *checkval, ITEM *item)
+checkcondition_gin(void *checkval, ITEM *item, void *options)
 {
 	GinChkVal  *gcv = (GinChkVal *) checkval;
 
@@ -357,7 +362,7 @@ gin_bool_consistent(QUERYTYPE *query, bool *check)
 	}
 
 	return execute(GETQUERY(query) + query->size - 1,
-				   (void *) &gcv, true,
+				   (void *) &gcv, true, NULL,
 				   checkcondition_gin);
 }
 
@@ -430,7 +435,7 @@ boolop(PG_FUNCTION_ARGS)
 	chkval.arre = chkval.arrb + ARRNELEMS(val);
 	result = execute(GETQUERY(query) + query->size - 1,
 					 &chkval, true,
-					 checkcondition_arr);
+					 NULL, checkcondition_arr);
 	pfree(val);
 
 	PG_FREE_IF_COPY(query, 1);
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index 3c52912..52085e4 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -312,8 +312,9 @@ _int_unique(ArrayType *r)
 	return resize_intArrayType(r, dr + 1 - ARRPTR(r));
 }
 
+#if 0
 void
-gensign(BITVEC sign, int *a, int len)
+gensign(BITVEC sign, int *a, int len, int siglenint)
 {
 	int			i;
 
@@ -324,6 +325,7 @@ gensign(BITVEC sign, int *a, int len)
 		a++;
 	}
 }
+#endif
 
 int32
 intarray_match_first(ArrayType *a, int32 elem)
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index 6dae7c91..af4c16b 100644
--- a/contrib/intarray/_intbig_gist.c
+++ b/contrib/intarray/_intbig_gist.c
@@ -5,6 +5,7 @@
 
 #include "access/gist.h"
 #include "access/stratnum.h"
+#include "access/reloptions.h"
 
 #include "_int.h"
 
@@ -19,6 +20,7 @@ PG_FUNCTION_INFO_V1(g_intbig_penalty);
 PG_FUNCTION_INFO_V1(g_intbig_picksplit);
 PG_FUNCTION_INFO_V1(g_intbig_union);
 PG_FUNCTION_INFO_V1(g_intbig_same);
+PG_FUNCTION_INFO_V1(g_intbig_attoptions);
 
 /* Number of one-bits in an unsigned byte */
 static const uint8 number_of_ones[256] = {
@@ -43,6 +45,30 @@ static const uint8 number_of_ones[256] = {
 PG_FUNCTION_INFO_V1(_intbig_in);
 PG_FUNCTION_INFO_V1(_intbig_out);
 
+/* Catalog of relation options for bloom index */
+static options_catalog intbig_gist_attopt_catalog;
+
+
+void
+_PG_init(void)
+{
+	intbig_gist_attopt_catalog.definitions = NULL;
+	intbig_gist_attopt_catalog.num = 0;
+	intbig_gist_attopt_catalog.max = 0;
+	intbig_gist_attopt_catalog.need_initialization = 1;
+
+	add_int_reloption(0, &intbig_gist_attopt_catalog, "sig_len_int",
+					  "FIXME description", /*63*/ 120, 10, 122);  //FIXME limits
+
+//  elog(WARNING, "_intbig_gist.c _PG_init");
+}
+
+BITVECP
+new_bitvec(int siglenint)
+{
+  return (BITVECP) palloc0(SIGLEN_BYTES(siglenint));
+}
+
 Datum
 _intbig_in(PG_FUNCTION_ARGS)
 {
@@ -66,7 +92,7 @@ _intbig_out(PG_FUNCTION_ARGS)
 ** intbig functions
 *********************************************************************/
 static bool
-_intbig_overlap(GISTTYPE *a, ArrayType *b)
+_intbig_overlap(GISTTYPE *a, ArrayType *b, int siglenint)
 {
 	int			num = ARRNELEMS(b);
 	int32	   *ptr = ARRPTR(b);
@@ -75,7 +101,8 @@ _intbig_overlap(GISTTYPE *a, ArrayType *b)
 
 	while (num--)
 	{
-		if (GETBIT(GETSIGN(a), HASHVAL(*ptr)))
+		if (GETBIT(GETSIGN(a), HASHVAL_NEW(*ptr,siglenint)))
+		
 			return true;
 		ptr++;
 	}
@@ -84,7 +111,7 @@ _intbig_overlap(GISTTYPE *a, ArrayType *b)
 }
 
 static bool
-_intbig_contains(GISTTYPE *a, ArrayType *b)
+_intbig_contains(GISTTYPE *a, ArrayType *b, int siglenint)
 {
 	int			num = ARRNELEMS(b);
 	int32	   *ptr = ARRPTR(b);
@@ -93,7 +120,9 @@ _intbig_contains(GISTTYPE *a, ArrayType *b)
 
 	while (num--)
 	{
-		if (!GETBIT(GETSIGN(a), HASHVAL(*ptr)))
+		if (!GETBIT(GETSIGN(a), HASHVAL_NEW(*ptr, siglenint)))
+
+		
 			return false;
 		ptr++;
 	}
@@ -107,6 +136,10 @@ g_intbig_same(PG_FUNCTION_ARGS)
 	GISTTYPE   *a = (GISTTYPE *) PG_GETARG_POINTER(0);
 	GISTTYPE   *b = (GISTTYPE *) PG_GETARG_POINTER(1);
 	bool	   *result = (bool *) PG_GETARG_POINTER(2);
+	IntArrayOpclassOptions *attoptions =
+								(IntArrayOpclassOptions *) PG_GETARG_POINTER(3);
+
+//elog(WARNING, "g_intbig_same!!; sig_len_int=%i", attoptions->sig_len_int);
 
 	if (ISALLTRUE(a) && ISALLTRUE(b))
 		*result = true;
@@ -121,7 +154,8 @@ g_intbig_same(PG_FUNCTION_ARGS)
 					sb = GETSIGN(b);
 
 		*result = true;
-		LOOPBYTE
+//		for(i=0;i<SIGLEN;i++)
+		LOOPBYTE_NEW(attoptions->sig_len_int)
 		{
 			if (sa[i] != sb[i])
 			{
@@ -137,6 +171,10 @@ Datum
 g_intbig_compress(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+	IntArrayOpclassOptions *attoptions =
+								(IntArrayOpclassOptions *) PG_GETARG_POINTER(1);
+
+//elog(WARNING, "g_intbig_compress!!; sig_len_int=%i", attoptions->sig_len_int);
 
 	if (entry->leafkey)
 	{
@@ -144,8 +182,7 @@ g_intbig_compress(PG_FUNCTION_ARGS)
 		ArrayType  *in = DatumGetArrayTypeP(entry->key);
 		int32	   *ptr;
 		int			num;
-		GISTTYPE   *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));
-
+		GISTTYPE  *res = (GISTTYPE *) palloc0(GT_SIZE(attoptions->sig_len_int));
 		CHECKARRVALID(in);
 		if (ARRISEMPTY(in))
 		{
@@ -157,11 +194,11 @@ g_intbig_compress(PG_FUNCTION_ARGS)
 			ptr = ARRPTR(in);
 			num = ARRNELEMS(in);
 		}
-		SET_VARSIZE(res, CALCGTSIZE(0));
+		SET_VARSIZE(res, GT_SIZE(attoptions->sig_len_int));
 
 		while (num--)
 		{
-			HASH(GETSIGN(res), *ptr);
+			HASH_NEW(GETSIGN(res), *ptr, attoptions->sig_len_int);
 			ptr++;
 		}
 
@@ -182,14 +219,14 @@ g_intbig_compress(PG_FUNCTION_ARGS)
 		BITVECP		sign = GETSIGN(DatumGetPointer(entry->key));
 		GISTTYPE   *res;
 
-		LOOPBYTE
+		LOOPBYTE_NEW(attoptions->sig_len_int)
 		{
 			if ((sign[i] & 0xff) != 0xff)
 				PG_RETURN_POINTER(entry);
 		}
 
-		res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
-		SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
+		res = (GISTTYPE *) palloc(GT_EMPTY_SIZE);
+		SET_VARSIZE(res, GT_EMPTY_SIZE);
 		res->flag = ALLISTRUE;
 
 		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
@@ -205,24 +242,22 @@ g_intbig_compress(PG_FUNCTION_ARGS)
 
 
 static int32
-sizebitvec(BITVECP sign)
+sizebitvec(BITVECP sign, IntArrayOpclassOptions *attoptions)
 {
 	int32		size = 0,
 				i;
-
-	LOOPBYTE
+	LOOPBYTE_NEW(attoptions->sig_len_int)
 		size += number_of_ones[(unsigned char) sign[i]];
 	return size;
 }
 
 static int
-hemdistsign(BITVECP a, BITVECP b)
+hemdistsign(BITVECP a, BITVECP b, IntArrayOpclassOptions *attoptions)
 {
 	int			i,
 				diff,
 				dist = 0;
-
-	LOOPBYTE
+	LOOPBYTE_NEW(attoptions->sig_len_int)
 	{
 		diff = (unsigned char) (a[i] ^ b[i]);
 		dist += number_of_ones[diff];
@@ -231,19 +266,20 @@ hemdistsign(BITVECP a, BITVECP b)
 }
 
 static int
-hemdist(GISTTYPE *a, GISTTYPE *b)
+hemdist(GISTTYPE *a, GISTTYPE *b, IntArrayOpclassOptions *attoptions)
 {
+	int siglen_bits = SIGLEN_BITS(attoptions->sig_len_int);
 	if (ISALLTRUE(a))
 	{
 		if (ISALLTRUE(b))
 			return 0;
 		else
-			return SIGLENBIT - sizebitvec(GETSIGN(b));
+			return siglen_bits - sizebitvec(GETSIGN(b), attoptions);
 	}
 	else if (ISALLTRUE(b))
-		return SIGLENBIT - sizebitvec(GETSIGN(a));
+		return siglen_bits - sizebitvec(GETSIGN(a), attoptions);
 
-	return hemdistsign(GETSIGN(a), GETSIGN(b));
+	return hemdistsign(GETSIGN(a), GETSIGN(b), attoptions);
 }
 
 Datum
@@ -253,14 +289,14 @@ g_intbig_decompress(PG_FUNCTION_ARGS)
 }
 
 static int32
-unionkey(BITVECP sbase, GISTTYPE *add)
+unionkey(BITVECP sbase, GISTTYPE *add, IntArrayOpclassOptions *attoptions)
 {
 	int32		i;
 	BITVECP		sadd = GETSIGN(add);
 
 	if (ISALLTRUE(add))
 		return 1;
-	LOOPBYTE
+	LOOPBYTE_NEW(attoptions->sig_len_int)
 		sbase[i] |= sadd[i];
 	return 0;
 }
@@ -270,28 +306,40 @@ g_intbig_union(PG_FUNCTION_ARGS)
 {
 	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 	int		   *size = (int *) PG_GETARG_POINTER(1);
-	BITVEC		base;
+	IntArrayOpclassOptions *attoptions =
+								(IntArrayOpclassOptions *) PG_GETARG_POINTER(2);
+	BITVECP		base;
 	int32		i,
 				len;
 	int32		flag = 0;
 	GISTTYPE   *result;
+/*
+if (attoptions->sig_len_int == 63)
+{
+elog(WARNING, "g_intbig_compress!!; Right! sig_len_int=%i", attoptions->sig_len_int);
+} else
+{
+elog(WARNING, "g_intbig_compress!!; Wrong!!!!! sig_len_int=%i", attoptions->sig_len_int);
 
-	MemSet((void *) base, 0, sizeof(BITVEC));
+}*/
+//	MemSet((void *) base, 0, SIGLEN_BYTES(attoptions->sig_len_int)); // may be here will be better GT_SIZE(attoptions->sig_len_int)-GT_EMPTY_SIZE the same value but may be more clear
+	base = new_bitvec(attoptions->sig_len_int);
 	for (i = 0; i < entryvec->n; i++)
 	{
-		if (unionkey(base, GETENTRY(entryvec, i)))
+		if (unionkey(base, GETENTRY(entryvec, i), attoptions))
 		{
 			flag = ALLISTRUE;
 			break;
 		}
 	}
 
-	len = CALCGTSIZE(flag);
+	len = ((flag) & ALLISTRUE) ? GT_EMPTY_SIZE : GT_SIZE(attoptions->sig_len_int);
+	
 	result = (GISTTYPE *) palloc(len);
 	SET_VARSIZE(result, len);
 	result->flag = flag;
 	if (!ISALLTRUE(result))
-		memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
+		memcpy((void *) GETSIGN(result), (void *) base, SIGLEN_BYTES(attoptions->sig_len_int));
 	*size = len;
 
 	PG_RETURN_POINTER(result);
@@ -303,10 +351,14 @@ g_intbig_penalty(PG_FUNCTION_ARGS)
 	GISTENTRY  *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
 	GISTENTRY  *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
 	float	   *penalty = (float *) PG_GETARG_POINTER(2);
+	IntArrayOpclassOptions *attoptions =
+								(IntArrayOpclassOptions *) PG_GETARG_POINTER(3);
 	GISTTYPE   *origval = (GISTTYPE *) DatumGetPointer(origentry->key);
 	GISTTYPE   *newval = (GISTTYPE *) DatumGetPointer(newentry->key);
 
-	*penalty = hemdist(origval, newval);
+//elog(WARNING, "g_intbig_penalty!!; sig_len_int=%i", attoptions->sig_len_int);
+
+	*penalty = hemdist(origval, newval, attoptions);
 	PG_RETURN_POINTER(penalty);
 }
 
@@ -329,6 +381,9 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 {
 	GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
 	GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+	IntArrayOpclassOptions *attoptions =
+								(IntArrayOpclassOptions *) PG_GETARG_POINTER(2);
+
 	OffsetNumber k,
 				j;
 	GISTTYPE   *datum_l,
@@ -350,6 +405,10 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 	SPLITCOST  *costvector;
 	GISTTYPE   *_k,
 			   *_j;
+	int			siglen;
+
+//elog(WARNING, "g_intbig_picksplit!!");
+//elog(WARNING, "sig_len_int=%i", attoptions->sig_len_int);
 
 	maxoff = entryvec->n - 2;
 	nbytes = (maxoff + 2) * sizeof(OffsetNumber);
@@ -361,7 +420,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 		_k = GETENTRY(entryvec, k);
 		for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
 		{
-			size_waste = hemdist(_k, GETENTRY(entryvec, j));
+			size_waste = hemdist(_k, GETENTRY(entryvec, j),attoptions);
 			if (size_waste > waste)
 			{
 				waste = size_waste;
@@ -381,7 +440,7 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 		seed_1 = 1;
 		seed_2 = 2;
 	}
-
+	siglen = SIGLEN_BYTES(attoptions->sig_len_int);
 	/* form initial .. */
 	if (ISALLTRUE(GETENTRY(entryvec, seed_1)))
 	{
@@ -391,10 +450,10 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 	}
 	else
 	{
-		datum_l = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN);
-		SET_VARSIZE(datum_l, GTHDRSIZE + SIGLEN);
+		datum_l = (GISTTYPE *) palloc(GTHDRSIZE + siglen);
+		SET_VARSIZE(datum_l, GTHDRSIZE + siglen);
 		datum_l->flag = 0;
-		memcpy((void *) GETSIGN(datum_l), (void *) GETSIGN(GETENTRY(entryvec, seed_1)), sizeof(BITVEC));
+		memcpy((void *) GETSIGN(datum_l), (void *) GETSIGN(GETENTRY(entryvec, seed_1)), SIGLEN_BYTES(attoptions->sig_len_int));
 	}
 	if (ISALLTRUE(GETENTRY(entryvec, seed_2)))
 	{
@@ -404,10 +463,10 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 	}
 	else
 	{
-		datum_r = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN);
-		SET_VARSIZE(datum_r, GTHDRSIZE + SIGLEN);
+		datum_r = (GISTTYPE *) palloc(GTHDRSIZE + siglen);
+		SET_VARSIZE(datum_r, GTHDRSIZE + siglen);
 		datum_r->flag = 0;
-		memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), sizeof(BITVEC));
+		memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), SIGLEN_BYTES(attoptions->sig_len_int));
 	}
 
 	maxoff = OffsetNumberNext(maxoff);
@@ -417,8 +476,8 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 	{
 		costvector[j - 1].pos = j;
 		_j = GETENTRY(entryvec, j);
-		size_alpha = hemdist(datum_l, _j);
-		size_beta = hemdist(datum_r, _j);
+		size_alpha = hemdist(datum_l, _j, attoptions);
+		size_beta = hemdist(datum_r, _j, attoptions);
 		costvector[j - 1].cost = Abs(size_alpha - size_beta);
 	}
 	qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
@@ -442,20 +501,20 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 			continue;
 		}
 		_j = GETENTRY(entryvec, j);
-		size_alpha = hemdist(datum_l, _j);
-		size_beta = hemdist(datum_r, _j);
+		size_alpha = hemdist(datum_l, _j, attoptions);
+		size_beta = hemdist(datum_r, _j, attoptions);
 
 		if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
 		{
 			if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_l))
-					MemSet((void *) union_l, 0xff, sizeof(BITVEC));
+					MemSet((void *) union_l, 0xff, SIGLEN_BYTES(attoptions->sig_len_int));
 			}
 			else
 			{
 				ptr = GETSIGN(_j);
-				LOOPBYTE
+				LOOPBYTE_NEW(attoptions->sig_len_int)
 					union_l[i] |= ptr[i];
 			}
 			*left++ = j;
@@ -466,12 +525,12 @@ g_intbig_picksplit(PG_FUNCTION_ARGS)
 			if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
 			{
 				if (!ISALLTRUE(datum_r))
-					MemSet((void *) union_r, 0xff, sizeof(BITVEC));
+					MemSet((void *) union_r, 0xff, SIGLEN_BYTES(attoptions->sig_len_int));
 			}
 			else
 			{
 				ptr = GETSIGN(_j);
-				LOOPBYTE
+				LOOPBYTE_NEW(attoptions->sig_len_int)
 					union_r[i] |= ptr[i];
 			}
 			*right++ = j;
@@ -497,8 +556,13 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	bool	   *recheck = (bool *) PG_GETARG_POINTER(4);
+	IntArrayOpclassOptions *attoptions =
+								(IntArrayOpclassOptions *) PG_GETARG_POINTER(5);
+
 	bool		retval;
 
+//elog(WARNING, "g_intbig_consistent!!; sig_len_int=%i", attoptions->sig_len_int);
+
 	/* All cases served by this function are inexact */
 	*recheck = true;
 
@@ -509,7 +573,7 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 	{
 		retval = signconsistent((QUERYTYPE *) query,
 								GETSIGN(DatumGetPointer(entry->key)),
-								false);
+								false, (void*)attoptions);
 		PG_FREE_IF_COPY(query, 1);
 		PG_RETURN_BOOL(retval);
 	}
@@ -519,7 +583,7 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 	switch (strategy)
 	{
 		case RTOverlapStrategyNumber:
-			retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query);
+			retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query, attoptions->sig_len_int);
 			break;
 		case RTSameStrategyNumber:
 			if (GIST_LEAF(entry))
@@ -527,22 +591,22 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 				int			i,
 							num = ARRNELEMS(query);
 				int32	   *ptr = ARRPTR(query);
-				BITVEC		qp;
+				BITVECP		qp;
 				BITVECP		dq,
 							de;
 
-				memset(qp, 0, sizeof(BITVEC));
-
+//				memset(qp, 0, SIGLEN_BYTES(attoptions->sig_len_int));
+				qp = new_bitvec(attoptions->sig_len_int);
 				while (num--)
 				{
-					HASH(qp, *ptr);
+					HASH_NEW(qp, *ptr, attoptions->sig_len_int);
 					ptr++;
 				}
 
 				de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
 				dq = qp;
 				retval = true;
-				LOOPBYTE
+				LOOPBYTE_NEW(attoptions->sig_len_int)
 				{
 					if (de[i] != dq[i])
 					{
@@ -553,11 +617,11 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 
 			}
 			else
-				retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key), query);
+				retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key), query, attoptions->sig_len_int);
 			break;
 		case RTContainsStrategyNumber:
 		case RTOldContainsStrategyNumber:
-			retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key), query);
+			retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key), query, attoptions->sig_len_int);
 			break;
 		case RTContainedByStrategyNumber:
 		case RTOldContainedByStrategyNumber:
@@ -566,22 +630,22 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 				int			i,
 							num = ARRNELEMS(query);
 				int32	   *ptr = ARRPTR(query);
-				BITVEC		qp;
+				BITVECP		qp;
 				BITVECP		dq,
 							de;
 
-				memset(qp, 0, sizeof(BITVEC));
-
+//				memset(qp, 0, SIGLEN_BYTES(attoptions->sig_len_int));
+				qp = new_bitvec(attoptions->sig_len_int);
 				while (num--)
 				{
-					HASH(qp, *ptr);
+					HASH_NEW(qp, *ptr, attoptions->sig_len_int);
 					ptr++;
 				}
 
 				de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
 				dq = qp;
 				retval = true;
-				LOOPBYTE
+				LOOPBYTE_NEW(attoptions->sig_len_int)
 				{
 					if (de[i] & ~dq[i])
 					{
@@ -591,7 +655,7 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 				}
 			}
 			else
-				retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query);
+				retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query, attoptions->sig_len_int);
 			break;
 		default:
 			retval = FALSE;
@@ -599,3 +663,46 @@ g_intbig_consistent(PG_FUNCTION_ARGS)
 	PG_FREE_IF_COPY(query, 1);
 	PG_RETURN_BOOL(retval);
 }
+
+Datum
+g_intbig_attoptions(PG_FUNCTION_ARGS)
+{
+	relopt_value *options;
+	int			numoptions;
+	IntArrayOpclassOptions *attopts;
+	MemoryContext oldcxt;
+	Datum raw_options = PG_GETARG_DATUM(0);
+	bool validate = PG_GETARG_BOOL(1);
+	relopt_parse_elt tab[] =
+		{{"sig_len_int", RELOPT_TYPE_INT, offsetof(IntArrayOpclassOptions, sig_len_int)}};
+
+
+	options = parseRelOptions(raw_options, validate, &intbig_gist_attopt_catalog, 0, &numoptions);
+	attopts = allocateReloptStruct(sizeof(IntArrayOpclassOptions), options, numoptions);
+
+	fillRelOptions((void *) attopts, sizeof(IntArrayOpclassOptions), options, numoptions,
+				   validate, tab, 1);
+				   
+//	elog(WARNING, "************* %i", attopts->sig_len_int);
+
+//	oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+//	attopts = palloc0(sizeof(IntArrayOpclassOptions));  //FIXME do something else with this palloc
+//	MemoryContextSwitchTo(oldcxt);
+
+//	attopts->sig_len_int = 10;
+
+//	attopts->sig_len_int = 63;
+//	attopts->sig_len_int = 77;
+//	attopts->sig_len_int = 120;
+
+
+	
+	
+//	char s[] = "Awe postgres!";
+//	char * copy;
+//	elog(WARNING, "g_int_getattopdesc!!");
+//	copy = palloc(sizeof(s));
+//	memcpy(copy,s,sizeof(s));
+	PG_RETURN_POINTER(attopts);
+}
+
diff --git a/contrib/intarray/intarray--1.1.sql b/contrib/intarray/intarray--1.1.sql
index 6ee0d5a..23be554 100644
--- a/contrib/intarray/intarray--1.1.sql
+++ b/contrib/intarray/intarray--1.1.sql
@@ -394,6 +394,7 @@ AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
 
+
 -- Create the operator class for indexing
 
 CREATE OPERATOR CLASS gist__int_ops
@@ -413,7 +414,6 @@ DEFAULT FOR TYPE _int4 USING gist AS
 	FUNCTION	6	g_int_picksplit (internal, internal),
 	FUNCTION	7	g_int_same (_int4, _int4, internal);
 
-
 ---------------------------------------------
 -- intbig
 ---------------------------------------------
@@ -435,12 +435,12 @@ CREATE TYPE intbig_gkey (
         OUTPUT = _intbig_out
 );
 
-CREATE FUNCTION g_intbig_consistent(internal,_int4,smallint,oid,internal)
+CREATE FUNCTION g_intbig_consistent(internal,_int4,smallint,oid,internal,internal)
 RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
-CREATE FUNCTION g_intbig_compress(internal)
+CREATE FUNCTION g_intbig_compress(internal, internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
@@ -450,26 +450,31 @@ RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
-CREATE FUNCTION g_intbig_penalty(internal,internal,internal)
+CREATE FUNCTION g_intbig_penalty(internal, internal, internal, internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
-CREATE FUNCTION g_intbig_picksplit(internal, internal)
+CREATE FUNCTION g_intbig_picksplit(internal, internal, internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
-CREATE FUNCTION g_intbig_union(internal, internal)
+CREATE FUNCTION g_intbig_union(internal, internal, internal)
 RETURNS intbig_gkey
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
-CREATE FUNCTION g_intbig_same(intbig_gkey, intbig_gkey, internal)
+CREATE FUNCTION g_intbig_same(intbig_gkey, intbig_gkey, internal, internal)
 RETURNS internal
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
+CREATE FUNCTION g_intbig_attoptions(internal, boolean)
+RETURNS internal
+AS 'MODULE_PATHNAME', 'g_intbig_attoptions'
+LANGUAGE C IMMUTABLE STRICT;
+
 -- register the opclass for indexing (not as default)
 
 CREATE OPERATOR CLASS gist__intbig_ops
@@ -482,13 +487,15 @@ AS
 	OPERATOR	13	@,
 	OPERATOR	14	~,
 	OPERATOR	20	@@ (_int4, query_int),
-	FUNCTION	1	g_intbig_consistent (internal, _int4, smallint, oid, internal),
-	FUNCTION	2	g_intbig_union (internal, internal),
-	FUNCTION	3	g_intbig_compress (internal),
+	FUNCTION	1	g_intbig_consistent (internal, _int4, smallint, oid, internal, internal),
+	FUNCTION	2	g_intbig_union (internal, internal, internal),
+	FUNCTION	3	g_intbig_compress (internal, internal),
 	FUNCTION	4	g_intbig_decompress (internal),
-	FUNCTION	5	g_intbig_penalty (internal, internal, internal),
-	FUNCTION	6	g_intbig_picksplit (internal, internal),
-	FUNCTION	7	g_intbig_same (intbig_gkey, intbig_gkey, internal),
+	FUNCTION	5	g_intbig_penalty (internal, internal, internal, internal),
+	FUNCTION	6	g_intbig_picksplit (internal, internal, internal),
+	FUNCTION	7	g_intbig_same (intbig_gkey, intbig_gkey, internal, internal),
+	FUNCTION	10	g_intbig_attoptions(internal, boolean),
+
 	STORAGE		intbig_gkey;
 
 --GIN
@@ -503,6 +510,8 @@ RETURNS bool
 AS 'MODULE_PATHNAME'
 LANGUAGE C IMMUTABLE STRICT;
 
+
+
 CREATE OPERATOR CLASS gin__int_ops
 FOR TYPE _int4 USING gin
 AS
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 89bad05..797f367 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -110,6 +110,7 @@ brinhandler(PG_FUNCTION_ARGS)
 	amroutine->amendscan = brinendscan;
 	amroutine->ammarkpos = NULL;
 	amroutine->amrestrpos = NULL;
+	amroutine->amattoptions = NULL;
 
 	PG_RETURN_POINTER(amroutine);
 }
@@ -761,7 +762,7 @@ brinoptions(Datum reloptions, bool validate)
 		{"pages_per_range", RELOPT_TYPE_INT, offsetof(BrinOptions, pagesPerRange)}
 	};
 
-	options = parseRelOptions(reloptions, validate, RELOPT_KIND_BRIN,
+	options = parseRelOptions(reloptions, validate, NULL, RELOPT_KIND_BRIN,
 							  &numoptions);
 
 	/* if none set, we're done */
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 7448c7f..a665130 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -378,6 +378,7 @@ static bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT;
 static int	num_custom_options = 0;
 static relopt_gen **custom_options = NULL;
 static bool need_initialization = true;
+static int	max_custom_options = 0;
 
 static void initialize_reloptions(void);
 static void parse_one_reloption(relopt_value *option, char *text_str,
@@ -496,32 +497,31 @@ add_reloption_kind(void)
  *		main parser table.
  */
 static void
-add_reloption(relopt_gen *newoption)
+add_reloption(relopt_gen *newoption, options_catalog * catalog)
 {
-	static int	max_custom_options = 0;
-
-	if (num_custom_options >= max_custom_options)
+	if (catalog->num + 1 >= catalog->max)
 	{
 		MemoryContext oldcxt;
 
 		oldcxt = MemoryContextSwitchTo(TopMemoryContext);
 
-		if (max_custom_options == 0)
+		if (catalog->max == 0)
 		{
-			max_custom_options = 8;
-			custom_options = palloc(max_custom_options * sizeof(relopt_gen *));
+			catalog->max = 8;
+			catalog->definitions = palloc(catalog->max * sizeof(relopt_gen *));
 		}
 		else
 		{
-			max_custom_options *= 2;
-			custom_options = repalloc(custom_options,
-								  max_custom_options * sizeof(relopt_gen *));
+			catalog->max *= 2;
+			catalog->definitions = repalloc(catalog->definitions,
+								  catalog->max * sizeof(relopt_gen *));
 		}
 		MemoryContextSwitchTo(oldcxt);
 	}
-	custom_options[num_custom_options++] = newoption;
-
-	need_initialization = true;
+	catalog->definitions[catalog->num] = newoption;
+	catalog->definitions[catalog->num + 1] = NULL;
+	catalog->num++;
+	catalog->need_initialization = true;
 }
 
 /*
@@ -578,15 +578,33 @@ allocate_reloption(bits32 kinds, int type, char *name, char *desc)
  *		Add a new boolean reloption
  */
 void
-add_bool_reloption(bits32 kinds, char *name, char *desc, bool default_val)
+add_bool_reloption(bits32 kinds, options_catalog * catalog,
+									char *name, char *desc, bool default_val)
 {
 	relopt_bool *newoption;
 
 	newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL,
 												   name, desc);
 	newoption->default_val = default_val;
-
-	add_reloption((relopt_gen *) newoption);
+	
+	if (catalog)
+	{
+		add_reloption((relopt_gen *) newoption, catalog);
+	} else
+	{
+		options_catalog  static_catalog;
+		static_catalog.num = num_custom_options;
+		static_catalog.max = max_custom_options;
+		static_catalog.need_initialization = need_initialization;
+		static_catalog.definitions = custom_options;
+
+		add_reloption((relopt_gen *) newoption, &static_catalog);
+
+		num_custom_options = static_catalog.num;
+		max_custom_options = static_catalog.max;
+		need_initialization = static_catalog.need_initialization;
+		custom_options = static_catalog.definitions;
+	}
 }
 
 /*
@@ -594,8 +612,8 @@ add_bool_reloption(bits32 kinds, char *name, char *desc, bool default_val)
  *		Add a new integer reloption
  */
 void
-add_int_reloption(bits32 kinds, char *name, char *desc, int default_val,
-				  int min_val, int max_val)
+add_int_reloption(bits32 kinds, options_catalog * catalog,
+			char *name, char *desc, int default_val, int min_val, int max_val)
 {
 	relopt_int *newoption;
 
@@ -605,7 +623,24 @@ add_int_reloption(bits32 kinds, char *name, char *desc, int default_val,
 	newoption->min = min_val;
 	newoption->max = max_val;
 
-	add_reloption((relopt_gen *) newoption);
+	if (catalog)
+	{
+		add_reloption((relopt_gen *) newoption, catalog);
+	} else
+	{
+		options_catalog  static_catalog;
+		static_catalog.num = num_custom_options;
+		static_catalog.max = max_custom_options;
+		static_catalog.need_initialization = need_initialization;
+		static_catalog.definitions = custom_options;
+
+		add_reloption((relopt_gen *) newoption, &static_catalog);
+
+		num_custom_options = static_catalog.num;
+		max_custom_options = static_catalog.max;
+		need_initialization = static_catalog.need_initialization;
+		custom_options = static_catalog.definitions;
+	}
 }
 
 /*
@@ -613,8 +648,9 @@ add_int_reloption(bits32 kinds, char *name, char *desc, int default_val,
  *		Add a new float reloption
  */
 void
-add_real_reloption(bits32 kinds, char *name, char *desc, double default_val,
-				   double min_val, double max_val)
+add_real_reloption(bits32 kinds, options_catalog * catalog,
+							char *name, char *desc, double default_val,
+										double min_val, double max_val)
 {
 	relopt_real *newoption;
 
@@ -624,7 +660,24 @@ add_real_reloption(bits32 kinds, char *name, char *desc, double default_val,
 	newoption->min = min_val;
 	newoption->max = max_val;
 
-	add_reloption((relopt_gen *) newoption);
+	if (catalog)
+	{
+		add_reloption((relopt_gen *) newoption, catalog);
+	} else
+	{
+		options_catalog  static_catalog;
+		static_catalog.num = num_custom_options;
+		static_catalog.max = max_custom_options;
+		static_catalog.need_initialization = need_initialization;
+		static_catalog.definitions = custom_options;
+
+		add_reloption((relopt_gen *) newoption, &static_catalog);
+
+		num_custom_options = static_catalog.num;
+		max_custom_options = static_catalog.max;
+		need_initialization = static_catalog.need_initialization;
+		custom_options = static_catalog.definitions;
+	}
 }
 
 /*
@@ -637,8 +690,8 @@ add_real_reloption(bits32 kinds, char *name, char *desc, double default_val,
  * the validation.
  */
 void
-add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
-					 validate_string_relopt validator)
+add_string_reloption(bits32 kinds, options_catalog * catalog, char *name,
+			char *desc, char *default_val, validate_string_relopt validator)
 {
 	relopt_string *newoption;
 
@@ -663,7 +716,24 @@ add_string_reloption(bits32 kinds, char *name, char *desc, char *default_val,
 		newoption->default_isnull = true;
 	}
 
-	add_reloption((relopt_gen *) newoption);
+	if (catalog)
+	{
+		add_reloption((relopt_gen *) newoption, catalog);
+	} else
+	{
+		options_catalog  static_catalog;
+		static_catalog.num = num_custom_options;
+		static_catalog.max = max_custom_options;
+		static_catalog.need_initialization = need_initialization;
+		static_catalog.definitions = custom_options;
+
+		add_reloption((relopt_gen *) newoption, &static_catalog);
+
+		num_custom_options = static_catalog.num;
+		max_custom_options = static_catalog.max;
+		need_initialization = static_catalog.need_initialization;
+		custom_options = static_catalog.definitions;
+	}
 }
 
 /*
@@ -714,13 +784,13 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
 
 		deconstruct_array(array, TEXTOID, -1, false, 'i',
 						  &oldoptions, NULL, &noldoptions);
-
 		for (i = 0; i < noldoptions; i++)
 		{
 			text	   *oldoption = DatumGetTextP(oldoptions[i]);
 			char	   *text_str = VARDATA(oldoption);
 			int			text_len = VARSIZE(oldoption) - VARHDRSZ;
 
+//elog(WARNING, "parsing option %s",text_str);
 			/* Search for a match in defList */
 			foreach(cell, defList)
 			{
@@ -832,6 +902,8 @@ transformRelOptions(Datum oldOptions, List *defList, char *namspace,
 			t = (text *) palloc(len + 1);
 			SET_VARSIZE(t, len);
 			sprintf(VARDATA(t), "%s=%s", def->defname, value);
+			
+//elog(WARNING, "parsing option %s=%s", def->defname, value);
 
 			astate = accumArrayResult(astate, PointerGetDatum(t),
 									  false, TEXTOID,
@@ -964,21 +1036,31 @@ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
  * be freed by the caller.
  */
 relopt_value *
-parseRelOptions(Datum options, bool validate, relopt_kind kind,
-				int *numrelopts)
+parseRelOptions(Datum options, bool validate, options_catalog * catalog,
+				relopt_kind kind, int *numrelopts)
 {
 	relopt_value *reloptions;
 	int			numoptions = 0;
 	int			i;
 	int			j;
+	options_catalog static_catalog;
 
 	if (need_initialization)
 		initialize_reloptions();
 
+	if (! catalog)
+	{
+		static_catalog.definitions = relOpts;
+		catalog = &static_catalog;
+	} else
+	{
+		Assert(kind == 0);
+	}
+
 	/* Build a list of expected options, based on kind */
 
-	for (i = 0; relOpts[i]; i++)
-		if (relOpts[i]->kinds & kind)
+	for (i = 0; catalog->definitions[i]; i++)
+		if (! kind || (catalog->definitions[i]->kinds & kind))
 			numoptions++;
 
 	if (numoptions == 0)
@@ -989,11 +1071,11 @@ parseRelOptions(Datum options, bool validate, relopt_kind kind,
 
 	reloptions = palloc(numoptions * sizeof(relopt_value));
 
-	for (i = 0, j = 0; relOpts[i]; i++)
+	for (i = 0, j = 0; catalog->definitions[i]; i++)
 	{
-		if (relOpts[i]->kinds & kind)
+		if (! kind || (catalog->definitions[i]->kinds & kind))
 		{
-			reloptions[j].gen = relOpts[i];
+			reloptions[j].gen = catalog->definitions[i];
 			reloptions[j].isset = false;
 			j++;
 		}
@@ -1305,7 +1387,7 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
 		offsetof(StdRdOptions, parallel_degree)}
 	};
 
-	options = parseRelOptions(reloptions, validate, kind, &numoptions);
+	options = parseRelOptions(reloptions, validate, NULL, kind, &numoptions);
 
 	/* if none set, we're done */
 	if (numoptions == 0)
@@ -1337,7 +1419,7 @@ view_reloptions(Datum reloptions, bool validate)
 		offsetof(ViewOptions, check_option_offset)}
 	};
 
-	options = parseRelOptions(reloptions, validate, RELOPT_KIND_VIEW, &numoptions);
+	options = parseRelOptions(reloptions, validate, NULL, RELOPT_KIND_VIEW, &numoptions);
 
 	/* if none set, we're done */
 	if (numoptions == 0)
@@ -1417,7 +1499,7 @@ attribute_reloptions(Datum reloptions, bool validate)
 		{"n_distinct_inherited", RELOPT_TYPE_REAL, offsetof(AttributeOpts, n_distinct_inherited)}
 	};
 
-	options = parseRelOptions(reloptions, validate, RELOPT_KIND_ATTRIBUTE,
+	options = parseRelOptions(reloptions, validate, NULL, RELOPT_KIND_ATTRIBUTE,
 							  &numoptions);
 
 	/* if none set, we're done */
@@ -1449,7 +1531,7 @@ tablespace_reloptions(Datum reloptions, bool validate)
 		{"effective_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, effective_io_concurrency)}
 	};
 
-	options = parseRelOptions(reloptions, validate, RELOPT_KIND_TABLESPACE,
+	options = parseRelOptions(reloptions, validate, NULL, RELOPT_KIND_TABLESPACE,
 							  &numoptions);
 
 	/* if none set, we're done */
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index a2450f4..051c90e 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -65,6 +65,7 @@ ginhandler(PG_FUNCTION_ARGS)
 	amroutine->amendscan = ginendscan;
 	amroutine->ammarkpos = NULL;
 	amroutine->amrestrpos = NULL;
+	amroutine->amattoptions = NULL;
 
 	PG_RETURN_POINTER(amroutine);
 }
@@ -573,7 +574,7 @@ ginoptions(Datum reloptions, bool validate)
 													 pendingListCleanupSize)}
 	};
 
-	options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIN,
+	options = parseRelOptions(reloptions, validate, NULL, RELOPT_KIND_GIN,
 							  &numoptions);
 
 	/* if none set, we're done */
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index a290887..4a76e2d 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -87,6 +87,7 @@ gisthandler(PG_FUNCTION_ARGS)
 	amroutine->amendscan = gistendscan;
 	amroutine->ammarkpos = NULL;
 	amroutine->amrestrpos = NULL;
+	amroutine->amattoptions = gistattoptions;
 
 	PG_RETURN_POINTER(amroutine);
 }
@@ -1421,6 +1422,7 @@ initGISTstate(Relation index)
 	giststate->scanCxt = scanCxt;
 	giststate->tempCxt = scanCxt;		/* caller must change this if needed */
 	giststate->tupdesc = index->rd_att;
+	giststate->attoptions = get_index_attribute_options(index);
 
 	for (i = 0; i < index->rd_att->natts; i++)
 	{
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index affd635..f73bbac 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -193,11 +193,13 @@ gistindex_keytest(IndexScanDesc scan,
 			Datum		test;
 			bool		recheck;
 			GISTENTRY	de;
+			bytea*		attoptions;
 
 			gistdentryinit(giststate, key->sk_attno - 1, &de,
 						   datum, r, page, offset,
 						   FALSE, isNull);
 
+			attoptions = giststate->attoptions[key->sk_attno - 1];
 			/*
 			 * Call the Consistent function to evaluate the test.  The
 			 * arguments are the index datum (as a GISTENTRY*), the comparison
@@ -213,13 +215,14 @@ gistindex_keytest(IndexScanDesc scan,
 			 */
 			recheck = true;
 
-			test = FunctionCall5Coll(&key->sk_func,
+			test = FunctionCall6Coll(&key->sk_func,
 									 key->sk_collation,
 									 PointerGetDatum(&de),
 									 key->sk_argument,
 									 Int16GetDatum(key->sk_strategy),
 									 ObjectIdGetDatum(key->sk_subtype),
-									 PointerGetDatum(&recheck));
+									 PointerGetDatum(&recheck),
+									 PointerGetDatum(attoptions));
 
 			if (!DatumGetBool(test))
 				return false;
diff --git a/src/backend/access/gist/gistsplit.c b/src/backend/access/gist/gistsplit.c
index d394969..93bd937 100644
--- a/src/backend/access/gist/gistsplit.c
+++ b/src/backend/access/gist/gistsplit.c
@@ -378,18 +378,20 @@ genericPickSplit(GISTSTATE *giststate, GistEntryVector *entryvec, GIST_SPLITVEC
 	evec->n = v->spl_nleft;
 	memcpy(evec->vector, entryvec->vector + FirstOffsetNumber,
 		   sizeof(GISTENTRY) * evec->n);
-	v->spl_ldatum = FunctionCall2Coll(&giststate->unionFn[attno],
+	v->spl_ldatum = FunctionCall3Coll(&giststate->unionFn[attno],
 									  giststate->supportCollation[attno],
 									  PointerGetDatum(evec),
-									  PointerGetDatum(&nbytes));
+									  PointerGetDatum(&nbytes),
+								PointerGetDatum(giststate->attoptions[attno]));
 
 	evec->n = v->spl_nright;
 	memcpy(evec->vector, entryvec->vector + FirstOffsetNumber + v->spl_nleft,
 		   sizeof(GISTENTRY) * evec->n);
-	v->spl_rdatum = FunctionCall2Coll(&giststate->unionFn[attno],
+	v->spl_rdatum = FunctionCall3Coll(&giststate->unionFn[attno],
 									  giststate->supportCollation[attno],
 									  PointerGetDatum(evec),
-									  PointerGetDatum(&nbytes));
+									  PointerGetDatum(&nbytes),
+								PointerGetDatum(giststate->attoptions[attno]));
 }
 
 /*
@@ -425,15 +427,16 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GistSplitVec
 	sv->spl_rdatum_exists = (v->spl_risnull[attno]) ? false : true;
 	sv->spl_ldatum = v->spl_lattr[attno];
 	sv->spl_rdatum = v->spl_rattr[attno];
-
+	
 	/*
 	 * Let the opclass-specific PickSplit method do its thing.  Note that at
 	 * this point we know there are no null keys in the entryvec.
 	 */
-	FunctionCall2Coll(&giststate->picksplitFn[attno],
+	FunctionCall3Coll(&giststate->picksplitFn[attno],
 					  giststate->supportCollation[attno],
 					  PointerGetDatum(entryvec),
-					  PointerGetDatum(sv));
+					  PointerGetDatum(sv),
+					  PointerGetDatum(giststate->attoptions[attno]));
 
 	if (sv->spl_nleft == 0 || sv->spl_nright == 0)
 	{
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index fac166d..60fe6de 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -21,6 +21,13 @@
 #include "storage/lmgr.h"
 #include "utils/builtins.h"
 
+#include "access/htup_details.h"
+#include "utils/syscache.h"
+#include "utils/catcache.h"
+
+#include "catalog/pg_opclass.h"
+#include "catalog/pg_opfamily.h"
+#include "catalog/pg_amproc.h"
 
 /*
  * Write itup vector to page, has no control of free space.
@@ -195,10 +202,11 @@ gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len,
 			}
 
 			/* Make union and store in attr array */
-			attr[i] = FunctionCall2Coll(&giststate->unionFn[i],
+			attr[i] = FunctionCall3Coll(&giststate->unionFn[i],
 										giststate->supportCollation[i],
 										PointerGetDatum(evec),
-										PointerGetDatum(&attrsize));
+										PointerGetDatum(&attrsize),
+								PointerGetDatum(giststate->attoptions[i]));
 
 			isnull[i] = FALSE;
 		}
@@ -264,10 +272,11 @@ gistMakeUnionKey(GISTSTATE *giststate, int attno,
 		}
 
 		*dstisnull = FALSE;
-		*dst = FunctionCall2Coll(&giststate->unionFn[attno],
+		*dst = FunctionCall3Coll(&giststate->unionFn[attno],
 								 giststate->supportCollation[attno],
 								 PointerGetDatum(evec),
-								 PointerGetDatum(&dstsize));
+								 PointerGetDatum(&dstsize),
+								 PointerGetDatum(giststate->attoptions[attno]));
 	}
 }
 
@@ -276,10 +285,11 @@ gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b)
 {
 	bool		result;
 
-	FunctionCall3Coll(&giststate->equalFn[attno],
+	FunctionCall4Coll(&giststate->equalFn[attno],
 					  giststate->supportCollation[attno],
 					  a, b,
-					  PointerGetDatum(&result));
+					  PointerGetDatum(&result),
+					  PointerGetDatum(giststate->attoptions[attno]));
 	return result;
 }
 
@@ -582,9 +592,10 @@ gistFormTuple(GISTSTATE *giststate, Relation r,
 			gistentryinit(centry, attdata[i], r, NULL, (OffsetNumber) 0,
 						  isleaf);
 			cep = (GISTENTRY *)
-				DatumGetPointer(FunctionCall1Coll(&giststate->compressFn[i],
+				DatumGetPointer(FunctionCall2Coll(&giststate->compressFn[i],
 											  giststate->supportCollation[i],
-												  PointerGetDatum(&centry)));
+												  PointerGetDatum(&centry),
+									PointerGetDatum(giststate->attoptions[i])));
 			compatt[i] = cep->key;
 		}
 	}
@@ -670,11 +681,12 @@ gistpenalty(GISTSTATE *giststate, int attno,
 	if (giststate->penaltyFn[attno].fn_strict == FALSE ||
 		(isNullOrig == FALSE && isNullAdd == FALSE))
 	{
-		FunctionCall3Coll(&giststate->penaltyFn[attno],
+		FunctionCall4Coll(&giststate->penaltyFn[attno],
 						  giststate->supportCollation[attno],
 						  PointerGetDatum(orig),
 						  PointerGetDatum(add),
-						  PointerGetDatum(&penalty));
+						  PointerGetDatum(&penalty),
+						  PointerGetDatum(giststate->attoptions[attno]));
 		/* disallow negative or NaN penalty */
 		if (isnan(penalty) || penalty < 0.0)
 			penalty = 0.0;
@@ -819,7 +831,7 @@ gistoptions(Datum reloptions, bool validate)
 		{"buffering", RELOPT_TYPE_STRING, offsetof(GiSTOptions, bufferingModeOffset)}
 	};
 
-	options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIST,
+	options = parseRelOptions(reloptions, validate, NULL, RELOPT_KIND_GIST,
 							  &numoptions);
 
 	/* if none set, we're done */
@@ -864,3 +876,78 @@ gistGetFakeLSN(Relation rel)
 		return GetFakeLSNForUnloggedRel();
 	}
 }
+
+bytea *
+gistattoptions(Oid opfamilyoid, Oid opcintype, Datum reloptions, bool validate)
+{
+	bool		result = true;
+	HeapTuple	familytup;
+	Form_pg_opfamily familyform;
+	char	   *opfamilyname;
+	CatCList   *proclist,
+			   *oprlist;
+	bytea	   *res = NULL;
+
+    bool		ok = false;
+
+	int i;
+
+	/* Fetch opfamily information */
+	familytup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfamilyoid));
+	if (!HeapTupleIsValid(familytup))
+		elog(ERROR, "cache lookup failed for operator family %u", opfamilyoid);
+	familyform = (Form_pg_opfamily) GETSTRUCT(familytup);
+
+	opfamilyname = NameStr(familyform->opfname);
+
+	/* Fetch all operators and support functions of the opfamily */
+	oprlist = SearchSysCacheList1(AMOPSTRATEGY, ObjectIdGetDatum(opfamilyoid));
+	proclist = SearchSysCacheList1(AMPROCNUM, ObjectIdGetDatum(opfamilyoid));
+
+	for (i = 0; i < proclist->n_members; i++)
+	{
+		HeapTuple	proctup = &proclist->members[i]->tuple;
+		Form_pg_amproc procform = (Form_pg_amproc) GETSTRUCT(proctup);
+		
+		Oid tmp_oid = procform->amproc; // FIXME rename var;
+		/*
+		 * All GiST support functions should be registered with matching
+		 * left/right types
+		 */
+		if (procform->amproclefttype != procform->amprocrighttype)
+		{
+			ereport(INFO,
+					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+					 errmsg("gist opfamily %s contains support procedure %s with cross-type registration",
+							opfamilyname,
+							format_procedure(procform->amproc))));
+			result = false;
+		}
+
+		/*
+		 * We can't check signatures except within the specific opclass, since
+		 * we need to know the associated opckeytype in many cases.
+		 */
+		if (procform->amproclefttype != opcintype)
+			continue;
+
+		switch (procform->amprocnum)
+		{
+			case GIST_GET_ATTOPT_DEST_PROC:
+//				elog(WARNING, "2Proper function attopdesc for opclass found %i",(unsigned int) tmp_oid);
+				
+				res = DatumGetPointer(OidFunctionCall2(tmp_oid, reloptions, validate));
+				
+//				elog(WARNING, "Got result:'%i'",*((int *)res +1));
+
+				ok = true;
+				break;
+		}
+	}
+//	if (! ok) elog(WARNING, "2Proper function attopdesc for opclass NOT FOUND");
+
+	ReleaseCatCacheList(proclist);
+	ReleaseCatCacheList(oprlist);
+	ReleaseSysCache(familytup);
+	return res;
+}
\ No newline at end of file
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index 49a6c81..42a9460 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -82,6 +82,7 @@ hashhandler(PG_FUNCTION_ARGS)
 	amroutine->amendscan = hashendscan;
 	amroutine->ammarkpos = NULL;
 	amroutine->amrestrpos = NULL;
+	amroutine->amattoptions = NULL;
 
 	PG_RETURN_POINTER(amroutine);
 }
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 013394c..2255a79 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -115,6 +115,7 @@ bthandler(PG_FUNCTION_ARGS)
 	amroutine->amendscan = btendscan;
 	amroutine->ammarkpos = btmarkpos;
 	amroutine->amrestrpos = btrestrpos;
+	amroutine->amattoptions = NULL;
 
 	PG_RETURN_POINTER(amroutine);
 }
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
index bc679bf..d5d4132 100644
--- a/src/backend/access/spgist/spgutils.c
+++ b/src/backend/access/spgist/spgutils.c
@@ -66,6 +66,7 @@ spghandler(PG_FUNCTION_ARGS)
 	amroutine->amendscan = spgendscan;
 	amroutine->ammarkpos = NULL;
 	amroutine->amrestrpos = NULL;
+	amroutine->amattoptions = NULL;
 
 	PG_RETURN_POINTER(amroutine);
 }
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index e997b57..e95d0ef 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -600,7 +600,8 @@ CheckAttributeType(const char *attname,
 void
 InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
-					   CatalogIndexState indstate)
+					   CatalogIndexState indstate,
+					   Datum attoptions)
 {
 	Datum		values[Natts_pg_attribute];
 	bool		nulls[Natts_pg_attribute];
@@ -628,10 +629,14 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
 	values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(new_attribute->attislocal);
 	values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
 	values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(new_attribute->attcollation);
+	if (attoptions != (Datum) 0)
+		values[Anum_pg_attribute_attoptions - 1] = attoptions;
+	else
+		nulls[Anum_pg_attribute_attoptions - 1] = true;
 
 	/* start out with empty permissions and empty options */
 	nulls[Anum_pg_attribute_attacl - 1] = true;
-	nulls[Anum_pg_attribute_attoptions - 1] = true;
+//	nulls[Anum_pg_attribute_attoptions - 1] = true;
 	nulls[Anum_pg_attribute_attfdwoptions - 1] = true;
 
 	tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);
@@ -689,7 +694,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
 		attr->attstattarget = -1;
 		attr->attcacheoff = -1;
 
-		InsertPgAttributeTuple(rel, attr, indstate);
+		InsertPgAttributeTuple(rel, attr, indstate, (Datum) 0);
 
 		/* Add dependency info */
 		myself.classId = RelationRelationId;
@@ -739,7 +744,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
 				attStruct.attinhcount = oidinhcount;
 			}
 
-			InsertPgAttributeTuple(rel, &attStruct, indstate);
+			InsertPgAttributeTuple(rel, &attStruct, indstate, (Datum) 0);
 		}
 	}
 
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 31a1438..93680aa 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -96,7 +96,8 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
 						 Oid *classObjectId);
 static void InitializeAttributeOids(Relation indexRelation,
 						int numatts, Oid indexoid);
-static void AppendAttributeTuples(Relation indexRelation, int numatts);
+static void AppendAttributeTuples(Relation indexRelation, int numatts,
+						Datum *attoptions);
 static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
 					IndexInfo *indexInfo,
 					Oid *collationOids,
@@ -486,7 +487,7 @@ InitializeAttributeOids(Relation indexRelation,
  * ----------------------------------------------------------------
  */
 static void
-AppendAttributeTuples(Relation indexRelation, int numatts)
+AppendAttributeTuples(Relation indexRelation, int numatts, Datum *attoptions)
 {
 	Relation	pg_attribute;
 	CatalogIndexState indstate;
@@ -514,7 +515,8 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
 		Assert(indexTupDesc->attrs[i]->attnum == i + 1);
 		Assert(indexTupDesc->attrs[i]->attcacheoff == -1);
 
-		InsertPgAttributeTuple(pg_attribute, indexTupDesc->attrs[i], indstate);
+		InsertPgAttributeTuple(pg_attribute, indexTupDesc->attrs[i], indstate, 
+		attoptions ? attoptions[i]: (Datum) 0);
 	}
 
 	CatalogCloseIndexes(indstate);
@@ -864,6 +866,7 @@ index_create(Relation heapRelation,
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relhasoids = false;
+	indexRelation->rd_attoptions = NULL;
 
 	/*
 	 * store index's pg_class entry
@@ -887,7 +890,7 @@ index_create(Relation heapRelation,
 	/*
 	 * append ATTRIBUTE tuples for the index
 	 */
-	AppendAttributeTuples(indexRelation, indexInfo->ii_NumIndexAttrs);
+	AppendAttributeTuples(indexRelation, indexInfo->ii_NumIndexAttrs, indexInfo->ii_AttOptions);
 
 	/* ----------------
 	 *	  update pg_index
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 564e10e..8ec4ecc 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -308,6 +308,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 	indexInfo->ii_ExpressionsState = NIL;
 	indexInfo->ii_Predicate = NIL;
 	indexInfo->ii_PredicateState = NIL;
+	indexInfo->ii_AttOptions = NULL;
 	indexInfo->ii_ExclusionOps = NULL;
 	indexInfo->ii_ExclusionProcs = NULL;
 	indexInfo->ii_ExclusionStrats = NULL;
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index cf8c816..42cddd3 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -525,7 +525,8 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params,
 			 * If the appropriate flavor of the n_distinct option is
 			 * specified, override with the corresponding value.
 			 */
-			aopt = get_attribute_options(onerel->rd_id, stats->attr->attnum);
+			aopt = get_attribute_options(onerel->rd_rel->relkind, onerel->rd_id,
+										 stats->attr->attnum);
 			if (aopt != NULL)
 			{
 				float8		n_distinct;
@@ -811,7 +812,7 @@ compute_index_stats(Relation onerel, double totalrows,
 			{
 				VacAttrStats *stats = thisdata->vacattrstats[i];
 				AttributeOpts *aopt =
-				get_attribute_options(stats->attr->attrelid,
+				get_attribute_options(RELKIND_RELATION, stats->attr->attrelid,
 									  stats->attr->attnum);
 
 				stats->exprvals = exprvals + i;
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index d14d540..b789d7b 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -67,6 +67,7 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo,
 				  List *exclusionOpNames,
 				  Oid relId,
 				  char *accessMethodName, Oid accessMethodId,
+				  IndexAmRoutine *amRoutine,
 				  bool amcanorder,
 				  bool isconstraint);
 static Oid GetIndexOpClass(List *opclass, Oid attrType,
@@ -193,6 +194,7 @@ CheckIndexCompatible(Oid oldId,
 					  coloptions, attributeList,
 					  exclusionOpNames, relationId,
 					  accessMethodName, accessMethodId,
+					  amRoutine,
 					  amcanorder, isconstraint);
 
 
@@ -523,7 +525,6 @@ DefineIndex(Oid relationId,
 	amcanorder = amRoutine->amcanorder;
 	amoptions = amRoutine->amoptions;
 
-	pfree(amRoutine);
 	ReleaseSysCache(tuple);
 
 	/*
@@ -568,7 +569,9 @@ DefineIndex(Oid relationId,
 					  coloptions, stmt->indexParams,
 					  stmt->excludeOpNames, relationId,
 					  accessMethodName, accessMethodId,
+					  amRoutine,
 					  amcanorder, stmt->isconstraint);
+	pfree(amRoutine);
 
 	/*
 	 * Extra checks when creating a PRIMARY KEY index.
@@ -997,6 +1000,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
 				  Oid relId,
 				  char *accessMethodName,
 				  Oid accessMethodId,
+				  IndexAmRoutine *amRoutine,
 				  bool amcanorder,
 				  bool isconstraint)
 {
@@ -1017,7 +1021,8 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
 	}
 	else
 		nextExclOp = NULL;
-
+	
+	indexInfo->ii_AttOptions = (Datum*) palloc0(sizeof(Datum) * list_length(attList)); //FIXME list_length(attList) to ncols
 	/*
 	 * process attributeList
 	 */
@@ -1249,6 +1254,46 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
 								accessMethodName)));
 		}
 
+if (amRoutine->amattoptions)
+{
+	HeapTuple	classtup;
+	Form_pg_opclass classform;
+	Oid			opfamilyoid;
+	Oid			opcintype;
+	Datum		attoptions;
+
+	
+	attoptions = transformRelOptions((Datum) 0, attribute->options,
+									 NULL, NULL, false, false);
+
+	classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(classOidP[attn]));
+	if (!HeapTupleIsValid(classtup))
+		elog(ERROR, "cache lookup failed for operator class %u", classOidP[attn]);
+	classform = (Form_pg_opclass) GETSTRUCT(classtup);
+
+	opfamilyoid = classform->opcfamily;
+	opcintype = classform->opcintype;
+
+	
+		amRoutine->amattoptions(opfamilyoid, opcintype, attoptions, true); /* Do validate */
+		indexInfo->ii_AttOptions[attn] = attoptions;
+		
+		//
+	if(indexInfo->ii_AttOptions[attn])
+	{
+//  elog(WARNING, "Have amattoptions: %i",*((int *)indexInfo->ii_AttOptions[attn] +1));
+  } else
+  {
+//    elog(WARNING, "Have amattoptions, but there is no options here");
+  }
+	ReleaseSysCache(classtup);
+} else
+{
+		indexInfo->ii_AttOptions[attn] = (Datum) 0;
+//  elog(WARNING, "No amattoptions");
+//  FIXME add ERROR if no attoptions is supporsed to be here...
+}
+
 		attn++;
 	}
 }
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 86e9814..2d2456e 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -4858,7 +4858,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 
 	ReleaseSysCache(typeTuple);
 
-	InsertPgAttributeTuple(attrdesc, &attribute, NULL);
+	InsertPgAttributeTuple(attrdesc, &attribute, NULL, (Datum)0);
 
 	heap_close(attrdesc, RowExclusiveLock);
 
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 20e38f0..4b2edbe 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2591,6 +2591,7 @@ _copyIndexElem(const IndexElem *from)
 	COPY_NODE_FIELD(opclass);
 	COPY_SCALAR_FIELD(ordering);
 	COPY_SCALAR_FIELD(nulls_ordering);
+	COPY_NODE_FIELD(options);
 
 	return newnode;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 18ec5f0..56b3d86 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -347,7 +347,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <list>	stmtblock stmtmulti
 				OptTableElementList TableElementList OptInherit definition
 				OptTypedTableElementList TypedTableElementList
-				reloptions opt_reloptions
+				reloptions opt_reloptions opt_attoptions
 				OptWith distinct_clause opt_all_clause opt_definition func_args func_args_list
 				func_args_with_defaults func_args_with_defaults_list
 				aggr_args aggr_args_list
@@ -2973,7 +2973,7 @@ columnDef:	ColId Typename create_generic_options ColQualList
 				}
 		;
 
-columnOptions:	ColId WITH OPTIONS ColQualList
+columnOptions:	ColId WITH_LA OPTIONS ColQualList
 				{
 					ColumnDef *n = makeNode(ColumnDef);
 					n->colname = $1;
@@ -6707,7 +6707,8 @@ index_params:	index_elem							{ $$ = list_make1($1); }
  * expressions in parens.  For backwards-compatibility reasons, we allow
  * an expression that's just a function call to be written without parens.
  */
-index_elem:	ColId opt_collate opt_class opt_asc_desc opt_nulls_order
+
+index_elem:	ColId opt_collate opt_class opt_attoptions opt_asc_desc opt_nulls_order
 				{
 					$$ = makeNode(IndexElem);
 					$$->name = $1;
@@ -6715,10 +6716,11 @@ index_elem:	ColId opt_collate opt_class opt_asc_desc opt_nulls_order
 					$$->indexcolname = NULL;
 					$$->collation = $2;
 					$$->opclass = $3;
-					$$->ordering = $4;
-					$$->nulls_ordering = $5;
+					$$->options = $4;
+					$$->ordering = $5;
+					$$->nulls_ordering = $6;
 				}
-			| func_expr_windowless opt_collate opt_class opt_asc_desc opt_nulls_order
+			| func_expr_windowless opt_collate opt_class opt_attoptions opt_asc_desc opt_nulls_order
 				{
 					$$ = makeNode(IndexElem);
 					$$->name = NULL;
@@ -6726,10 +6728,11 @@ index_elem:	ColId opt_collate opt_class opt_asc_desc opt_nulls_order
 					$$->indexcolname = NULL;
 					$$->collation = $2;
 					$$->opclass = $3;
-					$$->ordering = $4;
-					$$->nulls_ordering = $5;
+					$$->options = $4;
+					$$->ordering = $5;
+					$$->nulls_ordering = $6;
 				}
-			| '(' a_expr ')' opt_collate opt_class opt_asc_desc opt_nulls_order
+			| '(' a_expr ')' opt_collate opt_class opt_attoptions opt_asc_desc opt_nulls_order
 				{
 					$$ = makeNode(IndexElem);
 					$$->name = NULL;
@@ -6737,8 +6740,9 @@ index_elem:	ColId opt_collate opt_class opt_asc_desc opt_nulls_order
 					$$->indexcolname = NULL;
 					$$->collation = $4;
 					$$->opclass = $5;
-					$$->ordering = $6;
-					$$->nulls_ordering = $7;
+					$$->options = $6;
+					$$->ordering = $7;
+					$$->nulls_ordering = $8;
 				}
 		;
 
@@ -6751,6 +6755,10 @@ opt_class:	any_name								{ $$ = $1; }
 			| /*EMPTY*/								{ $$ = NIL; }
 		;
 
+opt_attoptions:	WITH_LA OPTIONS '(' reloption_list ')'		{ $$ = $4; }
+			 |	/* EMPTY */									{ $$ = NIL; }
+		;
+
 opt_asc_desc: ASC							{ $$ = SORTBY_ASC; }
 			| DESC							{ $$ = SORTBY_DESC; }
 			| /*EMPTY*/						{ $$ = SORTBY_DEFAULT; }
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index 61d24e1..7a14e1e 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -185,6 +185,7 @@ base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner)
 			{
 				case TIME:
 				case ORDINALITY:
+				case OPTIONS:
 					cur_token = WITH_LA;
 					break;
 			}
diff --git a/src/backend/utils/cache/attoptcache.c b/src/backend/utils/cache/attoptcache.c
index 54eb864..ae97b9d 100644
--- a/src/backend/utils/cache/attoptcache.c
+++ b/src/backend/utils/cache/attoptcache.c
@@ -22,7 +22,8 @@
 #include "utils/hsearch.h"
 #include "utils/inval.h"
 #include "utils/syscache.h"
-
+#include "utils/rel.h"
+#include "utils/memutils.h"
 
 /* Hash table for informations about each attribute's options */
 static HTAB *AttoptCacheHash = NULL;
@@ -101,7 +102,7 @@ InitializeAttoptCache(void)
  *		Fetch attribute options for a specified table OID.
  */
 AttributeOpts *
-get_attribute_options(Oid attrelid, int attnum)
+get_attribute_options(char relkind, Oid attrelid, int attnum)
 {
 	AttoptCacheKey key;
 	AttoptCacheEntry *attopt;
@@ -177,3 +178,87 @@ get_attribute_options(Oid attrelid, int attnum)
 	memcpy(result, attopt->opts, VARSIZE(attopt->opts));
 	return result;
 }
+
+bytea **
+get_index_attribute_options(Relation index)
+{
+	int natts;
+	int i;
+	IndexAmRoutine* amRoutine;
+	MemoryContext oldcxt;
+
+//	elog(WARNING, "get_index_attribute_options");
+
+	if (index->rd_attoptions)
+	{
+//			elog(WARNING, "hot get");
+
+		if (index->rd_attoptions[0])
+		{
+//			elog(WARNING, "%i ",*((int *) index->rd_attoptions[i] + 1) );
+		}
+	}
+
+	if (index->rd_attoptions)
+			return index->rd_attoptions;
+	natts = index->rd_att->natts;
+
+	oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+	index->rd_attoptions = palloc(sizeof (bytea **)*natts); // FIXME palloc is wrong here; FIXME free this memory somewhere
+	MemoryContextSwitchTo(oldcxt);
+
+	amRoutine = GetIndexAmRoutine(index->rd_amhandler);
+
+	for(i=0;i<natts;i++)
+	{
+		if (amRoutine->amattoptions)
+		{
+			HeapTuple	tp;
+			Datum raw_attoptions = (Datum) 0;
+			Datum parsed_attoptions;
+			
+			tp = SearchSysCache2(ATTNUM,
+						 ObjectIdGetDatum(index->rd_id),
+						 Int16GetDatum(i + 1));
+			if (HeapTupleIsValid(tp))
+			{
+				bool		isNull;
+
+				raw_attoptions = SysCacheGetAttr(ATTNUM,
+												tp,
+												Anum_pg_attribute_attoptions,
+												&isNull);
+				if (isNull)
+						raw_attoptions = (Datum) 0;
+//				if (!isNull) elog(WARNING, "Non null attoptions!");
+				ReleaseSysCache(tp);
+			}
+			parsed_attoptions = amRoutine->amattoptions(
+								index->rd_opfamily[i], index->rd_opcintype[i],
+								raw_attoptions, false);
+			
+			if (parsed_attoptions)
+			{
+				Datum result;
+
+				oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+				result = palloc(VARSIZE(parsed_attoptions));
+				MemoryContextSwitchTo(oldcxt);
+
+				memcpy(result, parsed_attoptions, VARSIZE(parsed_attoptions));
+
+				index->rd_attoptions[i] = result;
+			} else
+			{
+				index->rd_attoptions[i] = NULL;
+			}
+			
+//			elog(WARNING, "coldget %i ",*((int *) index->rd_attoptions[i] + 1) );
+			
+		} else
+		{
+			index->rd_attoptions[i] = NULL;
+		}
+	}
+	return index->rd_attoptions;
+}
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h
index 35f1061..13804fa 100644
--- a/src/include/access/amapi.h
+++ b/src/include/access/amapi.h
@@ -104,6 +104,10 @@ typedef void (*ammarkpos_function) (IndexScanDesc scan);
 /* restore marked scan position */
 typedef void (*amrestrpos_function) (IndexScanDesc scan);
 
+//typedef char *(*amgetattopdesc_function) (Oid opclassoid);
+
+typedef bytea *(*amattoptions_function) (Oid opfamilyoid, Oid opcintype,
+											Datum reloptions, bool validate);
 
 /*
  * API struct for an index AM.  Note this must be stored in a single palloc'd
@@ -162,6 +166,8 @@ typedef struct IndexAmRoutine
 	amendscan_function amendscan;
 	ammarkpos_function ammarkpos;		/* can be NULL */
 	amrestrpos_function amrestrpos;		/* can be NULL */
+//	amgetattopdesc_function amgetattopdesc;	/* can be NULL */
+	amattoptions_function amattoptions;	/* can be NULL */
 } IndexAmRoutine;
 
 
diff --git a/src/include/access/gist.h b/src/include/access/gist.h
index 4343d6f..d8b5ac8 100644
--- a/src/include/access/gist.h
+++ b/src/include/access/gist.h
@@ -34,7 +34,8 @@
 #define GIST_EQUAL_PROC					7
 #define GIST_DISTANCE_PROC				8
 #define GIST_FETCH_PROC					9
-#define GISTNProcs					9
+#define GIST_GET_ATTOPT_DEST_PROC	   10
+#define GISTNProcs					10
 
 /*
  * Page opaque data in a GiST index page.
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index f9732ba..6989afd 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -95,6 +95,8 @@ typedef struct GISTSTATE
 
 	/* Collations to pass to the support functions */
 	Oid			supportCollation[INDEX_MAX_KEYS];
+	
+	bytea	  **attoptions; /* FIXME add comment */
 } GISTSTATE;
 
 
@@ -440,6 +442,8 @@ extern void gistdoinsert(Relation r,
 			 Size freespace,
 			 GISTSTATE *GISTstate);
 
+
+
 /* A List of these is returned from gistplacetopage() in *splitinfo */
 typedef struct
 {
@@ -540,6 +544,10 @@ extern void gistMakeUnionKey(GISTSTATE *giststate, int attno,
 
 extern XLogRecPtr gistGetFakeLSN(Relation rel);
 
+// extern char *gistgetattopdesc(Oid opclassoid);
+extern bytea *gistattoptions(Oid opfamilyoid, Oid opcintype,
+											Datum reloptions, bool validate);
+
 /* gistvacuum.c */
 extern IndexBulkDeleteResult *gistbulkdelete(IndexVacuumInfo *info,
 			   IndexBulkDeleteResult *stats,
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 469ac67..216f0c7 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -126,6 +126,13 @@ typedef struct
 	int			offset;			/* offset of field in result struct */
 } relopt_parse_elt;
 
+typedef struct
+{
+	relopt_gen	  **definitions;
+	int				num;
+	int				max;
+	bool			need_initialization;
+} options_catalog;
 
 /*
  * These macros exist for the convenience of amoptions writers (but consider
@@ -245,14 +252,16 @@ typedef struct
 
 
 extern relopt_kind add_reloption_kind(void);
-extern void add_bool_reloption(bits32 kinds, char *name, char *desc,
-				   bool default_val);
-extern void add_int_reloption(bits32 kinds, char *name, char *desc,
-				  int default_val, int min_val, int max_val);
-extern void add_real_reloption(bits32 kinds, char *name, char *desc,
-				   double default_val, double min_val, double max_val);
-extern void add_string_reloption(bits32 kinds, char *name, char *desc,
-					 char *default_val, validate_string_relopt validator);
+extern void add_bool_reloption(bits32 kinds, options_catalog * catalog,
+				   char *name, char *desc, bool default_val);
+extern void add_int_reloption(bits32 kinds, options_catalog * catalog,
+			char *name, char *desc, int default_val, int min_val, int max_val);
+extern void add_real_reloption(bits32 kinds, options_catalog * catalog,
+							char *name, char *desc, double default_val,
+											double min_val, double max_val);
+extern void add_string_reloption(bits32 kinds, options_catalog * catalog,
+								char *name, char *desc, char *default_val,
+											validate_string_relopt validator);
 
 extern Datum transformRelOptions(Datum oldOptions, List *defList,
 					char *namspace, char *validnsps[],
@@ -261,7 +270,7 @@ extern List *untransformRelOptions(Datum options);
 extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
 				  amoptions_function amoptions);
 extern relopt_value *parseRelOptions(Datum options, bool validate,
-				relopt_kind kind, int *numrelopts);
+			options_catalog * catalog, relopt_kind kind, int *numrelopts);
 extern void *allocateReloptStruct(Size base, relopt_value *options,
 					 int numoptions);
 extern void fillRelOptions(void *rdopts, Size basesize,
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index b80d8d8..a3654a2 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -87,7 +87,8 @@ extern List *heap_truncate_find_FKs(List *relationIds);
 
 extern void InsertPgAttributeTuple(Relation pg_attribute_rel,
 					   Form_pg_attribute new_attribute,
-					   CatalogIndexState indstate);
+					   CatalogIndexState indstate,
+					   Datum attoptions);
 
 extern void InsertPgClassTuple(Relation pg_class_desc,
 				   Relation new_rel_desc,
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index ee97c5d..1540748 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -56,6 +56,7 @@ CATALOG(pg_index,2610) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO
 								 * each zero entry in indkey[] */
 	pg_node_tree indpred;		/* expression tree for predicate, if a partial
 								 * index; else NULL */
+
 #endif
 } FormData_pg_index;
 
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index ee4e189..6af4b39 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -40,6 +40,7 @@
  *		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
+ *		AttOptions			FIXME
  *		ExclusionOps		Per-column exclusion operators, or NULL if none
  *		ExclusionProcs		Underlying function OIDs for ExclusionOps
  *		ExclusionStrats		Opclass strategy numbers for ExclusionOps
@@ -64,6 +65,7 @@ typedef struct IndexInfo
 	List	   *ii_ExpressionsState;	/* list of ExprState */
 	List	   *ii_Predicate;	/* list of Expr */
 	List	   *ii_PredicateState;		/* list of ExprState */
+	Datum	   *ii_AttOptions;			/* array of attrubute options */
 	Oid		   *ii_ExclusionOps;	/* array with one entry per column */
 	Oid		   *ii_ExclusionProcs;		/* array with one entry per column */
 	uint16	   *ii_ExclusionStrats;		/* array with one entry per column */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 714cf15..fe5c68b 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -638,6 +638,7 @@ typedef struct IndexElem
 	List	   *opclass;		/* name of desired opclass; NIL = default */
 	SortByDir	ordering;		/* ASC/DESC/default */
 	SortByNulls nulls_ordering; /* FIRST/LAST/default */
+	List	   *options;		/* WITH OPTIONS clause options: a list of DefElem */
 } IndexElem;
 
 /*
diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h
index cf8ead0..4411238 100644
--- a/src/include/utils/attoptcache.h
+++ b/src/include/utils/attoptcache.h
@@ -23,6 +23,7 @@ typedef struct AttributeOpts
 	float8		n_distinct_inherited;
 } AttributeOpts;
 
-AttributeOpts *get_attribute_options(Oid spcid, int attnum);
+AttributeOpts *get_attribute_options(char relkind, Oid spcid, int attnum);
+bytea **get_index_attribute_options(Relation index);
 
 #endif   /* ATTOPTCACHE_H */
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index a0ba417..314a267 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -146,6 +146,7 @@ typedef struct RelationData
 	uint16	   *rd_exclstrats;	/* exclusion ops' strategy numbers, if any */
 	void	   *rd_amcache;		/* available for use by index AM */
 	Oid		   *rd_indcollation;	/* OIDs of index collations */
+	bytea	  **rd_attoptions;	/* FIXME */
 
 	/*
 	 * foreign-table support
