# 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 $
#
#-------------------------------------------------------------------------
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
*
*
* 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
*/
/* ----------------
- * 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;
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);
}
/* ----------------
- * 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;
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;
}
}
/* 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");
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * 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();
-}
*
*
* 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
* 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
{
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);
}
/* ----------------
- * 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);
*
*
* 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
*/
/*
- * 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.
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);
}
*
*
* 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
static void drop_default(Oid relid, int16 attnum);
static bool needs_toast_table(Relation rel);
-static bool is_relation(char *name);
/* --------------------------------
#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);
#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! */
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)
/* 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);
/*
LockTableCommand(LockStmt *lockstmt)
{
List *p;
- Relation rel;
/*
* Iterate over the list and open, lock, and close the relations one
{
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(),
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 */
+ }
}
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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 */
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);
}
/*------------------------------------------------------------------
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
/*
* 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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
List *i = NIL;
Node *first_arg = NULL;
char *refname;
- Relation rd;
int nargs = length(fargs);
int argn;
Func *funcnode;
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.
*
*
* 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 $
*
*
*-------------------------------------------------------------------------
RelationCacheInitialize();
/*
- * Initialize the access methods. Does not touch files (?) - thomas
- * 1997-11-01
- */
- initam();
-
- /*
* Initialize all the system catalog caches.
*
* Does not touch files since all routines are builtins (?) - thomas
* 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 $
*
*-------------------------------------------------------------------------
*/
* ----------------
*/
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,
* 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"
#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
extern Datum heap_getsysattr(HeapTuple tup, int attnum, bool *isnull);
-extern HeapAccessStatistics heap_access_stats; /* in stats.c */
/* ----------------
* function prototypes for heap access method
/* 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);
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 */
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
-- 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
-- test temp table deletion
\c regression
SELECT * FROM temptest;
-ERROR: Relation 'temptest' does not exist
+ERROR: Relation "temptest" does not exist