Tom Lane wrote:
> Alvaro Herrera <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers