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