Index: src/backend/access/common/reloptions.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/common/reloptions.c,v
retrieving revision 1.16
diff -c -p -r1.16 reloptions.c
Index: src/backend/access/nbtree/nbtinsert.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/nbtree/nbtinsert.c,v
retrieving revision 1.169
diff -c -p -r1.169 nbtinsert.c
*** src/backend/access/nbtree/nbtinsert.c	1 Jan 2009 17:23:35 -0000	1.169
--- src/backend/access/nbtree/nbtinsert.c	7 Jan 2009 03:21:31 -0000
***************
*** 17,22 ****
--- 17,23 ----
  
  #include "access/heapam.h"
  #include "access/nbtree.h"
+ #include "access/reloptions.h"
  #include "access/transam.h"
  #include "miscadmin.h"
  #include "storage/bufmgr.h"
***************
*** 565,570 ****
--- 566,590 ----
  	OffsetNumber firstright = InvalidOffsetNumber;
  	Size		itemsz;
  
+ 	{
+ 		BtOptions *options = (BtOptions *) rel->rd_options;
+ 
+ 		if (options)
+ 		{
+ 			char	*str;
+ 
+ 			str = GET_STRING_RELOPTION(options, teststring);
+ 			elog(LOG, "the teststring option is %s",
+ 				 str ? str : "empty");
+ 			str = GET_STRING_RELOPTION(options, teststring2);
+ 			elog(LOG, "the teststring2 option is %s",
+ 				 str ? str : "empty");
+ 			str = GET_STRING_RELOPTION(options, teststring3);
+ 			elog(LOG, "the teststring3 option is %s",
+ 				 str ? str : "empty");
+ 		}
+ 	}
+ 
  	page = BufferGetPage(buf);
  	lpageop = (BTPageOpaque) PageGetSpecialPointer(page);
  
Index: src/backend/access/nbtree/nbtutils.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/nbtree/nbtutils.c,v
retrieving revision 1.93
diff -c -p -r1.93 nbtutils.c
*** src/backend/access/nbtree/nbtutils.c	5 Jan 2009 17:14:28 -0000	1.93
--- src/backend/access/nbtree/nbtutils.c	7 Jan 2009 13:31:23 -0000
***************
*** 1395,1408 ****
  		Assert(found);
  }
  
  Datum
  btoptions(PG_FUNCTION_ARGS)
  {
  	Datum		reloptions = PG_GETARG_DATUM(0);
  	bool		validate = PG_GETARG_BOOL(1);
  	bytea	   *result;
  
- 	result = default_reloptions(reloptions, validate, RELOPT_KIND_BTREE);
  	if (result)
  		PG_RETURN_BYTEA_P(result);
  	PG_RETURN_NULL();
--- 1395,1490 ----
  		Assert(found);
  }
  
+ void
+ validate_teststring(char *string);
+ 
+ void
+ validate_teststring(char *string)
+ {
+ 	if (string == NULL)
+ 		elog(ERROR, "teststring must not be null!");
+ 	if (strlen(string) != 3)
+ 		elog(ERROR, "teststring must be of length 3, but it's \"%s\"", string);
+ }
+ 
  Datum
  btoptions(PG_FUNCTION_ARGS)
  {
  	Datum		reloptions = PG_GETARG_DATUM(0);
  	bool		validate = PG_GETARG_BOOL(1);
  	bytea	   *result;
+ 	relopt_value *options;
+ 	int			numoptions;
+ 	int			i;
+ 	static	bool initialized = false;
+ 
+ 	if (!initialized)
+ 	{
+ 		add_string_reloption(RELOPT_KIND_BTREE, "teststring", NULL,
+ 							 "foo", validate_teststring);
+ 		add_string_reloption(RELOPT_KIND_BTREE, "teststring2", NULL,
+ 							 "", NULL);
+ 		add_string_reloption(RELOPT_KIND_BTREE, "teststring3", NULL,
+ 							 NULL, NULL);
+ 		initialized = true;
+ 	}
+ 
+ 	options = parseRelOptions(reloptions, validate, RELOPT_KIND_BTREE,
+ 							  &numoptions);
+ 
+ 	/* if none set, we're done */
+ 	if (numoptions == 0)
+ 		result = NULL;
+ 	else
+ 	{
+ 		BtOptions *rdopts;
+ 		int		tstrlen;
+ 		int		t2strlen;
+ 		int		t3strlen;
+ 		int		offset;
+ 
+ 		for (i = 0; i < numoptions; i++)
+ 		{
+ 			if (HAVE_RELOPTION("teststring", options[i]))
+ 			{
+ 				tstrlen = GET_STRING_RELOPTION_LEN(options[i]);
+ 				continue;
+ 			}
+ 			if (HAVE_RELOPTION("teststring2", options[i]))
+ 			{
+ 				t2strlen = GET_STRING_RELOPTION_LEN(options[i]);
+ 				continue;
+ 			}
+ 			if (HAVE_RELOPTION("teststring3", options[i]))
+ 			{
+ 				t3strlen = GET_STRING_RELOPTION_LEN(options[i]);
+ 				continue;
+ 			}
+ 		}
+ 
+ 		rdopts = palloc0(sizeof(BtOptions) + tstrlen + t2strlen + t3strlen + 4);
+ 		offset = sizeof(BtOptions);
+ 
+ 		for (i = 0; i < numoptions; i++)
+ 		{
+ 			HANDLE_INT_RELOPTION("fillfactor", rdopts->fillfactor, options[i],
+ 								 (char *) NULL);
+ 			HANDLE_STRING_RELOPTION("teststring", rdopts->teststring,
+ 									options[i], rdopts, offset,
+ 									(char *) NULL);
+ 			HANDLE_STRING_RELOPTION("teststring2", rdopts->teststring2,
+ 									options[i], rdopts, offset,
+ 									(char *) NULL);
+ 			HANDLE_STRING_RELOPTION("teststring3", rdopts->teststring3,
+ 									options[i], rdopts, offset,
+ 									(char *) NULL);
+ 		}
+ 
+ 		pfree(options);
+ 		SET_VARSIZE(rdopts, offset);
+ 		result = (bytea *) rdopts;
+ 	}
  
  	if (result)
  		PG_RETURN_BYTEA_P(result);
  	PG_RETURN_NULL();
Index: src/include/access/nbtree.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/access/nbtree.h,v
retrieving revision 1.123
diff -c -p -r1.123 nbtree.h
*** src/include/access/nbtree.h	1 Jan 2009 17:23:56 -0000	1.123
--- src/include/access/nbtree.h	6 Jan 2009 20:35:32 -0000
***************
*** 595,598 ****
--- 595,609 ----
  extern void btree_xlog_cleanup(void);
  extern bool btree_safe_restartpoint(void);
  
+ /* must follow StdRdOptions conventions */
+ typedef struct BtOptions
+ {
+ 	int32	vl_len_;
+ 	int		fillfactor;
+ 	int		teststring;
+ 	int		teststring2;
+ 	int		teststring3;
+ 	/* variable length struct -- string is allocated here */
+ } BtOptions;
+ 
  #endif   /* NBTREE_H */
Index: src/include/access/reloptions.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/access/reloptions.h,v
retrieving revision 1.8
diff -c -p -r1.8 reloptions.h
