Tom Lane wrote:
> Alvaro Herrera <alvhe...@commandprompt.com> writes:

> >    Right now we just plow
> >    ahead using a pg_class seqscan, which avoids locking the relations
> >    just for the sake of verifying whether they need work.
> 
> We should stick with that, and refactor the reloptions code as needed to
> be able to work from just a pg_class tuple.  I'm envisioning a scheme
> like:
> 
>       bottom level: extract from pg_class tuple, return a palloc'd struct
> 
>       relcache: logic to cache the result of the above
> 
>       top level: exported function to return a cached options struct
> 
> The autovac scan could use the bottom-level API.

I'm not sure that we have any use for the top level you propose; the
attached patch just uses the two lower levels, and I think it fits
autovacuum usage just fine.  Thanks for the idea.

-- 
Alvaro Herrera                                http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/access/common/reloptions.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/access/common/reloptions.c,v
retrieving revision 1.18
diff -c -p -r1.18 reloptions.c
*** src/backend/access/common/reloptions.c	12 Jan 2009 21:02:14 -0000	1.18
--- src/backend/access/common/reloptions.c	22 Jan 2009 23:24:04 -0000
*************** untransformRelOptions(Datum options)
*** 558,563 ****
--- 558,606 ----
  	return result;
  }
  
+ /*
+  * Extract reloptions from a pg_class tuple.
+  *
+  * This is a very low-level routine, expected to be used by relcache code only.
+  * For other uses, consider grabbing the pointer from the relcache entry
+  * instead.
+  *
+  * tupdesc is pg_class' tuple descriptor.  amoptions is the amoptions regproc
+  * in the case of the tuple corresponding to an index, or InvalidOid otherwise.
+  */
+ bytea *
+ extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, char relkind, Oid amoptions)
+ {
+ 	bytea  *options;
+ 	bool	isnull;
+ 	Datum	datum;
+ 
+ 	datum = fastgetattr(tuple,
+ 						Anum_pg_class_reloptions,
+ 						tupdesc,
+ 						&isnull);
+ 	if (isnull)
+ 		return NULL;
+ 
+ 	/* Parse into appropriate format; don't error out here */
+ 	switch (relkind)
+ 	{
+ 		case RELKIND_RELATION:
+ 		case RELKIND_TOASTVALUE:
+ 		case RELKIND_UNCATALOGED:
+ 			options = heap_reloptions(relkind, datum, false);
+ 			break;
+ 		case RELKIND_INDEX:
+ 			options = index_reloptions(amoptions, datum, false);
+ 			break;
+ 		default:
+ 			Assert(false);		/* can't get here */
+ 			options = NULL;		/* keep compiler quiet */
+ 			break;
+ 	}
+ 	
+ 	return options;
+ }
  
  /*
   * Interpret reloptions that are given in text-array format.
Index: src/backend/utils/cache/relcache.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/utils/cache/relcache.c,v
retrieving revision 1.282
diff -c -p -r1.282 relcache.c
*** src/backend/utils/cache/relcache.c	22 Jan 2009 20:16:06 -0000	1.282
--- src/backend/utils/cache/relcache.c	22 Jan 2009 23:30:45 -0000
*************** AllocateRelationDesc(Relation relation, 
*** 351,358 ****
  static void
  RelationParseRelOptions(Relation relation, HeapTuple tuple)
  {
- 	Datum		datum;
- 	bool		isnull;
  	bytea	   *options;
  
  	relation->rd_options = NULL;
--- 351,356 ----
*************** RelationParseRelOptions(Relation relatio
*** 374,404 ****
  	 * we might not have any other for pg_class yet (consider executing this
  	 * code for pg_class itself)
  	 */
! 	datum = fastgetattr(tuple,
! 						Anum_pg_class_reloptions,
! 						GetPgClassDescriptor(),
! 						&isnull);
! 	if (isnull)
! 		return;
! 
! 	/* Parse into appropriate format; don't error out here */
! 	switch (relation->rd_rel->relkind)
! 	{
! 		case RELKIND_RELATION:
! 		case RELKIND_TOASTVALUE:
! 		case RELKIND_UNCATALOGED:
! 			options = heap_reloptions(relation->rd_rel->relkind, datum,
! 									  false);
! 			break;
! 		case RELKIND_INDEX:
! 			options = index_reloptions(relation->rd_am->amoptions, datum,
! 									   false);
! 			break;
! 		default:
! 			Assert(false);		/* can't get here */
! 			options = NULL;		/* keep compiler quiet */
! 			break;
! 	}
  
  	/* Copy parsed data into CacheMemoryContext */
  	if (options)
--- 372,382 ----
  	 * we might not have any other for pg_class yet (consider executing this
  	 * code for pg_class itself)
  	 */
! 	options = extractRelOptions(tuple,
! 								GetPgClassDescriptor(),
! 							   	relation->rd_rel->relkind,
! 								relation->rd_rel->relkind == RELKIND_INDEX ?
! 								relation->rd_am->amoptions : InvalidOid);
  
  	/* Copy parsed data into CacheMemoryContext */
  	if (options)
Index: src/include/access/reloptions.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/access/reloptions.h,v
retrieving revision 1.10
diff -c -p -r1.10 reloptions.h
*** src/include/access/reloptions.h	12 Jan 2009 21:02:15 -0000	1.10
--- src/include/access/reloptions.h	22 Jan 2009 23:22:58 -0000
***************
*** 18,23 ****
--- 18,24 ----
  #ifndef RELOPTIONS_H
  #define RELOPTIONS_H
  
+ #include "access/htup.h"
  #include "nodes/pg_list.h"
  
  /* types supported by reloptions */
*************** extern void add_string_reloption(int kin
*** 241,246 ****
--- 242,249 ----
  extern Datum transformRelOptions(Datum oldOptions, List *defList,
  					bool ignoreOids, bool isReset);
  extern List *untransformRelOptions(Datum options);
+ extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
+ 				  char relkind, Oid amoptions);
  extern relopt_value *parseRelOptions(Datum options, bool validate,
  				relopt_kind kind, int *numrelopts);
  extern void *allocateReloptStruct(Size base, relopt_value *options,
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to