diff --git a/src/backend/access/heap/Makefile b/src/backend/access/heap/Makefile index 95575f8e325b8633825717af538d2e804aaf806e..352ced339292e5c74ab3a506f32da2fd2992b9b3 100644 --- a/src/backend/access/heap/Makefile +++ b/src/backend/access/heap/Makefile @@ -4,7 +4,7 @@ # Makefile for access/heap # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/heap/Makefile,v 1.11 2000/08/31 16:09:33 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/heap/Makefile,v 1.12 2001/11/02 16:30:29 tgl Exp $ # #------------------------------------------------------------------------- @@ -12,7 +12,7 @@ subdir = src/backend/access/heap top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = heapam.o hio.o stats.o tuptoaster.o +OBJS = heapam.o hio.o tuptoaster.o all: SUBSYS.o diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index f73ca50285b5093f653b4cdd484ace04461707c9..bf7798a07dc56c02d4dde2cf7373081cf970d8bf 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,14 +8,16 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.126 2001/10/25 05:49:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.127 2001/11/02 16:30:29 tgl Exp $ * * * INTERFACE ROUTINES - * heap_open - open a heap relation by relationId + * relation_open - open any relation by relation OID + * relation_openr - open any relation by name + * relation_close - close any relation + * heap_open - open a heap relation by relation OID * heap_openr - open a heap relation by name - * heap_open[r]_nofail - same, but return NULL on failure instead of elog - * heap_close - close a heap relation + * heap_close - (now just a macro for relation_close) * heap_beginscan - begin relation scan * heap_rescan - restart a relation scan * heap_endscan - end relation scan @@ -440,15 +442,21 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, */ /* ---------------- - * heap_open - open a heap relation by relationId + * relation_open - open any relation by relation OID * * If lockmode is not "NoLock", the specified kind of lock is - * obtained on the relation. + * obtained on the relation. (Generally, NoLock should only be + * used if the caller knows it has some appropriate lock on the + * relation already.) + * * An error is raised if the relation does not exist. + * + * NB: a "relation" is anything with a pg_class entry. The caller is + * expected to check whether the relkind is something it can handle. * ---------------- */ Relation -heap_open(Oid relationId, LOCKMODE lockmode) +relation_open(Oid relationId, LOCKMODE lockmode) { Relation r; @@ -466,10 +474,6 @@ heap_open(Oid relationId, LOCKMODE lockmode) if (!RelationIsValid(r)) elog(ERROR, "Relation %u does not exist", relationId); - /* Under no circumstances will we return an index as a relation. */ - if (r->rd_rel->relkind == RELKIND_INDEX) - elog(ERROR, "%s is an index relation", RelationGetRelationName(r)); - if (lockmode != NoLock) LockRelation(r, lockmode); @@ -477,15 +481,13 @@ heap_open(Oid relationId, LOCKMODE lockmode) } /* ---------------- - * heap_openr - open a heap relation by name + * relation_openr - open any relation by name * - * If lockmode is not "NoLock", the specified kind of lock is - * obtained on the relation. - * An error is raised if the relation does not exist. + * As above, but lookup by name instead of OID. * ---------------- */ Relation -heap_openr(const char *relationName, LOCKMODE lockmode) +relation_openr(const char *relationName, LOCKMODE lockmode) { Relation r; @@ -497,116 +499,111 @@ heap_openr(const char *relationName, LOCKMODE lockmode) IncrHeapAccessStat(local_openr); IncrHeapAccessStat(global_openr); + /* + * Check for shared-cache-inval messages before trying to open the + * relation. This is needed to cover the case where the name identifies + * a rel that has been dropped and recreated since the start of our + * transaction: if we don't flush the old relcache entry then we'll + * latch onto that entry and suffer an error when we do LockRelation. + * Note that relation_open does not need to do this, since a relation's + * OID never changes. + * + * We skip this if asked for NoLock, on the assumption that the caller + * has already ensured some appropriate lock is held. + */ + if (lockmode != NoLock) + AcceptInvalidationMessages(); + /* The relcache does all the real work... */ r = RelationNameGetRelation(relationName); if (!RelationIsValid(r)) - elog(ERROR, "Relation '%s' does not exist", relationName); - - /* Under no circumstances will we return an index as a relation. */ - if (r->rd_rel->relkind == RELKIND_INDEX) - elog(ERROR, "%s is an index relation", RelationGetRelationName(r)); + elog(ERROR, "Relation \"%s\" does not exist", relationName); if (lockmode != NoLock) LockRelation(r, lockmode); - pgstat_initstats(&r->pgstat_info, r); - - pgstat_initstats(&r->pgstat_info, r); - return r; } /* ---------------- - * heap_open_nofail - open a heap relation by relationId, - * do not raise error on failure + * relation_close - close any relation + * + * If lockmode is not "NoLock", we first release the specified lock. * - * The caller must check for a NULL return value indicating - * that no such relation exists. - * No lock is obtained on the relation, either. + * Note that it is often sensible to hold a lock beyond relation_close; + * in that case, the lock is released automatically at xact end. * ---------------- */ -Relation -heap_open_nofail(Oid relationId) +void +relation_close(Relation relation, LOCKMODE lockmode) { - Relation r; + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); /* * increment access statistics */ - IncrHeapAccessStat(local_open); - IncrHeapAccessStat(global_open); - - /* The relcache does all the real work... */ - r = RelationIdGetRelation(relationId); + IncrHeapAccessStat(local_close); + IncrHeapAccessStat(global_close); - /* Under no circumstances will we return an index as a relation. */ - if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX) - elog(ERROR, "%s is an index relation", RelationGetRelationName(r)); + if (lockmode != NoLock) + UnlockRelation(relation, lockmode); - return r; + /* The relcache does the real work... */ + RelationClose(relation); } + /* ---------------- - * heap_openr_nofail - open a heap relation by name, - * do not raise error on failure + * heap_open - open a heap relation by relation OID * - * The caller must check for a NULL return value indicating - * that no such relation exists. - * No lock is obtained on the relation, either. + * This is essentially relation_open plus check that the relation + * is not an index or special relation. (The caller should also check + * that it's not a view before assuming it has storage.) * ---------------- */ Relation -heap_openr_nofail(const char *relationName) +heap_open(Oid relationId, LOCKMODE lockmode) { Relation r; - /* - * increment access statistics - */ - IncrHeapAccessStat(local_openr); - IncrHeapAccessStat(global_openr); + r = relation_open(relationId, lockmode); - /* The relcache does all the real work... */ - r = RelationNameGetRelation(relationName); - - /* Under no circumstances will we return an index as a relation. */ - if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX) - elog(ERROR, "%s is an index relation", RelationGetRelationName(r)); - - if (RelationIsValid(r)) - pgstat_initstats(&r->pgstat_info, r); + if (r->rd_rel->relkind == RELKIND_INDEX) + elog(ERROR, "%s is an index relation", + RelationGetRelationName(r)); + else if (r->rd_rel->relkind == RELKIND_SPECIAL) + elog(ERROR, "%s is a special relation", + RelationGetRelationName(r)); - if (RelationIsValid(r)) - pgstat_initstats(&r->pgstat_info, r); + pgstat_initstats(&r->pgstat_info, r); return r; } /* ---------------- - * heap_close - close a heap relation + * heap_openr - open a heap relation by name * - * If lockmode is not "NoLock", we first release the specified lock. - * Note that it is often sensible to hold a lock beyond heap_close; - * in that case, the lock is released automatically at xact end. + * As above, but lookup by name instead of OID. * ---------------- */ -void -heap_close(Relation relation, LOCKMODE lockmode) +Relation +heap_openr(const char *relationName, LOCKMODE lockmode) { - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + Relation r; - /* - * increment access statistics - */ - IncrHeapAccessStat(local_close); - IncrHeapAccessStat(global_close); + r = relation_openr(relationName, lockmode); - if (lockmode != NoLock) - UnlockRelation(relation, lockmode); + if (r->rd_rel->relkind == RELKIND_INDEX) + elog(ERROR, "%s is an index relation", + RelationGetRelationName(r)); + else if (r->rd_rel->relkind == RELKIND_SPECIAL) + elog(ERROR, "%s is a special relation", + RelationGetRelationName(r)); - /* The relcache does the real work... */ - RelationClose(relation); + pgstat_initstats(&r->pgstat_info, r); + + return r; } @@ -2332,8 +2329,7 @@ newsame:; } /* undo */ - if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied - * ?! */ + if (XLByteLT(PageGetLSN(page), lsn)) /* changes not applied?! */ elog(STOP, "heap_update_undo: bad new tuple page LSN"); elog(STOP, "heap_update_undo: unimplemented"); diff --git a/src/backend/access/heap/stats.c b/src/backend/access/heap/stats.c deleted file mode 100644 index 6f5dfbea1412801ae784a68e84942a223b1fb588..0000000000000000000000000000000000000000 --- a/src/backend/access/heap/stats.c +++ /dev/null @@ -1,333 +0,0 @@ -/*------------------------------------------------------------------------- - * - * stats.c - * heap access method debugging statistic collection routines - * - * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.25 2001/10/25 05:49:21 momjian Exp $ - * - * NOTES - * initam should be moved someplace else. - * - *------------------------------------------------------------------------- - */ - -#include <time.h> - -#include "postgres.h" - -#include "access/heapam.h" - - -static void InitHeapAccessStatistics(void); - -/* ---------------- - * InitHeapAccessStatistics - * ---------------- - */ -HeapAccessStatistics heap_access_stats = (HeapAccessStatistics) NULL; - -static void -InitHeapAccessStatistics() -{ - MemoryContext oldContext; - HeapAccessStatistics stats; - - /* - * make sure we don't initialize things twice - */ - if (heap_access_stats != NULL) - return; - - /* - * allocate statistics structure from the top memory context - */ - oldContext = MemoryContextSwitchTo(TopMemoryContext); - - stats = (HeapAccessStatistics) - palloc(sizeof(HeapAccessStatisticsData)); - - /* - * initialize fields to default values - */ - stats->global_open = 0; - stats->global_openr = 0; - stats->global_close = 0; - stats->global_beginscan = 0; - stats->global_rescan = 0; - stats->global_endscan = 0; - stats->global_getnext = 0; - stats->global_fetch = 0; - stats->global_insert = 0; - stats->global_delete = 0; - stats->global_replace = 0; - stats->global_mark4update = 0; - stats->global_markpos = 0; - stats->global_restrpos = 0; - stats->global_BufferGetRelation = 0; - stats->global_RelationIdGetRelation = 0; - stats->global_RelationIdGetRelation_Buf = 0; - stats->global_getreldesc = 0; - stats->global_heapgettup = 0; - stats->global_RelationPutHeapTuple = 0; - stats->global_RelationPutLongHeapTuple = 0; - - stats->local_open = 0; - stats->local_openr = 0; - stats->local_close = 0; - stats->local_beginscan = 0; - stats->local_rescan = 0; - stats->local_endscan = 0; - stats->local_getnext = 0; - stats->local_fetch = 0; - stats->local_insert = 0; - stats->local_delete = 0; - stats->local_replace = 0; - stats->local_mark4update = 0; - stats->local_markpos = 0; - stats->local_restrpos = 0; - stats->local_BufferGetRelation = 0; - stats->local_RelationIdGetRelation = 0; - stats->local_RelationIdGetRelation_Buf = 0; - stats->local_getreldesc = 0; - stats->local_heapgettup = 0; - stats->local_RelationPutHeapTuple = 0; - stats->local_RelationPutLongHeapTuple = 0; - stats->local_RelationNameGetRelation = 0; - stats->global_RelationNameGetRelation = 0; - - /* - * record init times - */ - time(&stats->init_global_timestamp); - time(&stats->local_reset_timestamp); - time(&stats->last_request_timestamp); - - /* - * return to old memory context - */ - MemoryContextSwitchTo(oldContext); - - heap_access_stats = stats; -} - -#ifdef NOT_USED -/* ---------------- - * ResetHeapAccessStatistics - * ---------------- - */ -void -ResetHeapAccessStatistics() -{ - HeapAccessStatistics stats; - - /* - * do nothing if stats aren't initialized - */ - if (heap_access_stats == NULL) - return; - - stats = heap_access_stats; - - /* - * reset local counts - */ - stats->local_open = 0; - stats->local_openr = 0; - stats->local_close = 0; - stats->local_beginscan = 0; - stats->local_rescan = 0; - stats->local_endscan = 0; - stats->local_getnext = 0; - stats->local_fetch = 0; - stats->local_insert = 0; - stats->local_delete = 0; - stats->local_replace = 0; - stats->local_mark4update = 0; - stats->local_markpos = 0; - stats->local_restrpos = 0; - stats->local_BufferGetRelation = 0; - stats->local_RelationIdGetRelation = 0; - stats->local_RelationIdGetRelation_Buf = 0; - stats->local_getreldesc = 0; - stats->local_heapgettup = 0; - stats->local_RelationPutHeapTuple = 0; - stats->local_RelationPutLongHeapTuple = 0; - - /* - * reset local timestamps - */ - time(&stats->local_reset_timestamp); - time(&stats->last_request_timestamp); -} -#endif - -#ifdef NOT_USED -/* ---------------- - * GetHeapAccessStatistics - * ---------------- - */ -HeapAccessStatistics -GetHeapAccessStatistics() -{ - HeapAccessStatistics stats; - - /* - * return nothing if stats aren't initialized - */ - if (heap_access_stats == NULL) - return NULL; - - /* - * record the current request time - */ - time(&heap_access_stats->last_request_timestamp); - - /* - * allocate a copy of the stats and return it to the caller. - */ - stats = (HeapAccessStatistics) - palloc(sizeof(HeapAccessStatisticsData)); - - memmove(stats, - heap_access_stats, - sizeof(HeapAccessStatisticsData)); - - return stats; -} -#endif - -#ifdef NOT_USED -/* ---------------- - * PrintHeapAccessStatistics - * ---------------- - */ -void -PrintHeapAccessStatistics(HeapAccessStatistics stats) -{ - /* - * return nothing if stats aren't valid - */ - if (stats == NULL) - return; - - printf("======== heap am statistics ========\n"); - printf("init_global_timestamp: %s", - ctime(&(stats->init_global_timestamp))); - - printf("local_reset_timestamp: %s", - ctime(&(stats->local_reset_timestamp))); - - printf("last_request_timestamp: %s", - ctime(&(stats->last_request_timestamp))); - - printf("local/global_open: %6d/%6d\n", - stats->local_open, stats->global_open); - - printf("local/global_openr: %6d/%6d\n", - stats->local_openr, stats->global_openr); - - printf("local/global_close: %6d/%6d\n", - stats->local_close, stats->global_close); - - printf("local/global_beginscan: %6d/%6d\n", - stats->local_beginscan, stats->global_beginscan); - - printf("local/global_rescan: %6d/%6d\n", - stats->local_rescan, stats->global_rescan); - - printf("local/global_endscan: %6d/%6d\n", - stats->local_endscan, stats->global_endscan); - - printf("local/global_getnext: %6d/%6d\n", - stats->local_getnext, stats->global_getnext); - - printf("local/global_fetch: %6d/%6d\n", - stats->local_fetch, stats->global_fetch); - - printf("local/global_insert: %6d/%6d\n", - stats->local_insert, stats->global_insert); - - printf("local/global_delete: %6d/%6d\n", - stats->local_delete, stats->global_delete); - - printf("local/global_replace: %6d/%6d\n", - stats->local_replace, stats->global_replace); - - printf("local/global_mark4update: %6d/%6d\n", - stats->local_mark4update, stats->global_mark4update); - - printf("local/global_markpos: %6d/%6d\n", - stats->local_markpos, stats->global_markpos); - - printf("local/global_restrpos: %6d/%6d\n", - stats->local_restrpos, stats->global_restrpos); - - printf("================\n"); - - printf("local/global_BufferGetRelation: %6d/%6d\n", - stats->local_BufferGetRelation, - stats->global_BufferGetRelation); - - printf("local/global_RelationIdGetRelation: %6d/%6d\n", - stats->local_RelationIdGetRelation, - stats->global_RelationIdGetRelation); - - printf("local/global_RelationIdGetRelation_Buf: %6d/%6d\n", - stats->local_RelationIdGetRelation_Buf, - stats->global_RelationIdGetRelation_Buf); - - printf("local/global_getreldesc: %6d/%6d\n", - stats->local_getreldesc, stats->global_getreldesc); - - printf("local/global_heapgettup: %6d/%6d\n", - stats->local_heapgettup, stats->global_heapgettup); - - printf("local/global_RelationPutHeapTuple: %6d/%6d\n", - stats->local_RelationPutHeapTuple, - stats->global_RelationPutHeapTuple); - - printf("local/global_RelationPutLongHeapTuple: %6d/%6d\n", - stats->local_RelationPutLongHeapTuple, - stats->global_RelationPutLongHeapTuple); - - printf("===================================\n"); - - printf("\n"); -} -#endif - -#ifdef NOT_USED -/* ---------------- - * PrintAndFreeHeapAccessStatistics - * ---------------- - */ -void -PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats) -{ - PrintHeapAccessStatistics(stats); - if (stats != NULL) - pfree(stats); -} -#endif - -/* ---------------------------------------------------------------- - * access method initialization - * ---------------------------------------------------------------- - */ -/* ---------------- - * initam should someday be moved someplace else. - * ---------------- - */ -void -initam(void) -{ - /* - * initialize heap statistics. - */ - InitHeapAccessStatistics(); -} diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 8e1d5b87332a1de5acfc1a8c9be91e9344925c63..523349ebdb566d9f34576682152b0c07545a6644 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,12 +8,12 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.54 2001/10/25 05:49:21 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.55 2001/11/02 16:30:29 tgl Exp $ * * INTERFACE ROUTINES - * index_open - open an index relation by relationId - * index_openr - open a index relation by name - * index_close - close a index relation + * index_open - open an index relation by relation OID + * index_openr - open an index relation by name + * index_close - close an index relation * index_beginscan - start a scan of an index * index_rescan - restart a scan of an index * index_endscan - end a scan @@ -106,15 +106,17 @@ * index_ interface functions * ---------------------------------------------------------------- */ + /* ---------------- - * index_open - open an index relation by relationId - * - * presently the relcache routines do all the work we need - * to open/close index relations. However, callers of index_open - * expect it to succeed, so we need to check for a failure return. + * index_open - open an index relation by relation OID * * Note: we acquire no lock on the index. An AccessShareLock is * acquired by index_beginscan (and released by index_endscan). + * Generally, the caller should already hold some type of lock on + * the parent relation to ensure that the index doesn't disappear. + * + * This is a convenience routine adapted for indexscan use. + * Some callers may prefer to use relation_open directly. * ---------------- */ Relation @@ -122,13 +124,11 @@ index_open(Oid relationId) { Relation r; - r = RelationIdGetRelation(relationId); - - if (!RelationIsValid(r)) - elog(ERROR, "Index %u does not exist", relationId); + r = relation_open(relationId, NoLock); if (r->rd_rel->relkind != RELKIND_INDEX) - elog(ERROR, "%s is not an index relation", RelationGetRelationName(r)); + elog(ERROR, "%s is not an index relation", + RelationGetRelationName(r)); pgstat_initstats(&r->pgstat_info, r); @@ -136,23 +136,21 @@ index_open(Oid relationId) } /* ---------------- - * index_openr - open a index relation by name + * index_openr - open an index relation by name * * As above, but lookup by name instead of OID. * ---------------- */ Relation -index_openr(char *relationName) +index_openr(const char *relationName) { Relation r; - r = RelationNameGetRelation(relationName); - - if (!RelationIsValid(r)) - elog(ERROR, "Index '%s' does not exist", relationName); + r = relation_openr(relationName, NoLock); if (r->rd_rel->relkind != RELKIND_INDEX) - elog(ERROR, "%s is not an index relation", RelationGetRelationName(r)); + elog(ERROR, "%s is not an index relation", + RelationGetRelationName(r)); pgstat_initstats(&r->pgstat_info, r); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 4e338b0eb21c137868075e507b61fc0fceb699cc..b5c25516cd1f1e1654ca2f5d49585c5aaff0884a 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.167 2001/10/25 20:37:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.168 2001/11/02 16:30:29 tgl Exp $ * * * INTERFACE ROUTINES @@ -1417,15 +1417,9 @@ UpdateStats(Oid relid, double reltuples) */ /* - * Can't use heap_open here since we don't know if it's an index... + * Grabbing lock here is probably redundant ... */ - whichRel = RelationIdGetRelation(relid); - - if (!RelationIsValid(whichRel)) - elog(ERROR, "UpdateStats: cannot open relation id %u", relid); - - /* Grab lock to be held till end of xact (probably redundant...) */ - LockRelation(whichRel, ShareLock); + whichRel = relation_open(relid, ShareLock); /* * Find the RELATION relation tuple for the given relation. @@ -1553,8 +1547,7 @@ UpdateStats(Oid relid, double reltuples) heap_endscan(pg_class_scan); heap_close(pg_class, RowExclusiveLock); - /* Cheating a little bit since we didn't open it with heap_open... */ - heap_close(whichRel, NoLock); + relation_close(whichRel, NoLock); } diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index b9cfee96e4f2642be77626373a2227535ec0e833..93c52e1b3340e1ae9a2631a609b5ddeff937f208 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.148 2001/10/31 04:49:43 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.149 2001/11/02 16:30:29 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -55,7 +55,6 @@ static void drop_default(Oid relid, int16 attnum); static bool needs_toast_table(Relation rel); -static bool is_relation(char *name); /* -------------------------------- @@ -554,9 +553,11 @@ AlterTableAlterColumnDefault(const char *relationName, #endif rel = heap_openr(relationName, AccessExclusiveLock); + if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", relationName); + myrelid = RelationGetRelid(rel); heap_close(rel, NoLock); @@ -721,9 +722,11 @@ AlterTableAlterColumnStatistics(const char *relationName, #endif rel = heap_openr(relationName, AccessExclusiveLock); + if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", relationName); + myrelid = RelationGetRelid(rel); heap_close(rel, NoLock); /* close rel, but keep lock! */ @@ -1192,12 +1195,16 @@ AlterTableAddConstraint(char *relationName, elog(ERROR, "ALTER TABLE: permission denied"); #endif - /* Disallow ADD CONSTRAINT on views, indexes, sequences, etc */ - if (!is_relation(relationName)) - elog(ERROR, "ALTER TABLE ADD CONSTRAINT: %s is not a table", + /* + * Grab an exclusive lock on the target table, which we will NOT + * release until end of transaction. + */ + rel = heap_openr(relationName, AccessExclusiveLock); + + if (rel->rd_rel->relkind != RELKIND_RELATION) + elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", relationName); - rel = heap_openr(relationName, AccessExclusiveLock); myrelid = RelationGetRelid(rel); if (inh) @@ -1686,7 +1693,7 @@ AlterTableDropConstraint(const char *relationName, /* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */ if (rel->rd_rel->relkind != RELKIND_RELATION) - elog(ERROR, "ALTER TABLE / DROP CONSTRAINT: %s is not a table", + elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", relationName); /* @@ -2053,7 +2060,6 @@ void LockTableCommand(LockStmt *lockstmt) { List *p; - Relation rel; /* * Iterate over the list and open, lock, and close the relations one @@ -2064,12 +2070,7 @@ LockTableCommand(LockStmt *lockstmt) { char *relname = strVal(lfirst(p)); int aclresult; - - rel = heap_openr(relname, NoLock); - - if (rel->rd_rel->relkind != RELKIND_RELATION) - elog(ERROR, "LOCK TABLE: %s is not a table", - relname); + Relation rel; if (lockstmt->mode == AccessShareLock) aclresult = pg_aclcheck(relname, GetUserId(), @@ -2081,21 +2082,13 @@ LockTableCommand(LockStmt *lockstmt) if (aclresult != ACLCHECK_OK) elog(ERROR, "LOCK TABLE: permission denied"); - LockRelation(rel, lockstmt->mode); - - heap_close(rel, NoLock); /* close rel, keep lock */ - } -} - - -static bool -is_relation(char *name) -{ - Relation rel = heap_openr(name, NoLock); + rel = relation_openr(relname, lockstmt->mode); - bool retval = (rel->rd_rel->relkind == RELKIND_RELATION); - - heap_close(rel, NoLock); + /* Currently, we only allow plain tables to be locked */ + if (rel->rd_rel->relkind != RELKIND_RELATION) + elog(ERROR, "LOCK TABLE: %s is not a table", + relname); - return retval; + relation_close(rel, NoLock); /* close rel, keep lock */ + } } diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 647cb55b7e7d217c3a06ed5ffa5e5381b22b5df2..baeff0c172d240032826b5b81f269a74ad59b8c4 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1999-2001, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.34 2001/10/25 05:49:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.35 2001/11/02 16:30:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -336,16 +336,8 @@ CommentRelation(int reltype, char *relname, char *comment) * ensures no one else drops the relation before we commit. (If they * did, they'd fail to remove the entry we are about to make in * pg_description.) - * - * heap_openr will complain if it's an index, so we must do this: */ - if (reltype != INDEX) - relation = heap_openr(relname, AccessShareLock); - else - { - relation = index_openr(relname); - LockRelation(relation, AccessShareLock); - } + relation = relation_openr(relname, AccessShareLock); /* Next, verify that the relation type matches the intent */ @@ -374,11 +366,7 @@ CommentRelation(int reltype, char *relname, char *comment) CreateComments(RelationGetRelid(relation), RelOid_pg_class, 0, comment); /* Done, but hold lock until commit */ - - if (reltype != INDEX) - heap_close(relation, NoLock); - else - index_close(relation); + relation_close(relation, NoLock); } /*------------------------------------------------------------------ diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c index c65cfcc5519ed7c8d88d77e0e44e9dc7041c2e8b..42abe24f1387aa8940c3dc58dfe34ceac13245d4 100644 --- a/src/backend/commands/rename.c +++ b/src/backend/commands/rename.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.59 2001/10/25 05:49:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.60 2001/11/02 16:30:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -258,19 +258,10 @@ renamerel(const char *oldrelname, const char *newrelname) return; /* all done... */ /* - * Instead of using heap_openr(), do it the hard way, so that we can - * rename indexes as well as regular relations. - */ - targetrelation = RelationNameGetRelation(oldrelname); - - if (!RelationIsValid(targetrelation)) - elog(ERROR, "Relation \"%s\" does not exist", oldrelname); - - /* - * Grab an exclusive lock on the target table, which we will NOT + * Grab an exclusive lock on the target table or index, which we will NOT * release until end of transaction. */ - LockRelation(targetrelation, AccessExclusiveLock); + targetrelation = relation_openr(oldrelname, AccessExclusiveLock); reloid = RelationGetRelid(targetrelation); relkind = targetrelation->rd_rel->relkind; @@ -278,7 +269,7 @@ renamerel(const char *oldrelname, const char *newrelname) /* * Close rel, but keep exclusive lock! */ - heap_close(targetrelation, NoLock); + relation_close(targetrelation, NoLock); /* * Flush the relcache entry (easier than trying to change it at diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index f6d94e5c552e456154e9354e387f9d813fb5668d..1f2887031e489add21960c553f8ab02a7029ab2b 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.112 2001/10/25 05:49:39 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.113 2001/11/02 16:30:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -131,7 +131,6 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, List *i = NIL; Node *first_arg = NULL; char *refname; - Relation rd; int nargs = length(fargs); int argn; Func *funcnode; @@ -200,13 +199,10 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, if (attisset) { toid = exprType(first_arg); - rd = heap_openr_nofail(typeidTypeName(toid)); - if (RelationIsValid(rd)) - heap_close(rd, NoLock); - else + argrelid = typeidTypeRelid(toid); + if (argrelid == InvalidOid) elog(ERROR, "Type '%s' is not a relation type", typeidTypeName(toid)); - argrelid = typeidTypeRelid(toid); /* * A projection must match an attribute name of the rel. diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 3dc6deb0cb4704eacfb23c2494eed4f8d0ea502b..3a48b133bfe8aeb3bf50de83fc858b740d51dd67 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.96 2001/10/28 06:25:54 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.97 2001/11/02 16:30:29 tgl Exp $ * * *------------------------------------------------------------------------- @@ -292,12 +292,6 @@ InitPostgres(const char *dbname, const char *username) */ RelationCacheInitialize(); - /* - * Initialize the access methods. Does not touch files (?) - thomas - * 1997-11-01 - */ - initam(); - /* * Initialize all the system catalog caches. * diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 88c1c06699b5c89e92dd348e65d513dff31520c6..dbef1a6cdad74fe6164ca291757f90028ee6f7d6 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: genam.h,v 1.29 2001/10/28 06:25:59 momjian Exp $ + * $Id: genam.h,v 1.30 2001/11/02 16:30:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state); * ---------------- */ extern Relation index_open(Oid relationId); -extern Relation index_openr(char *relationName); +extern Relation index_openr(const char *relationName); extern void index_close(Relation relation); extern InsertIndexResult index_insert(Relation relation, Datum *datum, char *nulls, diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 61fa3afea5660a68e837fe8865cadeed08d17177..b0124ed31cdd343d61b39cfb8c1d22940fa91de0 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -7,15 +7,13 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: heapam.h,v 1.70 2001/10/28 06:25:59 momjian Exp $ + * $Id: heapam.h,v 1.71 2001/11/02 16:30:29 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef HEAPAM_H #define HEAPAM_H -#include <time.h> - #include "access/htup.h" #include "access/relscan.h" #include "access/tupmacs.h" @@ -26,67 +24,11 @@ #include "utils/tqual.h" /* ---------------------------------------------------------------- - * heap access method statistics + * leftover cruft from old statistics code * ---------------------------------------------------------------- */ -typedef struct HeapAccessStatisticsData -{ - time_t init_global_timestamp; /* time global statistics started */ - time_t local_reset_timestamp; /* last time local reset was done */ - time_t last_request_timestamp; /* last time stats were requested */ - - int global_open; - int global_openr; - int global_close; - int global_beginscan; - int global_rescan; - int global_endscan; - int global_getnext; - int global_fetch; - int global_insert; - int global_delete; - int global_replace; - int global_mark4update; - int global_markpos; - int global_restrpos; - int global_BufferGetRelation; - int global_RelationIdGetRelation; - int global_RelationIdGetRelation_Buf; - int global_RelationNameGetRelation; - int global_getreldesc; - int global_heapgettup; - int global_RelationPutHeapTuple; - int global_RelationPutLongHeapTuple; - - int local_open; - int local_openr; - int local_close; - int local_beginscan; - int local_rescan; - int local_endscan; - int local_getnext; - int local_fetch; - int local_insert; - int local_delete; - int local_replace; - int local_mark4update; - int local_markpos; - int local_restrpos; - int local_BufferGetRelation; - int local_RelationIdGetRelation; - int local_RelationIdGetRelation_Buf; - int local_RelationNameGetRelation; - int local_getreldesc; - int local_heapgettup; - int local_RelationPutHeapTuple; - int local_RelationPutLongHeapTuple; -} HeapAccessStatisticsData; - -typedef HeapAccessStatisticsData *HeapAccessStatistics; - -#define IncrHeapAccessStat(x) \ - (heap_access_stats == NULL ? 0 : (heap_access_stats->x)++) +#define IncrHeapAccessStat(x) ((void) 0) /* ---------------- * fastgetattr @@ -180,7 +122,6 @@ extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, extern Datum heap_getsysattr(HeapTuple tup, int attnum, bool *isnull); -extern HeapAccessStatistics heap_access_stats; /* in stats.c */ /* ---------------- * function prototypes for heap access method @@ -192,11 +133,14 @@ extern HeapAccessStatistics heap_access_stats; /* in stats.c */ /* heapam.c */ +extern Relation relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation relation_openr(const char *relationName, LOCKMODE lockmode); +extern void relation_close(Relation relation, LOCKMODE lockmode); + extern Relation heap_open(Oid relationId, LOCKMODE lockmode); extern Relation heap_openr(const char *relationName, LOCKMODE lockmode); -extern Relation heap_open_nofail(Oid relationId); -extern Relation heap_openr_nofail(const char *relationName); -extern void heap_close(Relation relation, LOCKMODE lockmode); +#define heap_close(r,l) relation_close(r,l) + extern HeapScanDesc heap_beginscan(Relation relation, int atend, Snapshot snapshot, unsigned nkeys, ScanKey key); extern void heap_rescan(HeapScanDesc scan, bool scanFromEnd, ScanKey key); @@ -242,8 +186,4 @@ extern HeapTuple heap_modifytuple(HeapTuple tuple, extern void heap_freetuple(HeapTuple tuple); extern HeapTuple heap_addheader(int natts, Size structlen, void *structure); -/* in common/heap/stats.c */ -extern void PrintHeapAccessStatistics(HeapAccessStatistics stats); -extern void initam(void); - #endif /* HEAPAM_H */ diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index f652fb1eb0544e36e36fb64e4ab501a3e09353ba..8a4344fe1ec4d6837c0baa71ea61a11fbe678498 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -43,7 +43,7 @@ delete from; ERROR: parser: parse error at or near ";" -- no such relation delete from nonesuch; -ERROR: Relation 'nonesuch' does not exist +ERROR: Relation "nonesuch" does not exist -- -- DESTROY @@ -78,7 +78,7 @@ ERROR: renamerel: relation "stud_emp" exists -- attribute renaming -- no such relation alter table nonesuchrel rename column nonesuchatt to newnonesuchatt; -ERROR: Relation 'nonesuchrel' does not exist +ERROR: Relation "nonesuchrel" does not exist -- no such attribute alter table emp rename column nonesuchatt to newnonesuchatt; ERROR: renameatt: attribute "nonesuchatt" does not exist diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out index 7d085de85bcd7aa30cec934074e55b628f931b51..a3a583ec624a71a6fd46e0c3bc14cbb33b78a85b 100644 --- a/src/test/regress/expected/temp.out +++ b/src/test/regress/expected/temp.out @@ -34,4 +34,4 @@ CREATE TEMP TABLE temptest(col int); -- test temp table deletion \c regression SELECT * FROM temptest; -ERROR: Relation 'temptest' does not exist +ERROR: Relation "temptest" does not exist