diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 5371da7ee7..950d2016df 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,6 +1,6 @@ @@ -568,6 +568,15 @@ Name of the table, index, view, etc. + + relnamespace + oid + pg_namespace.oid + + The OID of the namespace that contains this relation + + + reltype oid diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index adcf9bc6cb..86c62e4fdb 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,15 +8,17 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.131 2002/03/03 17:47:53 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.132 2002/03/26 19:15:11 tgl Exp $ * * * INTERFACE ROUTINES * relation_open - open any relation by relation OID - * relation_openr - open any relation by name + * relation_openrv - open any relation specified by a RangeVar + * relation_openr - open a system 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_openrv - open a heap relation specified by a RangeVar + * heap_openr - open a system heap relation by name * heap_close - (now just a macro for relation_close) * heap_beginscan - begin relation scan * heap_rescan - restart a relation scan @@ -44,6 +46,7 @@ #include "access/valid.h" #include "access/xlogutils.h" #include "catalog/catalog.h" +#include "catalog/namespace.h" #include "miscadmin.h" #include "utils/inval.h" #include "utils/relcache.h" @@ -481,13 +484,56 @@ relation_open(Oid relationId, LOCKMODE lockmode) } /* ---------------- - * relation_openr - open any relation by name + * relation_openrv - open any relation specified by a RangeVar * - * As above, but lookup by name instead of OID. + * As above, but the relation is specified by a RangeVar. * ---------------- */ Relation -relation_openr(const char *relationName, LOCKMODE lockmode) +relation_openrv(const RangeVar *relation, LOCKMODE lockmode) +{ + Oid relOid; + + /* + * In bootstrap mode, don't do any namespace processing. + */ + if (IsBootstrapProcessingMode()) + { + Assert(relation->schemaname == NULL); + return relation_openr(relation->relname, lockmode); + } + + /* + * 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 syscache 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(); + + /* Look up the appropriate relation using namespace search */ + relOid = RangeVarGetRelid(relation, false); + + /* Let relation_open do the rest */ + return relation_open(relOid, lockmode); +} + +/* ---------------- + * relation_openr - open a system relation specified by name. + * + * As above, but the relation is specified by an unqualified name; + * it is assumed to live in the system catalog namespace. + * ---------------- + */ +Relation +relation_openr(const char *sysRelationName, LOCKMODE lockmode) { Relation r; @@ -500,25 +546,15 @@ relation_openr(const char *relationName, LOCKMODE lockmode) 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. + * We assume we should not need to worry about the rel's OID changing, + * hence no need for AcceptInvalidationMessages here. */ - if (lockmode != NoLock) - AcceptInvalidationMessages(); /* The relcache does all the real work... */ - r = RelationNameGetRelation(relationName); + r = RelationSysNameGetRelation(sysRelationName); if (!RelationIsValid(r)) - elog(ERROR, "Relation \"%s\" does not exist", relationName); + elog(ERROR, "Relation \"%s\" does not exist", sysRelationName); if (lockmode != NoLock) LockRelation(r, lockmode); @@ -582,17 +618,44 @@ heap_open(Oid relationId, LOCKMODE lockmode) } /* ---------------- - * heap_openr - open a heap relation by name + * heap_openrv - open a heap relation specified + * by a RangeVar node * - * As above, but lookup by name instead of OID. + * As above, but relation is specified by a RangeVar. * ---------------- */ Relation -heap_openr(const char *relationName, LOCKMODE lockmode) +heap_openrv(const RangeVar *relation, LOCKMODE lockmode) { Relation r; - r = relation_openr(relationName, lockmode); + r = relation_openrv(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)); + + pgstat_initstats(&r->pgstat_info, r); + + return r; +} + +/* ---------------- + * heap_openr - open a system heap relation specified by name. + * + * As above, but the relation is specified by an unqualified name; + * it is assumed to live in the system catalog namespace. + * ---------------- + */ +Relation +heap_openr(const char *sysRelationName, LOCKMODE lockmode) +{ + Relation r; + + r = relation_openr(sysRelationName, lockmode); if (r->rd_rel->relkind == RELKIND_INDEX) elog(ERROR, "%s is an index relation", diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 523349ebdb..ea043afb34 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -8,11 +8,12 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.55 2001/11/02 16:30:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.56 2002/03/26 19:15:14 tgl Exp $ * * INTERFACE ROUTINES * index_open - open an index relation by relation OID - * index_openr - open an index relation by name + * index_openrv - open an index relation specified by a RangeVar + * index_openr - open a system 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 @@ -136,17 +137,41 @@ index_open(Oid relationId) } /* ---------------- - * index_openr - open an index relation by name + * index_openrv - open an index relation specified + * by a RangeVar node * - * As above, but lookup by name instead of OID. + * As above, but relation is specified by a RangeVar. * ---------------- */ Relation -index_openr(const char *relationName) +index_openrv(const RangeVar *relation) { Relation r; - r = relation_openr(relationName, NoLock); + r = relation_openrv(relation, NoLock); + + if (r->rd_rel->relkind != RELKIND_INDEX) + elog(ERROR, "%s is not an index relation", + RelationGetRelationName(r)); + + pgstat_initstats(&r->pgstat_info, r); + + return r; +} + +/* ---------------- + * index_openr - open a system index relation specified by name. + * + * As above, but the relation is specified by an unqualified name; + * it is assumed to live in the system catalog namespace. + * ---------------- + */ +Relation +index_openr(const char *sysRelationName) +{ + Relation r; + + r = relation_openr(sysRelationName, NoLock); if (r->rd_rel->relkind != RELKIND_INDEX) elog(ERROR, "%s is not an index relation", diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 04f68adee7..3b0d34f9fc 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.40 2002/03/02 21:39:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.41 2002/03/26 19:15:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,8 +32,10 @@ #include "catalog/pg_am.h" #include "catalog/pg_attribute.h" #include "catalog/pg_class.h" +#include "catalog/pg_namespace.h" #include "commands/defrem.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/nodes.h" #include "nodes/parsenodes.h" #include "nodes/pg_list.h" @@ -179,7 +181,9 @@ Boot_CreateStmt: } tupdesc = CreateTupleDesc(numattr, attrtypes); - reldesc = heap_create(LexIDStr($4), tupdesc, + reldesc = heap_create(LexIDStr($4), + PG_CATALOG_NAMESPACE, + tupdesc, false, true, true); reldesc->rd_rel->relhasoids = ! ($3); elog(DEBUG3, "bootstrap relation created"); @@ -191,6 +195,7 @@ Boot_CreateStmt: tupdesc = CreateTupleDesc(numattr,attrtypes); id = heap_create_with_catalog(LexIDStr($4), + PG_CATALOG_NAMESPACE, tupdesc, RELKIND_RELATION, ! ($3), @@ -232,7 +237,7 @@ Boot_DeclareIndexStmt: { do_start(); - DefineIndex(LexIDStr($5), + DefineIndex(makeRangeVar(NULL, LexIDStr($5)), LexIDStr($3), LexIDStr($7), $9, false, false, NULL, NIL); @@ -245,7 +250,7 @@ Boot_DeclareUniqueIndexStmt: { do_start(); - DefineIndex(LexIDStr($6), + DefineIndex(makeRangeVar(NULL, LexIDStr($6)), LexIDStr($4), LexIDStr($8), $10, true, false, NULL, NIL); diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 275b0579ff..a4ab6fce61 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.124 2002/03/15 19:20:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.125 2002/03/26 19:15:16 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -153,8 +153,8 @@ extern char *optarg; typedef struct _IndexList { - char *il_heap; - char *il_ind; + Oid il_heap; + Oid il_ind; IndexInfo *il_info; struct _IndexList *il_next; } IndexList; @@ -1080,8 +1080,8 @@ AddStr(char *str, int strlength, int mderef) * are present in the index. */ void -index_register(char *heap, - char *ind, +index_register(Oid heap, + Oid ind, IndexInfo *indexInfo) { IndexList *newind; @@ -1103,8 +1103,8 @@ index_register(char *heap, oldcxt = MemoryContextSwitchTo(nogc); newind = (IndexList *) palloc(sizeof(IndexList)); - newind->il_heap = pstrdup(heap); - newind->il_ind = pstrdup(ind); + newind->il_heap = heap; + newind->il_ind = ind; newind->il_info = (IndexInfo *) palloc(sizeof(IndexInfo)); memcpy(newind->il_info, indexInfo, sizeof(IndexInfo)); @@ -1126,8 +1126,8 @@ build_indices() Relation heap; Relation ind; - heap = heap_openr(ILHead->il_heap, NoLock); - ind = index_openr(ILHead->il_ind); + heap = heap_open(ILHead->il_heap, NoLock); + ind = index_open(ILHead->il_ind); index_build(heap, ind, ILHead->il_info); /* diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index d0bc7b3726..3d1126bf01 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/catalog # -# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.38 2002/03/22 21:34:43 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.39 2002/03/26 19:15:22 tgl Exp $ # #------------------------------------------------------------------------- @@ -10,7 +10,7 @@ subdir = src/backend/catalog top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -OBJS = catalog.o heap.o index.o indexing.o aclchk.o \ +OBJS = catalog.o heap.o index.o indexing.o namespace.o aclchk.o \ pg_aggregate.o pg_largeobject.o pg_namespace.o \ pg_operator.o pg_proc.o pg_type.o diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 2225dc3a14..bead0959d9 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.58 2002/03/21 23:27:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.59 2002/03/26 19:15:22 tgl Exp $ * * NOTES * See acl.h. @@ -22,6 +22,7 @@ #include "catalog/catalog.h" #include "catalog/catname.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_group.h" #include "catalog/pg_language.h" @@ -200,7 +201,8 @@ ExecuteGrantStmt_Table(GrantStmt *stmt) foreach(i, stmt->objects) { - char *relname = ((RangeVar *) lfirst(i))->relname; + RangeVar *relvar = (RangeVar *) lfirst(i); + Oid relOid; Relation relation; HeapTuple tuple; Form_pg_class pg_class_tuple; @@ -216,27 +218,27 @@ ExecuteGrantStmt_Table(GrantStmt *stmt) /* open pg_class */ relation = heap_openr(RelationRelationName, RowExclusiveLock); - tuple = SearchSysCache(RELNAME, - PointerGetDatum(relname), + relOid = RangeVarGetRelid(relvar, false); + tuple = SearchSysCache(RELOID, + ObjectIdGetDatum(relOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "relation \"%s\" not found", - relname); + elog(ERROR, "relation %u not found", relOid); pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple); - if (!pg_class_ownercheck(tuple->t_data->t_oid, GetUserId())) + if (!pg_class_ownercheck(relOid, GetUserId())) elog(ERROR, "%s: permission denied", - relname); + relvar->relname); if (pg_class_tuple->relkind == RELKIND_INDEX) elog(ERROR, "\"%s\" is an index", - relname); + relvar->relname); /* * If there's no ACL, create a default using the pg_class.relowner * field. */ - aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl, + aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl, &isNull); if (isNull) old_acl = acldefault(pg_class_tuple->relowner); diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh index 6324d90628..4edb86cdba 100644 --- a/src/backend/catalog/genbki.sh +++ b/src/backend/catalog/genbki.sh @@ -10,7 +10,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.25 2001/11/30 20:21:06 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.26 2002/03/26 19:15:24 tgl Exp $ # # NOTES # non-essential whitespace is removed from the generated file. @@ -136,6 +136,14 @@ for dir in $INCLUDE_DIRS; do fi done +# Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h +for dir in $INCLUDE_DIRS; do + if [ -f "$dir/catalog/pg_namespace.h" ]; then + PG_CATALOG_NAMESPACE=`grep '^#define[ ]*PG_CATALOG_NAMESPACE' $dir/catalog/pg_namespace.h | $AWK '{ print $3 }'` + break + fi +done + # Get FirstGenBKIObjectId from access/transam.h for dir in $INCLUDE_DIRS; do if [ -f "$dir/access/transam.h" ]; then @@ -185,6 +193,7 @@ sed -e "s/;[ ]*$//g" \ -e "s/(TransactionId/(xid/g" \ -e "s/PGUID/1/g" \ -e "s/NAMEDATALEN/$NAMEDATALEN/g" \ + -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \ -e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \ -e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \ -e "s/INDEX_MAX_KEYS\*4/$INDEXMAXKEYS4/g" \ diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 9df788406a..0b367e3dab 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.191 2002/03/22 02:56:30 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.192 2002/03/26 19:15:25 tgl Exp $ * * * INTERFACE ROUTINES @@ -38,7 +38,7 @@ #include "catalog/indexing.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_inherits.h" -#include "catalog/pg_index.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_relcheck.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" @@ -50,11 +50,9 @@ #include "optimizer/planmain.h" #include "optimizer/prep.h" #include "optimizer/var.h" -#include "parser/parse_coerce.h" #include "parser/parse_expr.h" #include "parser/parse_relation.h" #include "parser/parse_target.h" -#include "parser/parse_type.h" #include "rewrite/rewriteRemove.h" #include "storage/smgr.h" #include "utils/builtins.h" @@ -214,6 +212,7 @@ SystemAttributeByName(const char *attname, bool relhasoids) */ Relation heap_create(char *relname, + Oid relnamespace, TupleDesc tupDesc, bool istemp, bool storage_create, @@ -222,7 +221,8 @@ heap_create(char *relname, static unsigned int uniqueId = 0; Oid relid; - Oid tblNode = MyDatabaseId; + Oid dbid = MyDatabaseId; + RelFileNode rnode; bool nailme = false; Relation rel; @@ -238,9 +238,11 @@ heap_create(char *relname, /* * Real ugly stuff to assign the proper relid in the relation * descriptor follows. Note that only "bootstrapped" relations whose - * OIDs are hard-coded in pg_class.h need be listed here. + * OIDs are hard-coded in pg_class.h need be listed here. We also + * have to take special care for those rels that should be nailed + * in cache and/or are shared across databases. */ - if (relname && IsSystemRelationName(relname)) + if (relname && relnamespace == PG_CATALOG_NAMESPACE) { if (strcmp(TypeRelationName, relname) == 0) { @@ -264,24 +266,24 @@ heap_create(char *relname, } else if (strcmp(ShadowRelationName, relname) == 0) { - tblNode = InvalidOid; + dbid = InvalidOid; relid = RelOid_pg_shadow; } else if (strcmp(GroupRelationName, relname) == 0) { - tblNode = InvalidOid; + dbid = InvalidOid; relid = RelOid_pg_group; } else if (strcmp(DatabaseRelationName, relname) == 0) { - tblNode = InvalidOid; + dbid = InvalidOid; relid = RelOid_pg_database; } else { relid = newoid(); if (IsSharedSystemRelationName(relname)) - tblNode = InvalidOid; + dbid = InvalidOid; } } else @@ -297,11 +299,21 @@ heap_create(char *relname, PG_TEMP_REL_PREFIX, (int) MyProcPid, uniqueId++); } + /* + * For now, the physical identifier of the relation is the same as the + * logical identifier. + */ + rnode.tblNode = dbid; + rnode.relNode = relid; + /* * build the relcache entry. */ - rel = RelationBuildLocalRelation(relname, tupDesc, - relid, tblNode, + rel = RelationBuildLocalRelation(relname, + relnamespace, + tupDesc, + relid, dbid, + rnode, nailme); /* @@ -329,7 +341,7 @@ heap_storage_create(Relation rel) * 1) CheckAttributeNames() is used to make certain the tuple * descriptor contains a valid set of attribute names * - * 2) pg_class is opened and RelationFindRelid() + * 2) pg_class is opened and get_relname_relid() * performs a scan to ensure that no relation with the * same name already exists. * @@ -400,73 +412,6 @@ CheckAttributeNames(TupleDesc tupdesc, bool relhasoids) } } -/* -------------------------------- - * RelnameFindRelid - * - * Find any existing relation of the given name. - * -------------------------------- - */ -Oid -RelnameFindRelid(const char *relname) -{ - Oid relid; - - /* - * If this is not bootstrap (initdb) time, use the catalog index on - * pg_class. - */ - if (!IsBootstrapProcessingMode()) - { - relid = GetSysCacheOid(RELNAME, - PointerGetDatum(relname), - 0, 0, 0); - } - else - { - Relation pg_class_desc; - ScanKeyData key; - HeapScanDesc pg_class_scan; - HeapTuple tuple; - - pg_class_desc = heap_openr(RelationRelationName, AccessShareLock); - - /* - * At bootstrap time, we have to do this the hard way. Form the - * scan key. - */ - ScanKeyEntryInitialize(&key, - 0, - (AttrNumber) Anum_pg_class_relname, - (RegProcedure) F_NAMEEQ, - PointerGetDatum(relname)); - - /* - * begin the scan - */ - pg_class_scan = heap_beginscan(pg_class_desc, - 0, - SnapshotNow, - 1, - &key); - - /* - * get a tuple. if the tuple is NULL then it means we didn't find - * an existing relation. - */ - tuple = heap_getnext(pg_class_scan, 0); - - if (HeapTupleIsValid(tuple)) - relid = tuple->t_data->t_oid; - else - relid = InvalidOid; - - heap_endscan(pg_class_scan); - - heap_close(pg_class_desc, AccessShareLock); - } - return relid; -} - /* -------------------------------- * AddNewAttributeTuples * @@ -719,6 +664,7 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid) */ Oid heap_create_with_catalog(char *relname, + Oid relnamespace, TupleDesc tupdesc, char relkind, bool relhasoids, @@ -742,7 +688,7 @@ heap_create_with_catalog(char *relname, CheckAttributeNames(tupdesc, relhasoids); /* temp tables can mask non-temp tables */ - if ((!istemp && RelnameFindRelid(relname)) || + if ((!istemp && get_relname_relid(relname, relnamespace)) || (istemp && is_temp_rel_name(relname))) elog(ERROR, "Relation '%s' already exists", relname); @@ -765,8 +711,8 @@ heap_create_with_catalog(char *relname, * heap_storage_create() does all the "real" work of creating the disk * file for the relation. */ - new_rel_desc = heap_create(relname, tupdesc, istemp, false, - allow_system_table_mods); + new_rel_desc = heap_create(relname, relnamespace, tupdesc, + istemp, false, allow_system_table_mods); /* Fetch the relation OID assigned by heap_create */ new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid; @@ -916,10 +862,8 @@ RelationRemoveInheritance(Relation relation) heap_close(catalogRelation, RowExclusiveLock); } -/* -------------------------------- +/* * RelationRemoveIndexes - * - * -------------------------------- */ static void RelationRemoveIndexes(Relation relation) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index ce63a0fd54..17d290f84e 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.173 2002/03/03 17:47:54 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.174 2002/03/26 19:15:28 tgl Exp $ * * * INTERFACE ROUTINES @@ -48,10 +48,12 @@ #include "utils/catcache.h" #include "utils/fmgroids.h" #include "utils/inval.h" +#include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/syscache.h" #include "utils/temprel.h" + /* * macros used in guessing how many tuples are on a page. */ @@ -61,15 +63,13 @@ ((natts) * AVG_ATTR_SIZE + MAXALIGN(sizeof(HeapTupleHeaderData)))) /* non-export function prototypes */ -static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName, - bool istemp); static TupleDesc BuildFuncTupleDesc(Oid funcOid, Oid *classObjectId); static TupleDesc ConstructTupleDescriptor(Relation heapRelation, int numatts, AttrNumber *attNums, Oid *classObjectId); static void ConstructIndexReldesc(Relation indexRelation, Oid amoid); -static Oid UpdateRelationRelation(Relation indexRelation, char *temp_relname); +static void UpdateRelationRelation(Relation indexRelation, char *temp_relname); static void InitializeAttributeOids(Relation indexRelation, int numatts, Oid indexoid); static void AppendAttributeTuples(Relation indexRelation, int numatts); @@ -99,33 +99,6 @@ IsReindexProcessing(void) return reindexing; } -/* ---------------------------------------------------------------- - * GetHeapRelationOid - * ---------------------------------------------------------------- - */ -static Oid -GetHeapRelationOid(char *heapRelationName, char *indexRelationName, bool istemp) -{ - Oid indoid; - Oid heapoid; - - - indoid = RelnameFindRelid(indexRelationName); - - if ((!istemp && OidIsValid(indoid)) || - (istemp && is_temp_rel_name(indexRelationName))) - elog(ERROR, "index named \"%s\" already exists", - indexRelationName); - - heapoid = RelnameFindRelid(heapRelationName); - - if (!OidIsValid(heapoid)) - elog(ERROR, "cannot create index on non-existent relation \"%s\"", - heapRelationName); - - return heapoid; -} - static TupleDesc BuildFuncTupleDesc(Oid funcOid, Oid *classObjectId) @@ -356,12 +329,11 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid) * UpdateRelationRelation * ---------------------------------------------------------------- */ -static Oid +static void UpdateRelationRelation(Relation indexRelation, char *temp_relname) { Relation pg_class; HeapTuple tuple; - Oid tupleOid; Relation idescs[Num_pg_class_indices]; pg_class = heap_openr(RelationRelationName, RowExclusiveLock); @@ -372,9 +344,8 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname) (void *) indexRelation->rd_rel); /* - * the new tuple must have the same oid as the relcache entry for the - * index. sure would be embarrassing to do this sort of thing in - * polite company. + * the new tuple must have the oid already chosen for the index. + * sure would be embarrassing to do this sort of thing in polite company. */ tuple->t_data->t_oid = RelationGetRelid(indexRelation); heap_insert(pg_class, tuple); @@ -396,11 +367,8 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname) CatalogCloseIndices(Num_pg_class_indices, idescs); } - tupleOid = tuple->t_data->t_oid; heap_freetuple(tuple); heap_close(pg_class, RowExclusiveLock); - - return tupleOid; } /* ---------------------------------------------------------------- @@ -586,24 +554,31 @@ UpdateIndexRelation(Oid indexoid, * ---------------------------------------------------------------- */ Oid -index_create(char *heapRelationName, +index_create(Oid heapRelationId, char *indexRelationName, IndexInfo *indexInfo, Oid accessMethodObjectId, Oid *classObjectId, + bool istemp, bool primary, bool allow_system_table_mods) { Relation heapRelation; Relation indexRelation; TupleDesc indexTupDesc; - Oid heapoid; + Oid namespaceId; Oid indexoid; - bool istemp = is_temp_rel_name(heapRelationName); char *temp_relname = NULL; SetReindexProcessing(false); + /* + * Only SELECT ... FOR UPDATE are allowed while doing this + */ + heapRelation = heap_open(heapRelationId, ShareLock); + + namespaceId = RelationGetNamespace(heapRelation); + /* * check parameters */ @@ -611,19 +586,15 @@ index_create(char *heapRelationName, indexInfo->ii_NumKeyAttrs < 1) elog(ERROR, "must index at least one column"); - if (heapRelationName && !allow_system_table_mods && - IsSystemRelationName(heapRelationName) && IsNormalProcessingMode()) + if (!allow_system_table_mods && + IsSystemRelationName(RelationGetRelationName(heapRelation)) && + IsNormalProcessingMode()) elog(ERROR, "User-defined indexes on system catalogs are not supported"); - /* - * get heap relation oid and open the heap relation - */ - heapoid = GetHeapRelationOid(heapRelationName, indexRelationName, istemp); - - /* - * Only SELECT ... FOR UPDATE are allowed while doing this - */ - heapRelation = heap_open(heapoid, ShareLock); + if ((!istemp && get_relname_relid(indexRelationName, namespaceId)) || + (istemp && is_temp_rel_name(indexRelationName))) + elog(ERROR, "index named \"%s\" already exists", + indexRelationName); /* * construct tuple descriptor for index tuples @@ -649,8 +620,11 @@ index_create(char *heapRelationName, /* * create the index relation */ - indexRelation = heap_create(indexRelationName, indexTupDesc, + indexRelation = heap_create(indexRelationName, + namespaceId, + indexTupDesc, istemp, false, allow_system_table_mods); + indexoid = RelationGetRelid(indexRelation); /* * Obtain exclusive lock on it. Although no other backends can see it @@ -671,7 +645,7 @@ index_create(char *heapRelationName, * (append RELATION tuple) * ---------------- */ - indexoid = UpdateRelationRelation(indexRelation, temp_relname); + UpdateRelationRelation(indexRelation, temp_relname); /* * We create the disk file for this relation here @@ -699,7 +673,7 @@ index_create(char *heapRelationName, * (Or, could define a rule to maintain the predicate) --Nels, Feb '92 * ---------------- */ - UpdateIndexRelation(indexoid, heapoid, indexInfo, + UpdateIndexRelation(indexoid, heapRelationId, indexInfo, classObjectId, primary); /* @@ -725,7 +699,7 @@ index_create(char *heapRelationName, */ if (IsBootstrapProcessingMode()) { - index_register(heapRelationName, indexRelationName, indexInfo); + index_register(heapRelationId, indexoid, indexInfo); /* XXX shouldn't we close the heap and index rels here? */ } else diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index fcad116e99..da269d2841 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.84 2002/03/22 21:34:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.85 2002/03/26 19:15:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -44,7 +44,7 @@ char *Name_pg_attr_indices[Num_pg_attr_indices] = char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] = {AttrDefaultIndex}; char *Name_pg_class_indices[Num_pg_class_indices] = -{ClassNameIndex, ClassOidIndex}; +{ClassNameNspIndex, ClassOidIndex}; char *Name_pg_database_indices[Num_pg_database_indices] = {DatabaseNameIndex, DatabaseOidIndex}; char *Name_pg_group_indices[Num_pg_group_indices] = diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c new file mode 100644 index 0000000000..c9d8d21f92 --- /dev/null +++ b/src/backend/catalog/namespace.c @@ -0,0 +1,126 @@ +/*------------------------------------------------------------------------- + * + * namespace.c + * code to support accessing and searching namespaces + * + * This is separate from pg_namespace.c, which contains the routines that + * directly manipulate the pg_namespace system catalog. This module + * provides routines associated with defining a "namespace search path" + * and implementing search-path-controlled searches. + * + * + * 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/catalog/namespace.c,v 1.1 2002/03/26 19:15:32 tgl Exp $ + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "catalog/namespace.h" +#include "catalog/pg_namespace.h" +#include "miscadmin.h" +#include "utils/lsyscache.h" +#include "utils/syscache.h" + + +/* + * RangeVarGetRelid + * Given a RangeVar describing an existing relation, + * select the proper namespace and look up the relation OID. + * + * If the relation is not found, return InvalidOid if failOK = true, + * otherwise raise an error. + */ +Oid +RangeVarGetRelid(const RangeVar *relation, bool failOK) +{ + Oid namespaceId; + Oid relId; + + /* + * We check the catalog name and then ignore it. + */ + if (relation->catalogname) + { + if (strcmp(relation->catalogname, DatabaseName) != 0) + elog(ERROR, "Cross-database references are not implemented"); + } + + if (relation->schemaname) + { + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(relation->schemaname), + 0, 0, 0); + if (!OidIsValid(namespaceId)) + elog(ERROR, "Namespace \"%s\" does not exist", + relation->schemaname); + relId = get_relname_relid(relation->relname, namespaceId); + } + else + { + relId = RelnameGetRelid(relation->relname); + } + + if (!OidIsValid(relId) && !failOK) + { + if (relation->schemaname) + elog(ERROR, "Relation \"%s\".\"%s\" does not exist", + relation->schemaname, relation->relname); + else + elog(ERROR, "Relation \"%s\" does not exist", + relation->relname); + } + return relId; +} + +/* + * RangeVarGetCreationNamespace + * Given a RangeVar describing a to-be-created relation, + * choose which namespace to create it in. + */ +Oid +RangeVarGetCreationNamespace(const RangeVar *newRelation) +{ + Oid namespaceId; + + /* + * We check the catalog name and then ignore it. + */ + if (newRelation->catalogname) + { + if (strcmp(newRelation->catalogname, DatabaseName) != 0) + elog(ERROR, "Cross-database references are not implemented"); + } + + if (newRelation->schemaname) + { + namespaceId = GetSysCacheOid(NAMESPACENAME, + CStringGetDatum(newRelation->schemaname), + 0, 0, 0); + if (!OidIsValid(namespaceId)) + elog(ERROR, "Namespace \"%s\" does not exist", + newRelation->schemaname); + } + else + { + /* XXX Wrong! Need to get a default schema from somewhere */ + namespaceId = PG_CATALOG_NAMESPACE; + } + + return namespaceId; +} + +/* + * RelnameGetRelid + * Try to resolve an unqualified relation name. + * Returns OID if relation found in search path, else InvalidOid. + */ +Oid +RelnameGetRelid(const char *relname) +{ + /* XXX Wrong! must search search path */ + return get_relname_relid(relname, PG_CATALOG_NAMESPACE); +} diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index f373948742..0bd64232d1 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.72 2002/02/19 20:11:12 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.73 2002/03/26 19:15:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -38,7 +38,8 @@ static Oid copy_heap(Oid OIDOldHeap, char *NewName, bool istemp); -static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName); +static void copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName, + bool istemp); static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex); /* @@ -54,7 +55,7 @@ static void rebuildheap(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex); * hand, re-creating n indexes may blow out the space. */ void -cluster(char *oldrelname, char *oldindexname) +cluster(RangeVar *oldrelation, char *oldindexname) { Oid OIDOldHeap, OIDOldIndex, @@ -64,34 +65,40 @@ cluster(char *oldrelname, char *oldindexname) bool istemp; char NewHeapName[NAMEDATALEN]; char NewIndexName[NAMEDATALEN]; - char saveoldrelname[NAMEDATALEN]; - char saveoldindexname[NAMEDATALEN]; + RangeVar *saveoldrelation; + RangeVar *saveoldindex; + RangeVar *NewHeap; + RangeVar *NewIndex; /* - * Copy the arguments into local storage, just to be safe. + * FIXME SCHEMAS: The old code had the comment: + * "Copy the arguments into local storage, just to be safe." + * By using copyObject we are not using local storage. + * Was that really necessary? */ - StrNCpy(saveoldrelname, oldrelname, NAMEDATALEN); - StrNCpy(saveoldindexname, oldindexname, NAMEDATALEN); + saveoldrelation = copyObject(oldrelation); + saveoldindex = copyObject(oldrelation); + saveoldindex->relname = pstrdup(oldindexname); /* * We grab exclusive access to the target rel and index for the * duration of the transaction. */ - OldHeap = heap_openr(saveoldrelname, AccessExclusiveLock); + OldHeap = heap_openrv(saveoldrelation, AccessExclusiveLock); OIDOldHeap = RelationGetRelid(OldHeap); - OldIndex = index_openr(saveoldindexname); + OldIndex = index_openrv(saveoldindex); LockRelation(OldIndex, AccessExclusiveLock); OIDOldIndex = RelationGetRelid(OldIndex); - istemp = is_temp_rel_name(saveoldrelname); + istemp = is_temp_rel_name(saveoldrelation->relname); /* * Check that index is in fact an index on the given relation */ if (OldIndex->rd_index->indrelid != OIDOldHeap) elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"", - saveoldindexname, saveoldrelname); + saveoldindex->relname, saveoldrelation->relname); /* Drop relcache refcnts, but do NOT give up the locks */ heap_close(OldHeap, NoLock); @@ -117,21 +124,26 @@ cluster(char *oldrelname, char *oldindexname) /* Create new index over the tuples of the new heap. */ snprintf(NewIndexName, NAMEDATALEN, "temp_%u", OIDOldIndex); - copy_index(OIDOldIndex, OIDNewHeap, NewIndexName); + copy_index(OIDOldIndex, OIDNewHeap, NewIndexName, istemp); CommandCounterIncrement(); /* Destroy old heap (along with its index) and rename new. */ - heap_drop_with_catalog(saveoldrelname, allowSystemTableMods); + heap_drop_with_catalog(saveoldrelation->relname, allowSystemTableMods); CommandCounterIncrement(); - renamerel(NewHeapName, saveoldrelname); + NewHeap = copyObject(saveoldrelation); + NewHeap->relname = NewHeapName; + NewIndex = copyObject(saveoldindex); + NewIndex->relname = NewIndexName; + + renamerel(NewHeap, saveoldrelation->relname); /* This one might be unnecessary, but let's be safe. */ CommandCounterIncrement(); - renamerel(NewIndexName, saveoldindexname); + renamerel(NewIndex, saveoldindex->relname); } static Oid @@ -151,7 +163,9 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) */ tupdesc = CreateTupleDescCopyConstr(OldHeapDesc); - OIDNewHeap = heap_create_with_catalog(NewName, tupdesc, + OIDNewHeap = heap_create_with_catalog(NewName, + RelationGetNamespace(OldHeap), + tupdesc, OldHeap->rd_rel->relkind, OldHeap->rd_rel->relhasoids, istemp, @@ -168,7 +182,7 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) * AlterTableCreateToastTable ends with CommandCounterIncrement(), so * that the TOAST table will be visible for insertion. */ - AlterTableCreateToastTable(NewName, true); + AlterTableCreateToastTable(OIDNewHeap, true); heap_close(OldHeap, NoLock); @@ -176,7 +190,7 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp) } static void -copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName) +copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName, bool istemp) { Relation OldIndex, NewHeap; @@ -189,18 +203,15 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName) * Create a new index like the old one. To do this I get the info * from pg_index, and add a new index with a temporary name (that will * be changed later). - * - * NOTE: index_create will cause the new index to be a temp relation if - * its parent table is, so we don't need to do anything special for - * the temp-table case here. */ indexInfo = BuildIndexInfo(OldIndex->rd_index); - index_create(RelationGetRelationName(NewHeap), + index_create(OIDNewHeap, NewIndexName, indexInfo, OldIndex->rd_rel->relam, OldIndex->rd_index->indclass, + istemp, OldIndex->rd_index->indisprimary, allowSystemTableMods); diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index af9e76e279..bf7980d42c 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.165 2002/03/22 21:34:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.166 2002/03/26 19:15:36 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -26,6 +26,7 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_index.h" #include "catalog/pg_namespace.h" @@ -34,7 +35,6 @@ #include "catalog/pg_type.h" #include "commands/command.h" #include "commands/trigger.h" -#include "commands/defrem.h" #include "executor/execdefs.h" #include "executor/executor.h" #include "miscadmin.h" @@ -415,8 +415,8 @@ AlterTableAddColumn(const char *relationName, rel = heap_openr(RelationRelationName, RowExclusiveLock); - reltup = SearchSysCache(RELNAME, - PointerGetDatum(relationName), + reltup = SearchSysCache(RELOID, + ObjectIdGetDatum(myrelid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) @@ -424,7 +424,7 @@ AlterTableAddColumn(const char *relationName, relationName); if (SearchSysCacheExists(ATTNAME, - ObjectIdGetDatum(reltup->t_data->t_oid), + ObjectIdGetDatum(myrelid), PointerGetDatum(colDef->colname), 0, 0)) elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"", @@ -463,7 +463,7 @@ AlterTableAddColumn(const char *relationName, attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple); - attribute->attrelid = reltup->t_data->t_oid; + attribute->attrelid = myrelid; namestrcpy(&(attribute->attname), colDef->colname); attribute->atttypid = typeTuple->t_data->t_oid; attribute->attstattarget = DEFAULT_ATTSTATTARGET; @@ -532,7 +532,7 @@ AlterTableAddColumn(const char *relationName, */ if (colDef->constraints != NIL) { - rel = heap_openr(relationName, AccessExclusiveLock); + rel = heap_open(myrelid, AccessExclusiveLock); AddRelationRawConstraints(rel, NIL, colDef->constraints); heap_close(rel, NoLock); } @@ -541,7 +541,7 @@ AlterTableAddColumn(const char *relationName, * Automatically create the secondary relation for TOAST if it * formerly had no such but now has toastable attributes. */ - AlterTableCreateToastTable(relationName, true); + AlterTableCreateToastTable(myrelid, true); } @@ -989,11 +989,7 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup) } else { - htup = SearchSysCache(RELOID, - ObjectIdGetDatum(index->indexrelid), - 0, 0, 0); - RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname)); - ReleaseSysCache(htup); + index_drop(index->indexrelid); } break; } @@ -1066,8 +1062,8 @@ AlterTableDropColumn(const char *relationName, * lock the pg_class tuple for update */ rel = heap_openr(RelationRelationName, RowExclusiveLock); - reltup = SearchSysCache(RELNAME, - PointerGetDatum(relationName), + reltup = SearchSysCache(RELOID, + ObjectIdGetDatum(myrelid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) elog(ERROR, "ALTER TABLE: relation \"%s\" not found", @@ -1092,7 +1088,7 @@ AlterTableDropColumn(const char *relationName, * Get the target pg_attribute tuple and make a modifiable copy */ tup = SearchSysCacheCopy(ATTNAME, - ObjectIdGetDatum(reltup->t_data->t_oid), + ObjectIdGetDatum(myrelid), PointerGetDatum(colName), 0, 0); if (!HeapTupleIsValid(tup)) @@ -1370,7 +1366,8 @@ AlterTableAddConstraint(char *relationName, * someone doesn't delete rows out from under us. */ - pkrel = heap_openr(fkconstraint->pktable->relname, AccessExclusiveLock); + pkrel = heap_openrv(fkconstraint->pktable, + AccessExclusiveLock); if (pkrel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "referenced table \"%s\" not a relation", fkconstraint->pktable->relname); @@ -1557,43 +1554,48 @@ AlterTableDropConstraint(const char *relationName, * ALTER TABLE OWNER */ void -AlterTableOwner(const char *relationName, const char *newOwnerName) +AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName) { - Oid relationOid; - Relation relation; - int32 newOwnerSysId; + Relation rel; + Oid myrelid; + int32 newOwnerSysId; /* check that we are the superuser */ if (!superuser()) elog(ERROR, "ALTER TABLE: permission denied"); /* lookup the OID of the target relation */ - relation = RelationNameGetRelation(relationName); - relationOid = relation->rd_id; - RelationClose(relation); + rel = relation_openrv(tgtrel, AccessExclusiveLock); + myrelid = RelationGetRelid(rel); + heap_close(rel, NoLock); /* close rel but keep lock! */ /* lookup the sysid of the new owner */ newOwnerSysId = get_usesysid(newOwnerName); /* do all the actual work */ - AlterTableOwnerId(relationOid, newOwnerSysId); + AlterTableOwnerId(myrelid, newOwnerSysId); } static void AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) { + Relation target_rel; Relation class_rel; HeapTuple tuple; Relation idescs[Num_pg_class_indices]; Form_pg_class tuple_class; + /* Get exclusive lock till end of transaction on the target table */ + target_rel = heap_open(relationOid, AccessExclusiveLock); + + /* Get its pg_class tuple, too */ + class_rel = heap_openr(RelationRelationName, RowExclusiveLock); + tuple = SearchSysCacheCopy(RELOID, ObjectIdGetDatum(relationOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "ALTER TABLE: object ID %hd not found", - relationOid); - + elog(ERROR, "ALTER TABLE: relation %u not found", relationOid); tuple_class = (Form_pg_class) GETSTRUCT(tuple); /* Can we change the ownership of this tuple? */ @@ -1603,7 +1605,6 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) * Okay, this is a valid tuple: change its ownership and * write to the heap. */ - class_rel = heap_openr(RelationRelationName, RowExclusiveLock); tuple_class->relowner = newOwnerSysId; simple_heap_update(class_rel, &tuple->t_self, tuple); @@ -1617,25 +1618,25 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) * indexes that belong to the table, as well as the table's toast * table (if it has one) */ - if (tuple_class->relkind == RELKIND_RELATION) + if (tuple_class->relkind == RELKIND_RELATION || + tuple_class->relkind == RELKIND_TOASTVALUE) { - /* Search for indexes belonging to this table */ - Relation target_rel; List *index_oid_list, *i; /* Find all the indexes belonging to this relation */ - target_rel = heap_open(relationOid, RowExclusiveLock); index_oid_list = RelationGetIndexList(target_rel); - heap_close(target_rel, RowExclusiveLock); /* For each index, recursively change its ownership */ - foreach (i, index_oid_list) + foreach(i, index_oid_list) { AlterTableOwnerId(lfirsti(i), newOwnerSysId); } freeList(index_oid_list); + } + if (tuple_class->relkind == RELKIND_RELATION) + { /* If it has a toast table, recurse to change its ownership */ if (tuple_class->reltoastrelid != InvalidOid) { @@ -1644,7 +1645,8 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId) } heap_freetuple(tuple); - heap_close(class_rel, NoLock); + heap_close(class_rel, RowExclusiveLock); + heap_close(target_rel, NoLock); } static void @@ -1669,10 +1671,9 @@ CheckTupleType(Form_pg_class tuple_class) * ALTER TABLE CREATE TOAST TABLE */ void -AlterTableCreateToastTable(const char *relationName, bool silent) +AlterTableCreateToastTable(Oid relOid, bool silent) { Relation rel; - Oid myrelid; HeapTuple reltup; HeapTupleData classtuple; TupleDesc tupdesc; @@ -1690,14 +1691,13 @@ AlterTableCreateToastTable(const char *relationName, bool silent) * Grab an exclusive lock on the target table, which we will NOT * release until end of transaction. */ - rel = heap_openr(relationName, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); + rel = heap_open(relOid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table", - relationName); + RelationGetRelationName(rel)); - if (!pg_class_ownercheck(myrelid, GetUserId())) + if (!pg_class_ownercheck(relOid, GetUserId())) elog(ERROR, "ALTER TABLE: permission denied"); /* @@ -1705,12 +1705,12 @@ AlterTableCreateToastTable(const char *relationName, bool silent) */ class_rel = heap_openr(RelationRelationName, RowExclusiveLock); - reltup = SearchSysCache(RELNAME, - PointerGetDatum(relationName), + reltup = SearchSysCache(RELOID, + ObjectIdGetDatum(relOid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) elog(ERROR, "ALTER TABLE: relation \"%s\" not found", - relationName); + RelationGetRelationName(rel)); classtuple.t_self = reltup->t_self; ReleaseSysCache(reltup); @@ -1739,7 +1739,7 @@ AlterTableCreateToastTable(const char *relationName, bool silent) } elog(ERROR, "ALTER TABLE: relation \"%s\" already has a toast table", - relationName); + RelationGetRelationName(rel)); } /* @@ -1756,14 +1756,14 @@ AlterTableCreateToastTable(const char *relationName, bool silent) } elog(ERROR, "ALTER TABLE: relation \"%s\" does not need a toast table", - relationName); + RelationGetRelationName(rel)); } /* * Create the toast table and its index */ - sprintf(toast_relname, "pg_toast_%u", myrelid); - sprintf(toast_idxname, "pg_toast_%u_idx", myrelid); + sprintf(toast_relname, "pg_toast_%u", relOid); + sprintf(toast_idxname, "pg_toast_%u_idx", relOid); /* this is pretty painful... need a tuple descriptor */ tupdesc = CreateTemplateTupleDesc(3); @@ -1795,7 +1795,9 @@ AlterTableCreateToastTable(const char *relationName, bool silent) * collision, and the toast rel will be destroyed when its master is, * so there's no need to handle the toast rel as temp. */ - toast_relid = heap_create_with_catalog(toast_relname, tupdesc, + toast_relid = heap_create_with_catalog(toast_relname, + RelationGetNamespace(rel), + tupdesc, RELKIND_TOASTVALUE, false, false, true); @@ -1825,9 +1827,9 @@ AlterTableCreateToastTable(const char *relationName, bool silent) classObjectId[0] = OID_BTREE_OPS_OID; classObjectId[1] = INT4_BTREE_OPS_OID; - toast_idxid = index_create(toast_relname, toast_idxname, indexInfo, + toast_idxid = index_create(toast_relid, toast_idxname, indexInfo, BTREE_AM_OID, classObjectId, - true, true); + false, true, true); /* * Update toast rel's pg_class entry to show that it has an index. The @@ -1927,21 +1929,15 @@ LockTableCommand(LockStmt *lockstmt) foreach(p, lockstmt->relations) { RangeVar *relation = lfirst(p); - char *relname = relation->relname; Oid reloid; - int aclresult; + int32 aclresult; Relation rel; /* * We don't want to open the relation until we've checked privilege. * So, manually get the relation OID. */ - reloid = GetSysCacheOid(RELNAME, - PointerGetDatum(relname), - 0, 0, 0); - if (!OidIsValid(reloid)) - elog(ERROR, "LOCK TABLE: relation \"%s\" does not exist", - relname); + reloid = RangeVarGetRelid(relation, false); if (lockstmt->mode == AccessShareLock) aclresult = pg_class_aclcheck(reloid, GetUserId(), @@ -1958,7 +1954,7 @@ LockTableCommand(LockStmt *lockstmt) /* 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); + relation->relname); relation_close(rel, NoLock); /* close rel, keep lock */ } diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 4ad4958162..cdc8ce35be 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.36 2002/03/21 23:27:20 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.37 2002/03/26 19:15:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #include "catalog/indexing.h" #include "catalog/pg_database.h" #include "catalog/pg_description.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_trigger.h" @@ -48,7 +49,8 @@ *------------------------------------------------------------------ */ -static void CommentRelation(int objtype, char *relation, char *comment); +static void CommentRelation(int objtype, char * schemaname, char *relation, + char *comment); static void CommentAttribute(char *relation, char *attrib, char *comment); static void CommentDatabase(char *database, char *comment); static void CommentRewrite(char *rule, char *comment); @@ -74,7 +76,7 @@ static void CommentTrigger(char *trigger, char *relation, char *comments); */ void -CommentObject(int objtype, char *objname, char *objproperty, +CommentObject(int objtype, char *schemaname, char *objname, char *objproperty, List *objlist, char *comment) { switch (objtype) @@ -83,7 +85,7 @@ CommentObject(int objtype, char *objname, char *objproperty, case SEQUENCE: case TABLE: case VIEW: - CommentRelation(objtype, objname, comment); + CommentRelation(objtype, schemaname, objname, comment); break; case COLUMN: CommentAttribute(objname, objproperty, comment); @@ -323,9 +325,16 @@ DeleteComments(Oid oid, Oid classoid) */ static void -CommentRelation(int reltype, char *relname, char *comment) +CommentRelation(int reltype, char *schemaname, char *relname, char *comment) { Relation relation; + RangeVar *tgtrel = makeNode(RangeVar); + + + tgtrel->relname = relname; + tgtrel->schemaname = schemaname; + /* FIXME SCHEMA: Can we add comments to temp relations? */ + tgtrel->istemp = false; /* * Open the relation. We do this mainly to acquire a lock that @@ -333,7 +342,7 @@ CommentRelation(int reltype, char *relname, char *comment) * did, they'd fail to remove the entry we are about to make in * pg_description.) */ - relation = relation_openr(relname, AccessShareLock); + relation = relation_openrv(tgtrel, AccessShareLock); /* Check object security */ if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) @@ -504,9 +513,7 @@ CommentRewrite(char *rule, char *comment) /* pg_rewrite doesn't have a hard-coded OID, so must look it up */ - classoid = GetSysCacheOid(RELNAME, - PointerGetDatum(RewriteRelationName), - 0, 0, 0); + classoid = get_relname_relid(RewriteRelationName, PG_CATALOG_NAMESPACE); Assert(OidIsValid(classoid)); /* Call CreateComments() to create/drop the comments */ @@ -604,9 +611,7 @@ CommentAggregate(char *aggregate, List *arguments, char *comment) /* pg_aggregate doesn't have a hard-coded OID, so must look it up */ - classoid = GetSysCacheOid(RELNAME, - PointerGetDatum(AggregateRelationName), - 0, 0, 0); + classoid = get_relname_relid(AggregateRelationName, PG_CATALOG_NAMESPACE); Assert(OidIsValid(classoid)); /* Call CreateComments() to create/drop the comments */ diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index 0f9bf525ef..2d68d5d6e7 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.91 2002/03/22 02:56:31 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.92 2002/03/26 19:15:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,9 +18,11 @@ #include "access/heapam.h" #include "catalog/catalog.h" #include "catalog/catname.h" -#include "catalog/indexing.h" #include "catalog/heap.h" +#include "catalog/indexing.h" +#include "catalog/namespace.h" #include "catalog/pg_inherits.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_type.h" #include "commands/creatinh.h" #include "miscadmin.h" @@ -54,6 +56,7 @@ Oid DefineRelation(CreateStmt *stmt, char relkind) { char *relname = palloc(NAMEDATALEN); + Oid namespaceId; List *schema = stmt->tableElts; int numberOfAttributes; Oid relationId; @@ -73,6 +76,12 @@ DefineRelation(CreateStmt *stmt, char relkind) */ StrNCpy(relname, (stmt->relation)->relname, NAMEDATALEN); + /* + * Look up the namespace in which we are supposed to create the + * relation. + */ + namespaceId = RangeVarGetCreationNamespace(stmt->relation); + /* * Merge domain attributes into the known columns before processing table * inheritance. Otherwise we risk adding double constraints to a @@ -147,7 +156,8 @@ DefineRelation(CreateStmt *stmt, char relkind) } } - relationId = heap_create_with_catalog(relname, descriptor, + relationId = heap_create_with_catalog(relname, namespaceId, + descriptor, relkind, stmt->hasoids || parentHasOids, stmt->relation->istemp, @@ -330,7 +340,7 @@ MergeDomainAttributes(List *schema) * Input arguments: * 'schema' is the column/attribute definition for the table. (It's a list * of ColumnDef's.) It is destructively changed. - * 'supers' is a list of names (as Value objects) of parent relations. + * 'supers' is a list of names (as RangeVar nodes) of parent relations. * 'istemp' is TRUE if we are creating a temp relation. * * Output arguments: @@ -417,24 +427,6 @@ MergeAttributes(List *schema, List *supers, bool istemp, } } - /* - * Reject duplicate names in the list of parents, too. - * - * XXX needs to be smarter about schema-qualified table names. - */ - foreach(entry, supers) - { - List *rest; - - foreach(rest, lnext(entry)) - { - if (strcmp(((RangeVar *) lfirst(entry))->relname, - ((RangeVar *) lfirst(rest))->relname) == 0) - elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated", - ((RangeVar *) lfirst(entry))->relname); - } - } - /* * Scan the parents left-to-right, and merge their attributes to form * a list of inherited attributes (inhSchema). Also check to see if @@ -443,30 +435,40 @@ MergeAttributes(List *schema, List *supers, bool istemp, child_attno = 0; foreach(entry, supers) { - char *name = ((RangeVar *) lfirst(entry))->relname; + RangeVar *parent = (RangeVar *) lfirst(entry); Relation relation; TupleDesc tupleDesc; TupleConstr *constr; AttrNumber *newattno; AttrNumber parent_attno; - relation = heap_openr(name, AccessShareLock); + relation = heap_openrv(parent, AccessShareLock); if (relation->rd_rel->relkind != RELKIND_RELATION) - elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", name); + elog(ERROR, "CREATE TABLE: inherited relation \"%s\" is not a table", + parent->relname); /* Permanent rels cannot inherit from temporary ones */ - if (!istemp && is_temp_rel_name(name)) - elog(ERROR, "CREATE TABLE: cannot inherit from temp relation \"%s\"", name); + if (!istemp && is_temp_rel_name(parent->relname)) + elog(ERROR, "CREATE TABLE: cannot inherit from temp relation \"%s\"", + parent->relname); /* * We should have an UNDER permission flag for this, but for now, * demand that creator of a child table own the parent. */ if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId())) - elog(ERROR, "you do not own table \"%s\"", name); + elog(ERROR, "you do not own table \"%s\"", + parent->relname); - parentOids = lappendi(parentOids, relation->rd_id); - setRelhassubclassInRelation(relation->rd_id, true); + /* + * Reject duplications in the list of parents. + */ + if (intMember(RelationGetRelid(relation), parentOids)) + elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated", + parent->relname); + + parentOids = lappendi(parentOids, RelationGetRelid(relation)); + setRelhassubclassInRelation(RelationGetRelid(relation), true); parentHasOids |= relation->rd_rel->relhasoids; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 677f130637..ae3476efb2 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.64 2002/03/20 19:43:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.65 2002/03/26 19:15:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,8 +18,8 @@ #include "access/heapam.h" #include "catalog/catalog.h" #include "catalog/catname.h" -#include "catalog/heap.h" #include "catalog/index.h" +#include "catalog/namespace.h" #include "catalog/pg_opclass.h" #include "commands/defrem.h" #include "miscadmin.h" @@ -33,6 +33,7 @@ #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/syscache.h" +#include "utils/temprel.h" #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL) @@ -61,7 +62,7 @@ static Oid GetDefaultOpClass(Oid attrType, Oid accessMethodId); * 'rangetable' is needed to interpret the predicate. */ void -DefineIndex(char *heapRelationName, +DefineIndex(RangeVar *heapRelation, char *indexRelationName, char *accessMethodName, List *attributeList, @@ -73,6 +74,7 @@ DefineIndex(char *heapRelationName, Oid *classObjectId; Oid accessMethodId; Oid relationId; + bool istemp = is_temp_rel_name(heapRelation->relname); Relation rel; HeapTuple tuple; Form_pg_am accessMethodForm; @@ -93,20 +95,20 @@ DefineIndex(char *heapRelationName, /* * Open heap relation, acquire a suitable lock on it, remember its OID */ - rel = heap_openr(heapRelationName, ShareLock); + rel = heap_openrv(heapRelation, ShareLock); /* Note: during bootstrap may see uncataloged relation */ if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_UNCATALOGED) elog(ERROR, "DefineIndex: relation \"%s\" is not a table", - heapRelationName); + heapRelation->relname); relationId = RelationGetRelid(rel); heap_close(rel, NoLock); if (!IsBootstrapProcessingMode() && - IsSystemRelationName(heapRelationName) && + IsSystemRelationName(heapRelation->relname) && !IndexesAreActive(relationId, false)) elog(ERROR, "Existing indexes are inactive. REINDEX first"); @@ -187,9 +189,9 @@ DefineIndex(char *heapRelationName, relationId, accessMethodName, accessMethodId); } - index_create(heapRelationName, indexRelationName, + index_create(relationId, indexRelationName, indexInfo, accessMethodId, classObjectId, - primary, allowSystemTableMods); + istemp, primary, allowSystemTableMods); /* * We update the relation's pg_class tuple even if it already has @@ -500,23 +502,25 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId) * ... */ void -RemoveIndex(char *name) +RemoveIndex(RangeVar *relation) { + Oid indOid; HeapTuple tuple; - tuple = SearchSysCache(RELNAME, - PointerGetDatum(name), + indOid = RangeVarGetRelid(relation, false); + tuple = SearchSysCache(RELOID, + ObjectIdGetDatum(indOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "index \"%s\" does not exist", name); + elog(ERROR, "index \"%s\" does not exist", relation->relname); if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX) elog(ERROR, "relation \"%s\" is of type \"%c\"", - name, ((Form_pg_class) GETSTRUCT(tuple))->relkind); - - index_drop(tuple->t_data->t_oid); + relation->relname, ((Form_pg_class) GETSTRUCT(tuple))->relkind); ReleaseSysCache(tuple); + + index_drop(indOid); } /* @@ -528,8 +532,9 @@ RemoveIndex(char *name) * ... */ void -ReindexIndex(const char *name, bool force /* currently unused */ ) +ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ ) { + Oid indOid; HeapTuple tuple; bool overwrite = false; @@ -541,22 +546,24 @@ ReindexIndex(const char *name, bool force /* currently unused */ ) if (IsTransactionBlock()) elog(ERROR, "REINDEX cannot run inside a BEGIN/END block"); - tuple = SearchSysCache(RELNAME, - PointerGetDatum(name), + indOid = RangeVarGetRelid(indexRelation, false); + tuple = SearchSysCache(RELOID, + ObjectIdGetDatum(indOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "index \"%s\" does not exist", name); + elog(ERROR, "index \"%s\" does not exist", indexRelation->relname); if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX) elog(ERROR, "relation \"%s\" is of type \"%c\"", - name, ((Form_pg_class) GETSTRUCT(tuple))->relkind); + indexRelation->relname, + ((Form_pg_class) GETSTRUCT(tuple))->relkind); + + ReleaseSysCache(tuple); if (IsIgnoringSystemIndexes()) overwrite = true; - if (!reindex_index(tuple->t_data->t_oid, force, overwrite)) - elog(WARNING, "index \"%s\" wasn't reindexed", name); - - ReleaseSysCache(tuple); + if (!reindex_index(indOid, force, overwrite)) + elog(WARNING, "index \"%s\" wasn't reindexed", indexRelation->relname); } /* @@ -568,8 +575,9 @@ ReindexIndex(const char *name, bool force /* currently unused */ ) * ... */ void -ReindexTable(const char *name, bool force) +ReindexTable(RangeVar *relation, bool force) { + Oid heapOid; HeapTuple tuple; /* @@ -580,20 +588,22 @@ ReindexTable(const char *name, bool force) if (IsTransactionBlock()) elog(ERROR, "REINDEX cannot run inside a BEGIN/END block"); - tuple = SearchSysCache(RELNAME, - PointerGetDatum(name), + heapOid = RangeVarGetRelid(relation, false); + tuple = SearchSysCache(RELOID, + ObjectIdGetDatum(heapOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "table \"%s\" does not exist", name); + elog(ERROR, "table \"%s\" does not exist", relation->relname); if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION) elog(ERROR, "relation \"%s\" is of type \"%c\"", - name, ((Form_pg_class) GETSTRUCT(tuple))->relkind); - - if (!reindex_relation(tuple->t_data->t_oid, force)) - elog(WARNING, "table \"%s\" wasn't reindexed", name); + relation->relname, + ((Form_pg_class) GETSTRUCT(tuple))->relkind); ReleaseSysCache(tuple); + + if (!reindex_relation(heapOid, force)) + elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname); } /* diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c index 0ce475303a..f050aa9f7f 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.64 2002/03/21 23:27:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.65 2002/03/26 19:15:43 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,6 +36,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/syscache.h" #include "utils/temprel.h" @@ -266,19 +267,20 @@ renameatt(char *relname, * renamerel - change the name of a relation */ void -renamerel(const char *oldrelname, const char *newrelname) +renamerel(const RangeVar *relation, const char *newrelname) { Relation targetrelation; Relation relrelation; /* for RELATION relation */ HeapTuple reltup; + Oid namespaceId; Oid reloid; char relkind; bool relhastriggers; Relation irelations[Num_pg_class_indices]; - if (!allowSystemTableMods && IsSystemRelationName(oldrelname)) + if (!allowSystemTableMods && IsSystemRelationName(relation->relname)) elog(ERROR, "renamerel: system relation \"%s\" may not be renamed", - oldrelname); + relation->relname); if (!allowSystemTableMods && IsSystemRelationName(newrelname)) elog(ERROR, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs", @@ -288,15 +290,16 @@ renamerel(const char *oldrelname, const char *newrelname) * Check for renaming a temp table, which only requires altering the * temp-table mapping, not the underlying table. */ - if (rename_temp_relation(oldrelname, newrelname)) + if (rename_temp_relation(relation->relname, newrelname)) return; /* all done... */ /* * Grab an exclusive lock on the target table or index, which we will * NOT release until end of transaction. */ - targetrelation = relation_openr(oldrelname, AccessExclusiveLock); + targetrelation = relation_openrv(relation, AccessExclusiveLock); + namespaceId = RelationGetNamespace(targetrelation); reloid = RelationGetRelid(targetrelation); relkind = targetrelation->rd_rel->relkind; relhastriggers = (targetrelation->rd_rel->reltriggers > 0); @@ -323,13 +326,14 @@ renamerel(const char *oldrelname, const char *newrelname) */ relrelation = heap_openr(RelationRelationName, RowExclusiveLock); - reltup = SearchSysCacheCopy(RELNAME, - PointerGetDatum(oldrelname), + reltup = SearchSysCacheCopy(RELOID, + PointerGetDatum(reloid), 0, 0, 0); if (!HeapTupleIsValid(reltup)) - elog(ERROR, "renamerel: relation \"%s\" does not exist", oldrelname); + elog(ERROR, "renamerel: relation \"%s\" does not exist", + relation->relname); - if (RelnameFindRelid(newrelname) != InvalidOid) + if (get_relname_relid(newrelname, namespaceId) != InvalidOid) elog(ERROR, "renamerel: relation \"%s\" exists", newrelname); /* @@ -352,7 +356,7 @@ renamerel(const char *oldrelname, const char *newrelname) * Also rename the associated type, if any. */ if (relkind != RELKIND_INDEX) - TypeRename(oldrelname, newrelname); + TypeRename(relation->relname, newrelname); /* * If it's a view, must also rename the associated ON SELECT rule. @@ -362,7 +366,7 @@ renamerel(const char *oldrelname, const char *newrelname) char *oldrulename, *newrulename; - oldrulename = MakeRetrieveViewRuleName(oldrelname); + oldrulename = MakeRetrieveViewRuleName(relation->relname); newrulename = MakeRetrieveViewRuleName(newrelname); RenameRewriteRule(oldrulename, newrulename); } @@ -374,11 +378,11 @@ renamerel(const char *oldrelname, const char *newrelname) { /* update tgargs where relname is primary key */ update_ri_trigger_args(reloid, - oldrelname, newrelname, + relation->relname, newrelname, false, true); /* update tgargs where relname is foreign key */ update_ri_trigger_args(reloid, - oldrelname, newrelname, + relation->relname, newrelname, true, true); } } diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 2fa17612e3..931ddeae7b 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.107 2002/03/21 23:27:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.108 2002/03/26 19:15:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -71,7 +71,7 @@ CreateTrigger(CreateTrigStmt *stmt) char *constrname = ""; Oid constrrelid = InvalidOid; - rel = heap_openr(stmt->relation->relname, AccessExclusiveLock); + rel = heap_openrv(stmt->relation, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "CreateTrigger: relation \"%s\" is not a table", @@ -106,7 +106,7 @@ CreateTrigger(CreateTrigStmt *stmt) */ Relation conrel; - conrel = heap_openr(stmt->constrrel->relname, NoLock); + conrel = heap_openrv(stmt->constrrel, NoLock); constrrelid = conrel->rd_id; heap_close(conrel, NoLock); } @@ -285,8 +285,8 @@ CreateTrigger(CreateTrigStmt *stmt) * rebuild relcache entries. */ pgrel = heap_openr(RelationRelationName, RowExclusiveLock); - tuple = SearchSysCacheCopy(RELNAME, - PointerGetDatum(stmt->relation->relname), + tuple = SearchSysCacheCopy(RELOID, + ObjectIdGetDatum(RelationGetRelid(rel)), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "CreateTrigger: relation %s not found in pg_class", @@ -323,7 +323,7 @@ DropTrigger(DropTrigStmt *stmt) int found = 0; int tgfound = 0; - rel = heap_openr(stmt->relation->relname, AccessExclusiveLock); + rel = heap_openrv(stmt->relation, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "DropTrigger: relation \"%s\" is not a table", @@ -380,8 +380,8 @@ DropTrigger(DropTrigStmt *stmt) * rebuild relcache entries. */ pgrel = heap_openr(RelationRelationName, RowExclusiveLock); - tuple = SearchSysCacheCopy(RELNAME, - PointerGetDatum(stmt->relation->relname), + tuple = SearchSysCacheCopy(RELOID, + ObjectIdGetDatum(RelationGetRelid(rel)), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "DropTrigger: relation %s not found in pg_class", @@ -452,7 +452,7 @@ RelationRemoveTriggers(Relation rel) pgrel = heap_openr(RelationRelationName, RowExclusiveLock); tup = SearchSysCacheCopy(RELOID, - RelationGetRelid(rel), + ObjectIdGetDatum(RelationGetRelid(rel)), 0, 0, 0); if (!HeapTupleIsValid(tup)) elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class", diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 3de55ad71c..98ee430897 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.93 2002/03/06 06:09:37 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.94 2002/03/26 19:15:48 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -919,12 +919,12 @@ DropUser(DropUserStmt *stmt) * check to see if there is an ACL on pg_shadow */ static void -CheckPgUserAclNotNull() +CheckPgUserAclNotNull(void) { HeapTuple htup; - htup = SearchSysCache(RELNAME, - PointerGetDatum(ShadowRelationName), + htup = SearchSysCache(RELOID, + ObjectIdGetDatum(RelOid_pg_shadow), 0, 0, 0); if (!HeapTupleIsValid(htup)) elog(ERROR, "CheckPgUserAclNotNull: \"%s\" not found", diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 8532da1597..ab41dd50c3 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -27,7 +27,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.154 2002/03/21 23:27:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.155 2002/03/26 19:15:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -35,6 +35,7 @@ #include "access/heapam.h" #include "catalog/heap.h" +#include "catalog/namespace.h" #include "commands/command.h" #include "commands/trigger.h" #include "executor/execdebug.h" @@ -696,10 +697,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) if (operation == CMD_SELECT) { - char *intoName; - Oid intoRelationId; - TupleDesc tupdesc; - if (!parseTree->isPortal) { /* @@ -707,10 +704,16 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) */ if (parseTree->into != NULL) { + char *intoName; + Oid namespaceId; + Oid intoRelationId; + TupleDesc tupdesc; + /* * create the "into" relation */ intoName = parseTree->into->relname; + namespaceId = RangeVarGetCreationNamespace(parseTree->into); /* * have to copy tupType to get rid of constraints @@ -719,6 +722,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) intoRelationId = heap_create_with_catalog(intoName, + namespaceId, tupdesc, RELKIND_RELATION, true, parseTree->into->istemp, @@ -738,7 +742,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) * with CommandCounterIncrement(), so that the TOAST table * will be visible for insertion. */ - AlterTableCreateToastTable(intoName, true); + AlterTableCreateToastTable(intoRelationId, true); intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index adefcd040c..270637d451 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.222 2002/03/22 02:56:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.223 2002/03/26 19:15:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,6 +17,7 @@ #include "catalog/catname.h" #include "catalog/heap.h" #include "catalog/index.h" +#include "catalog/namespace.h" #include "catalog/pg_index.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" @@ -118,7 +119,7 @@ static void transformConstraintAttrs(List *constraintList); static void transformColumnType(ParseState *pstate, ColumnDef *column); static void transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid); static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid); -static bool relationHasPrimaryKey(char *relname); +static bool relationHasPrimaryKey(Oid relationOid); static Oid transformFkeyGetColType(CreateStmtContext *cxt, char *colname); static void release_pstate_resources(ParseState *pstate); static FromExpr *makeFromExpr(List *fromlist, Node *quals); @@ -1048,7 +1049,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt) /* In ALTER TABLE case, a primary index might already exist */ if (cxt->pkey != NULL || (OidIsValid(cxt->relOid) && - relationHasPrimaryKey((cxt->relation)->relname))) + relationHasPrimaryKey(cxt->relOid))) elog(ERROR, "%s / PRIMARY KEY multiple primary keys" " for table '%s' are not allowed", cxt->stmtType, (cxt->relation)->relname); @@ -1115,10 +1116,10 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt) int count; Assert(IsA(inh, RangeVar)); - rel = heap_openr(inh->relname, AccessShareLock); + rel = heap_openrv(inh, AccessShareLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "inherited table \"%s\" is not a relation", - strVal(inh)); + inh->relname); for (count = 0; count < rel->rd_att->natts; count++) { Form_pg_attribute inhattr = rel->rd_att->attrs[count]; @@ -1724,7 +1725,7 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt, * beforehand. We don't need to hold a refcount on the relcache * entry, however. */ - heap_close(heap_openr(stmt->relation->relname, AccessExclusiveLock), + heap_close(heap_openrv(stmt->relation, AccessExclusiveLock), NoLock); /* @@ -2562,9 +2563,7 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, cxt.relation = stmt->relation; cxt.inhRelations = NIL; cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname); - cxt.relOid = GetSysCacheOid(RELNAME, - PointerGetDatum((stmt->relation)->relname), - 0, 0, 0); + cxt.relOid = RangeVarGetRelid(stmt->relation, false); cxt.hasoids = SearchSysCacheExists(ATTNUM, ObjectIdGetDatum(cxt.relOid), Int16GetDatum(ObjectIdAttributeNumber), @@ -2594,9 +2593,7 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt, cxt.relation = stmt->relation; cxt.inhRelations = NIL; cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname); - cxt.relOid = GetSysCacheOid(RELNAME, - PointerGetDatum((stmt->relation)->relname), - 0, 0, 0); + cxt.relOid = RangeVarGetRelid(stmt->relation, false); cxt.hasoids = SearchSysCacheExists(ATTNUM, ObjectIdGetDatum(cxt.relOid), Int16GetDatum(ObjectIdAttributeNumber), @@ -2844,7 +2841,7 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid) /* * Open the referenced table */ - pkrel = heap_openr(fkconstraint->pktable->relname, AccessShareLock); + pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock); if (pkrel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "Referenced relation \"%s\" is not a table", @@ -2937,7 +2934,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid) /* * Open the referenced table */ - pkrel = heap_openr(fkconstraint->pktable->relname, AccessShareLock); + pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock); if (pkrel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "Referenced relation \"%s\" is not a table", @@ -3002,14 +2999,14 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid) * See whether an existing relation has a primary key. */ static bool -relationHasPrimaryKey(char *relname) +relationHasPrimaryKey(Oid relationOid) { bool result = false; Relation rel; List *indexoidlist, *indexoidscan; - rel = heap_openr(relname, AccessShareLock); + rel = heap_open(relationOid, AccessShareLock); /* * Get the list of index OIDs for the table from the relcache, and @@ -3084,10 +3081,10 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname) int count; Assert(IsA(inh, RangeVar)); - rel = heap_openr(inh->relname, AccessShareLock); + rel = heap_openrv(inh, AccessShareLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "inherited table \"%s\" is not a relation", - strVal(inh)); + inh->relname); for (count = 0; count < rel->rd_att->natts; count++) { char *name = NameStr(rel->rd_att->attrs[count]->attname); diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index c2f578f4e6..6213e9edef 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.86 2002/03/22 02:56:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.87 2002/03/26 19:15:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -133,7 +133,7 @@ setTargetTable(ParseState *pstate, RangeVar *relation, * analyze.c will eventually do the corresponding heap_close(), but *not* * release the lock. */ - pstate->p_target_relation = heap_openr(relation->relname, RowExclusiveLock); + pstate->p_target_relation = heap_openrv(relation, RowExclusiveLock); /* * Now build an RTE. diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 3701539af5..f6a2dc208f 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.65 2002/03/22 02:56:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.66 2002/03/26 19:15:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -443,7 +443,7 @@ addRangeTableEntry(ParseState *pstate, * access level depending on whether we're doing SELECT FOR UPDATE. */ lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock; - rel = heap_openr(relation->relname, lockmode); + rel = heap_openrv(relation, lockmode); rte->relid = RelationGetRelid(rel); eref = alias ? (Alias *) copyObject(alias) : makeAlias(refname, NIL); diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index 7e9f0fcfbb..f20c9a0d98 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.65 2002/03/21 23:27:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.66 2002/03/26 19:16:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -138,7 +138,7 @@ DefineQueryRewrite(RuleStmt *stmt) * actions. But for now, let's just grab AccessExclusiveLock all the * time. */ - event_relation = heap_openr(event_obj->relname, AccessExclusiveLock); + event_relation = heap_openrv(event_obj, AccessExclusiveLock); ev_relid = RelationGetRelid(event_relation); /* diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index cfa00e4cb5..84f3325256 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.139 2002/03/24 04:31:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.140 2002/03/26 19:16:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "access/heapam.h" #include "catalog/catalog.h" +#include "catalog/namespace.h" #include "catalog/pg_shadow.h" #include "commands/async.h" #include "commands/cluster.h" @@ -94,9 +95,10 @@ DropErrorMsg(char *relname, char wrongkind, char rightkind) } static void -CheckDropPermissions(char *name, char rightkind) +CheckDropPermissions(RangeVar *rel, char rightkind) { struct kindstrings *rentry; + Oid relOid; HeapTuple tuple; Form_pg_class classform; @@ -105,49 +107,54 @@ CheckDropPermissions(char *name, char rightkind) break; Assert(rentry->kind != '\0'); - tuple = SearchSysCache(RELNAME, - PointerGetDatum(name), + relOid = RangeVarGetRelid(rel, true); + if (!OidIsValid(relOid)) + elog(ERROR, "%s \"%s\" does not exist", rentry->name, rel->relname); + tuple = SearchSysCache(RELOID, + ObjectIdGetDatum(relOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "%s \"%s\" does not exist", rentry->name, name); + elog(ERROR, "%s \"%s\" does not exist", rentry->name, rel->relname); classform = (Form_pg_class) GETSTRUCT(tuple); if (classform->relkind != rightkind) - DropErrorMsg(name, classform->relkind, rightkind); + DropErrorMsg(rel->relname, classform->relkind, rightkind); - if (!pg_class_ownercheck(tuple->t_data->t_oid, GetUserId())) + if (!pg_class_ownercheck(relOid, GetUserId())) elog(ERROR, "you do not own %s \"%s\"", - rentry->name, name); + rentry->name, rel->relname); - if (!allowSystemTableMods && IsSystemRelationName(name) && - !is_temp_relname(name)) + if (!allowSystemTableMods && IsSystemRelationName(rel->relname) && + !is_temp_relname(rel->relname)) elog(ERROR, "%s \"%s\" is a system %s", - rentry->name, name, rentry->name); + rentry->name, rel->relname, rentry->name); ReleaseSysCache(tuple); } static void -CheckOwnership(char *relname, bool noCatalogs) +CheckOwnership(RangeVar *rel, bool noCatalogs) { + Oid relOid; HeapTuple tuple; - tuple = SearchSysCache(RELNAME, - PointerGetDatum(relname), + relOid = RangeVarGetRelid(rel, false); + tuple = SearchSysCache(RELOID, + ObjectIdGetDatum(relOid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - elog(ERROR, "Relation \"%s\" does not exist", relname); + elog(ERROR, "Relation \"%s\" does not exist", rel->relname); - if (!pg_class_ownercheck(tuple->t_data->t_oid, GetUserId())) - elog(ERROR, "%s: %s", relname, + if (!pg_class_ownercheck(relOid, GetUserId())) + elog(ERROR, "%s: %s", rel->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]); if (noCatalogs) { - if (!allowSystemTableMods && IsSystemRelationName(relname)) + if (!allowSystemTableMods && IsSystemRelationName(rel->relname)) elog(ERROR, "relation \"%s\" is a system catalog", - relname); + rel->relname); } ReleaseSysCache(tuple); @@ -251,47 +258,52 @@ ProcessUtility(Node *parsetree, break; case T_CreateStmt: - DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION); + { + Oid relOid; - /* - * Let AlterTableCreateToastTable decide if this one needs a - * secondary relation too. - */ - CommandCounterIncrement(); - AlterTableCreateToastTable(((CreateStmt *) parsetree)->relation->relname, - true); + relOid = DefineRelation((CreateStmt *) parsetree, + RELKIND_RELATION); + + /* + * Let AlterTableCreateToastTable decide if this one needs a + * secondary relation too. + */ + CommandCounterIncrement(); + AlterTableCreateToastTable(relOid, true); + } break; case T_DropStmt: { DropStmt *stmt = (DropStmt *) parsetree; - List *args = stmt->objects; List *arg; - foreach(arg, args) + foreach(arg, stmt->objects) { - relname = ((RangeVar *) lfirst(arg))->relname; + RangeVar *rel = (RangeVar *) lfirst(arg); + + relname = rel->relname; switch (stmt->removeType) { case DROP_TABLE: - CheckDropPermissions(relname, RELKIND_RELATION); + CheckDropPermissions(rel, RELKIND_RELATION); RemoveRelation(relname); break; case DROP_SEQUENCE: - CheckDropPermissions(relname, RELKIND_SEQUENCE); + CheckDropPermissions(rel, RELKIND_SEQUENCE); RemoveRelation(relname); break; case DROP_VIEW: - CheckDropPermissions(relname, RELKIND_VIEW); + CheckDropPermissions(rel, RELKIND_VIEW); RemoveView(relname); break; case DROP_INDEX: - CheckDropPermissions(relname, RELKIND_INDEX); - RemoveIndex(relname); + CheckDropPermissions(rel, RELKIND_INDEX); + RemoveIndex(rel); break; case DROP_RULE: @@ -329,13 +341,12 @@ ProcessUtility(Node *parsetree, case T_CommentStmt: { - CommentStmt *statement; + CommentStmt *stmt; - statement = ((CommentStmt *) parsetree); + stmt = ((CommentStmt *) parsetree); - CommentObject(statement->objtype, statement->objname, - statement->objproperty, statement->objlist, - statement->comment); + CommentObject(stmt->objtype, stmt->objschema, stmt->objname, + stmt->objproperty, stmt->objlist, stmt->comment); } break; @@ -370,7 +381,7 @@ ProcessUtility(Node *parsetree, RenameStmt *stmt = (RenameStmt *) parsetree; relname = stmt->relation->relname; - CheckOwnership(relname, true); + CheckOwnership(stmt->relation, true); /* ---------------- * XXX using len == 3 to tell the difference @@ -389,7 +400,7 @@ ProcessUtility(Node *parsetree, * Note: we also rename the "type" tuple corresponding to * the relation. */ - renamerel(relname, /* old name */ + renamerel(stmt->relation, /* old relation */ stmt->newname); /* new name */ } else @@ -454,11 +465,11 @@ ProcessUtility(Node *parsetree, stmt->behavior); break; case 'E': /* CREATE TOAST TABLE */ - AlterTableCreateToastTable(stmt->relation->relname, + AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false), false); break; case 'U': /* ALTER OWNER */ - AlterTableOwner(stmt->relation->relname, + AlterTableOwner(stmt->relation, stmt->name); break; default: /* oops */ @@ -519,10 +530,9 @@ ProcessUtility(Node *parsetree, { IndexStmt *stmt = (IndexStmt *) parsetree; - relname = stmt->relation->relname; - CheckOwnership(relname, true); + CheckOwnership(stmt->relation, true); - DefineIndex(stmt->relation->relname, /* relation */ + DefineIndex(stmt->relation, /* relation */ stmt->idxname, /* index name */ stmt->accessMethod, /* am name */ stmt->indexParams, /* parameters */ @@ -638,10 +648,9 @@ ProcessUtility(Node *parsetree, { ClusterStmt *stmt = (ClusterStmt *) parsetree; - relname = stmt->relation->relname; - CheckOwnership(relname, true); + CheckOwnership(stmt->relation, true); - cluster(relname, stmt->indexname); + cluster(stmt->relation, stmt->indexname); } break; @@ -775,13 +784,12 @@ ProcessUtility(Node *parsetree, elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options", relname); } - CheckOwnership(relname, false); - ReindexIndex(relname, stmt->force); + CheckOwnership(stmt->relation, false); + ReindexIndex(stmt->relation, stmt->force); break; case TABLE: - relname = (char *) stmt->relation->relname; - CheckOwnership(relname, false); - ReindexTable(relname, stmt->force); + CheckOwnership(stmt->relation, false); + ReindexTable(stmt->relation, stmt->force); break; case DATABASE: relname = (char *) stmt->name; diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 0e73cb04b1..1db296f5e0 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.69 2002/03/21 23:27:24 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.70 2002/03/26 19:16:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "access/heapam.h" #include "catalog/catalog.h" +#include "catalog/namespace.h" #include "catalog/pg_shadow.h" #include "catalog/pg_type.h" #include "lib/stringinfo.h" @@ -723,7 +724,7 @@ makeAclString(const char *privileges, const char *grantee, char grant_or_revoke) /* * has_table_privilege_name_name * Check user privileges on a relation given - * name usename, name relname, and text priv name. + * name username, name relname, and text priv name. * * RETURNS * a boolean value @@ -995,7 +996,8 @@ has_table_privilege_cname_id(char *username, Oid reloid, text *priv_type_text) { int32 usesysid; - char *relname; + AclMode mode; + int32 result; /* * Lookup userid based on username @@ -1003,18 +1005,19 @@ has_table_privilege_cname_id(char *username, Oid reloid, usesysid = get_usesysid(username); /* - * Lookup relname based on rel oid + * Convert priv_type_text to an AclMode */ - relname = get_rel_name(reloid); - if (relname == NULL) - elog(ERROR, "has_table_privilege: invalid relation oid %u", - reloid); + mode = convert_priv_string(priv_type_text); /* - * Make use of has_table_privilege_id_cname. It accepts the arguments - * we now have. + * Finally, check for the privilege */ - return has_table_privilege_id_cname(usesysid, relname, priv_type_text); + result = pg_class_aclcheck(reloid, usesysid, mode); + + if (result == ACLCHECK_OK) + return true; + else + return false; } @@ -1039,9 +1042,7 @@ has_table_privilege_id_cname(int32 usesysid, char *relname, /* * Convert relname to rel OID. */ - reloid = GetSysCacheOid(RELNAME, - PointerGetDatum(relname), - 0, 0, 0); + reloid = RelnameGetRelid(relname); if (!OidIsValid(reloid)) elog(ERROR, "has_table_privilege: relation \"%s\" does not exist", relname); diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 6cb7b65fe3..202f447076 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.92 2002/03/06 20:49:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.93 2002/03/26 19:16:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -656,11 +656,11 @@ do { \ CatCache * InitCatCache(int id, - char *relname, - char *indname, + const char *relname, + const char *indname, int reloidattr, int nkeys, - int *key) + const int *key) { CatCache *cp; MemoryContext oldcxt; diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 1157780111..82be75ac79 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.65 2002/03/22 02:56:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.66 2002/03/26 19:16:09 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -634,6 +634,21 @@ func_iscachable(Oid funcid) /* ---------- RELATION CACHE ---------- */ +/* + * get_relname_relid + * Given name and namespace of a relation, look up the OID. + * + * Returns InvalidOid if there is no such relation. + */ +Oid +get_relname_relid(const char *relname, Oid relnamespace) +{ + return GetSysCacheOid(RELNAMENSP, + PointerGetDatum(relname), + ObjectIdGetDatum(relnamespace), + 0, 0); +} + #ifdef NOT_USED /* * get_relnatts @@ -664,10 +679,12 @@ get_relnatts(Oid relid) /* * get_rel_name - * * Returns the name of a given relation. * - * Note: returns a palloc'd copy of the string, or NULL if no such relation. + * Returns a palloc'd copy of the string, or NULL if no such relation. + * + * NOTE: since relation name is not unique, be wary of code that uses this + * for anything except preparing error messages. */ char * get_rel_name(Oid relid) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index d10569fd7c..4894cd2779 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.157 2002/03/19 02:18:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.158 2002/03/26 19:16:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,10 +16,9 @@ * INTERFACE ROUTINES * RelationCacheInitialize - initialize relcache * RelationCacheInitializePhase2 - finish initializing relcache - * RelationIdCacheGetRelation - get a reldesc from the cache (id) - * RelationNameCacheGetRelation - get a reldesc from the cache (name) * RelationIdGetRelation - get a reldesc by relation id - * RelationNameGetRelation - get a reldesc by relation name + * RelationSysNameGetRelation - get a reldesc by system rel name + * RelationIdCacheGetRelation - get a cached reldesc by relid * RelationClose - close an open relation * * NOTES @@ -39,13 +38,13 @@ #include "access/istrat.h" #include "catalog/catalog.h" #include "catalog/catname.h" -#include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_attribute.h" #include "catalog/pg_index.h" +#include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_proc.h" #include "catalog/pg_relcheck.h" @@ -70,7 +69,7 @@ #define RELCACHE_INIT_FILENAME "pg_internal.init" /* - * hardcoded tuple descriptors. see lib/backend/catalog/pg_attribute.h + * hardcoded tuple descriptors. see include/catalog/pg_attribute.h */ static FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class}; static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute}; @@ -80,11 +79,14 @@ static FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type}; /* * Hash tables that index the relation cache * - * Relations are looked up two ways, by name and by id, + * Relations are looked up two ways, by OID and by name, * thus there are two hash tables for referencing them. + * + * The OID index covers all relcache entries. The name index + * covers *only* system relations (only those in PG_CATALOG_NAMESPACE). */ -static HTAB *RelationNameCache; static HTAB *RelationIdCache; +static HTAB *RelationSysNameCache; /* * Bufmgr uses RelFileNode for lookup. Actually, I would like to do @@ -128,7 +130,7 @@ static List *initFileRelationIds = NIL; /* * RelationBuildDescInfo exists so code can be shared - * between RelationIdGetRelation() and RelationNameGetRelation() + * between RelationIdGetRelation() and RelationSysNameGetRelation() */ typedef struct RelationBuildDescInfo { @@ -138,22 +140,22 @@ typedef struct RelationBuildDescInfo union { Oid info_id; /* relation object id */ - char *info_name; /* relation name */ + char *info_name; /* system relation name */ } i; } RelationBuildDescInfo; -typedef struct relnamecacheent -{ - NameData relname; - Relation reldesc; -} RelNameCacheEnt; - typedef struct relidcacheent { Oid reloid; Relation reldesc; } RelIdCacheEnt; +typedef struct relnamecacheent +{ + NameData relname; + Relation reldesc; +} RelNameCacheEnt; + typedef struct relnodecacheent { RelFileNode relnode; @@ -165,24 +167,14 @@ typedef struct relnodecacheent */ #define RelationCacheInsert(RELATION) \ do { \ - RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \ - char *relname; RelNodeCacheEnt *nodentry; bool found; \ - relname = RelationGetPhysicalRelationName(RELATION); \ - namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ - relname, \ - HASH_ENTER, \ - &found); \ - if (namehentry == NULL) \ - elog(ERROR, "out of memory for relation descriptor cache"); \ - /* used to give notice if found -- now just keep quiet */ ; \ - namehentry->reldesc = RELATION; \ + RelIdCacheEnt *idhentry; RelNodeCacheEnt *nodentry; bool found; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ (void *) &(RELATION->rd_id), \ HASH_ENTER, \ &found); \ if (idhentry == NULL) \ elog(ERROR, "out of memory for relation descriptor cache"); \ - /* used to give notice if found -- now just keep quiet */ ; \ + /* used to give notice if found -- now just keep quiet */ \ idhentry->reldesc = RELATION; \ nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ (void *) &(RELATION->rd_node), \ @@ -190,19 +182,21 @@ do { \ &found); \ if (nodentry == NULL) \ elog(ERROR, "out of memory for relation descriptor cache"); \ - /* used to give notice if found -- now just keep quiet */ ; \ + /* used to give notice if found -- now just keep quiet */ \ nodentry->reldesc = RELATION; \ -} while(0) - -#define RelationNameCacheLookup(NAME, RELATION) \ -do { \ - RelNameCacheEnt *hentry; \ - hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ - (void *) (NAME), HASH_FIND,NULL); \ - if (hentry) \ - RELATION = hentry->reldesc; \ - else \ - RELATION = NULL; \ + if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \ + { \ + char *relname = RelationGetPhysicalRelationName(RELATION); \ + RelNameCacheEnt *namehentry; \ + namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \ + relname, \ + HASH_ENTER, \ + &found); \ + if (namehentry == NULL) \ + elog(ERROR, "out of memory for relation descriptor cache"); \ + /* used to give notice if found -- now just keep quiet */ \ + namehentry->reldesc = RELATION; \ + } \ } while(0) #define RelationIdCacheLookup(ID, RELATION) \ @@ -216,6 +210,17 @@ do { \ RELATION = NULL; \ } while(0) +#define RelationSysNameCacheLookup(NAME, RELATION) \ +do { \ + RelNameCacheEnt *hentry; \ + hentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \ + (void *) (NAME), HASH_FIND,NULL); \ + if (hentry) \ + RELATION = hentry->reldesc; \ + else \ + RELATION = NULL; \ +} while(0) + #define RelationNodeCacheLookup(NODE, RELATION) \ do { \ RelNodeCacheEnt *hentry; \ @@ -229,14 +234,7 @@ do { \ #define RelationCacheDelete(RELATION) \ do { \ - RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \ - char *relname; RelNodeCacheEnt *nodentry; \ - relname = RelationGetPhysicalRelationName(RELATION); \ - namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ - relname, \ - HASH_REMOVE, NULL); \ - if (namehentry == NULL) \ - elog(WARNING, "trying to delete a reldesc that does not exist."); \ + RelIdCacheEnt *idhentry; RelNodeCacheEnt *nodentry; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ (void *)&(RELATION->rd_id), \ HASH_REMOVE, NULL); \ @@ -247,6 +245,16 @@ do { \ HASH_REMOVE, NULL); \ if (nodentry == NULL) \ elog(WARNING, "trying to delete a reldesc that does not exist."); \ + if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \ + { \ + char *relname = RelationGetPhysicalRelationName(RELATION); \ + RelNameCacheEnt *namehentry; \ + namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \ + relname, \ + HASH_REMOVE, NULL); \ + if (namehentry == NULL) \ + elog(WARNING, "trying to delete a reldesc that does not exist."); \ + } \ } while(0) @@ -275,11 +283,11 @@ static void RelationClearRelation(Relation relation, bool rebuildIt); static void RelationReloadClassinfo(Relation relation); #endif /* ENABLE_REINDEX_NAILED_RELATIONS */ static void RelationFlushRelation(Relation relation); -static Relation RelationNameCacheGetRelation(const char *relationName); +static Relation RelationSysNameCacheGetRelation(const char *relationName); static bool load_relcache_init_file(void); static void write_relcache_init_file(void); -static void formrdesc(char *relationName, int natts, +static void formrdesc(const char *relationName, int natts, FormData_pg_attribute *att); static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo); @@ -303,12 +311,6 @@ static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid, StrategyNumber numSupport); -/* - * RelationIdGetRelation() and RelationNameGetRelation() - * support functions - */ - - /* * ScanPgRelation * @@ -326,7 +328,8 @@ ScanPgRelation(RelationBuildDescInfo buildinfo) Relation pg_class_desc; const char *indexRelname; SysScanDesc pg_class_scan; - ScanKeyData key; + ScanKeyData key[2]; + int nkeys; /* * form a scan key @@ -334,19 +337,25 @@ ScanPgRelation(RelationBuildDescInfo buildinfo) switch (buildinfo.infotype) { case INFO_RELID: - ScanKeyEntryInitialize(&key, 0, + ScanKeyEntryInitialize(&key[0], 0, ObjectIdAttributeNumber, F_OIDEQ, ObjectIdGetDatum(buildinfo.i.info_id)); + nkeys = 1; indexRelname = ClassOidIndex; break; case INFO_RELNAME: - ScanKeyEntryInitialize(&key, 0, + ScanKeyEntryInitialize(&key[0], 0, Anum_pg_class_relname, F_NAMEEQ, NameGetDatum(buildinfo.i.info_name)); - indexRelname = ClassNameIndex; + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_class_relnamespace, + F_OIDEQ, + ObjectIdGetDatum(PG_CATALOG_NAMESPACE)); + nkeys = 2; + indexRelname = ClassNameNspIndex; break; default: @@ -363,7 +372,7 @@ ScanPgRelation(RelationBuildDescInfo buildinfo) pg_class_scan = systable_beginscan(pg_class_desc, indexRelname, criticalRelcachesBuilt, SnapshotNow, - 1, &key); + nkeys, key); pg_class_tuple = systable_getnext(pg_class_scan); @@ -512,12 +521,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, (char *) attp, ATTRIBUTE_TUPLE_SIZE); - - - /* - * Update constraint/default info - */ - if (attp->attnotnull) + /* Update constraint/default info */ + if (attp->attnotnull) constr->has_not_null = true; if (attp->atthasdef) @@ -1333,7 +1338,7 @@ LookupOpclassInfo(Oid operatorClassOid, * NOTE: we assume we are already switched into CacheMemoryContext. */ static void -formrdesc(char *relationName, +formrdesc(const char *relationName, int natts, FormData_pg_attribute *att) { @@ -1374,7 +1379,8 @@ formrdesc(char *relationName, relation->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE); MemSet(relation->rd_rel, 0, CLASS_TUPLE_SIZE); - strcpy(RelationGetPhysicalRelationName(relation), relationName); + namestrcpy(&relation->rd_rel->relname, relationName); + relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE; /* * It's important to distinguish between shared and non-shared @@ -1488,12 +1494,12 @@ RelationIdCacheGetRelation(Oid relationId) } /* - * RelationNameCacheGetRelation + * RelationSysNameCacheGetRelation * - * As above, but lookup by name. + * As above, but lookup by name; only works for system catalogs. */ static Relation -RelationNameCacheGetRelation(const char *relationName) +RelationSysNameCacheGetRelation(const char *relationName) { Relation rd; NameData name; @@ -1503,7 +1509,7 @@ RelationNameCacheGetRelation(const char *relationName) * null-padded */ namestrcpy(&name, relationName); - RelationNameCacheLookup(NameStr(name), rd); + RelationSysNameCacheLookup(NameStr(name), rd); if (RelationIsValid(rd)) RelationIncrementReferenceCount(rd); @@ -1539,12 +1545,6 @@ RelationIdGetRelation(Oid relationId) Relation rd; RelationBuildDescInfo buildinfo; - /* - * increment access statistics - */ - IncrHeapAccessStat(local_RelationIdGetRelation); - IncrHeapAccessStat(global_RelationIdGetRelation); - /* * first try and get a reldesc from the cache */ @@ -1564,23 +1564,17 @@ RelationIdGetRelation(Oid relationId) } /* - * RelationNameGetRelation + * RelationSysNameGetRelation * - * As above, but lookup by name. + * As above, but lookup by name; only works for system catalogs. */ Relation -RelationNameGetRelation(const char *relationName) +RelationSysNameGetRelation(const char *relationName) { char *temprelname; Relation rd; RelationBuildDescInfo buildinfo; - /* - * increment access statistics - */ - IncrHeapAccessStat(local_RelationNameGetRelation); - IncrHeapAccessStat(global_RelationNameGetRelation); - /* * if caller is looking for a temp relation, substitute its real name; * we only index temp rels by their real names. @@ -1592,7 +1586,7 @@ RelationNameGetRelation(const char *relationName) /* * first try and get a reldesc from the cache */ - rd = RelationNameCacheGetRelation(relationName); + rd = RelationSysNameCacheGetRelation(relationName); if (RelationIsValid(rd)) return rd; @@ -1951,17 +1945,17 @@ void RelationCacheInvalidate(void) { HASH_SEQ_STATUS status; - RelNameCacheEnt *namehentry; + RelIdCacheEnt *idhentry; Relation relation; List *rebuildList = NIL; List *l; /* Phase 1 */ - hash_seq_init(&status, RelationNameCache); + hash_seq_init(&status, RelationIdCache); - while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL) + while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) { - relation = namehentry->reldesc; + relation = idhentry->reldesc; /* Ignore xact-local relations, since they are never SI targets */ if (relation->rd_myxactonly) @@ -2007,13 +2001,13 @@ void RelationCacheAbort(void) { HASH_SEQ_STATUS status; - RelNameCacheEnt *namehentry; + RelIdCacheEnt *idhentry; - hash_seq_init(&status, RelationNameCache); + hash_seq_init(&status, RelationIdCache); - while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL) + while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) { - Relation relation = namehentry->reldesc; + Relation relation = idhentry->reldesc; if (relation->rd_isnailed) RelationSetReferenceCount(relation, 1); @@ -2029,8 +2023,10 @@ RelationCacheAbort(void) */ Relation RelationBuildLocalRelation(const char *relname, + Oid relnamespace, TupleDesc tupDesc, Oid relid, Oid dbid, + RelFileNode rnode, bool nailit) { Relation rel; @@ -2086,7 +2082,8 @@ RelationBuildLocalRelation(const char *relname, rel->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE); MemSet((char *) rel->rd_rel, 0, CLASS_TUPLE_SIZE); - strcpy(RelationGetPhysicalRelationName(rel), relname); + namestrcpy(&rel->rd_rel->relname, relname); + rel->rd_rel->relnamespace = relnamespace; rel->rd_rel->relkind = RELKIND_UNCATALOGED; rel->rd_rel->relhasoids = true; @@ -2094,10 +2091,8 @@ RelationBuildLocalRelation(const char *relname, rel->rd_rel->reltype = InvalidOid; /* - * Insert relation OID and database/tablespace ID into the right - * places. XXX currently we assume physical tblspace/relnode are same - * as logical dbid/reloid. Probably should pass an extra pair of - * parameters. + * Insert relation physical and logical identifiers (OIDs) into the + * right places. */ rel->rd_rel->relisshared = (dbid == InvalidOid); @@ -2106,11 +2101,10 @@ RelationBuildLocalRelation(const char *relname, for (i = 0; i < natts; i++) rel->rd_att->attrs[i]->attrelid = relid; - RelationInitLockInfo(rel); /* see lmgr.c */ + rel->rd_node = rnode; + rel->rd_rel->relfilenode = rnode.relNode; - rel->rd_node.tblNode = dbid; - rel->rd_node.relNode = relid; - rel->rd_rel->relfilenode = relid; + RelationInitLockInfo(rel); /* see lmgr.c */ /* * Okay to insert into the relcache hash tables. @@ -2201,8 +2195,8 @@ RelationCacheInitialize(void) MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(NameData); ctl.entrysize = sizeof(RelNameCacheEnt); - RelationNameCache = hash_create("Relcache by name", INITRELCACHESIZE, - &ctl, HASH_ELEM); + RelationSysNameCache = hash_create("Relcache by name", INITRELCACHESIZE, + &ctl, HASH_ELEM); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RelIdCacheEnt); @@ -2252,7 +2246,7 @@ void RelationCacheInitializePhase2(void) { HASH_SEQ_STATUS status; - RelNameCacheEnt *namehentry; + RelIdCacheEnt *idhentry; if (IsBootstrapProcessingMode()) return; @@ -2290,7 +2284,7 @@ RelationCacheInitializePhase2(void) RelationSetReferenceCount(ird, 1); \ } while (0) - LOAD_CRIT_INDEX(ClassNameIndex); + LOAD_CRIT_INDEX(ClassNameNspIndex); LOAD_CRIT_INDEX(ClassOidIndex); LOAD_CRIT_INDEX(AttributeRelidNumIndex); LOAD_CRIT_INDEX(IndexRelidIndex); @@ -2311,11 +2305,11 @@ RelationCacheInitializePhase2(void) * Also, if any of the relcache entries have rules or triggers, * load that info the hard way since it isn't recorded in the cache file. */ - hash_seq_init(&status, RelationNameCache); + hash_seq_init(&status, RelationIdCache); - while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL) + while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) { - Relation relation = namehentry->reldesc; + Relation relation = idhentry->reldesc; /* * If it's a faked-up entry, read the real pg_class tuple. @@ -2399,8 +2393,8 @@ CreateDummyCaches(void) MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(NameData); ctl.entrysize = sizeof(RelNameCacheEnt); - RelationNameCache = hash_create("Relcache by name", INITRELCACHESIZE, - &ctl, HASH_ELEM); + RelationSysNameCache = hash_create("Relcache by name", INITRELCACHESIZE, + &ctl, HASH_ELEM); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RelIdCacheEnt); @@ -2427,14 +2421,14 @@ DestroyDummyCaches(void) oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - if (RelationNameCache) - hash_destroy(RelationNameCache); if (RelationIdCache) hash_destroy(RelationIdCache); + if (RelationSysNameCache) + hash_destroy(RelationSysNameCache); if (RelationNodeCache) hash_destroy(RelationNodeCache); - RelationNameCache = RelationIdCache = RelationNodeCache = NULL; + RelationIdCache = RelationSysNameCache = RelationNodeCache = NULL; MemoryContextSwitchTo(oldcxt); } @@ -3001,7 +2995,7 @@ write_relcache_init_file(void) char tempfilename[MAXPGPATH]; char finalfilename[MAXPGPATH]; HASH_SEQ_STATUS status; - RelNameCacheEnt *namehentry; + RelIdCacheEnt *idhentry; MemoryContext oldcxt; int i; @@ -3031,13 +3025,13 @@ write_relcache_init_file(void) /* * Write all the reldescs (in no particular order). */ - hash_seq_init(&status, RelationNameCache); + hash_seq_init(&status, RelationIdCache); initFileRelationIds = NIL; - while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL) + while ((idhentry = (RelIdCacheEnt *) hash_seq_search(&status)) != NULL) { - Relation rel = namehentry->reldesc; + Relation rel = idhentry->reldesc; Form_pg_class relform = rel->rd_rel; Size len; diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index c30bbe3090..57d4719b29 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.69 2002/03/22 21:34:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.70 2002/03/26 19:16:14 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -86,14 +86,14 @@ */ struct cachedesc { - char *name; /* name of the relation being cached */ - char *indname; /* name of index relation for this cache */ + const char *name; /* name of the relation being cached */ + const char *indname; /* name of index relation for this cache */ int reloidattr; /* attr number of rel OID reference, or 0 */ int nkeys; /* # of keys needed for cache lookup */ int key[4]; /* attribute numbers of key attrs */ }; -static struct cachedesc cacheinfo[] = { +static const struct cachedesc cacheinfo[] = { {AggregateRelationName, /* AGGNAME */ AggregateNameTypeIndex, 0, @@ -324,13 +324,13 @@ static struct cachedesc cacheinfo[] = { 0, 0 }}, - {RelationRelationName, /* RELNAME */ - ClassNameIndex, + {RelationRelationName, /* RELNAMENSP */ + ClassNameNspIndex, ObjectIdAttributeNumber, - 1, + 2, { Anum_pg_class_relname, - 0, + Anum_pg_class_relnamespace, 0, 0 }}, @@ -515,7 +515,7 @@ SearchSysCache(int cacheId, * when sought. This is a kluge ... temp table substitution should be * happening at a higher level ... */ - if (cacheId == RELNAME || cacheId == TYPENAME) + if (cacheId == RELNAMENSP || cacheId == TYPENAME) { char *nontemp_relname; diff --git a/src/include/access/genam.h b/src/include/access/genam.h index c8cb4c1058..fe0ab0fba1 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.32 2002/02/19 20:11:19 tgl Exp $ + * $Id: genam.h,v 1.33 2002/03/26 19:16:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,6 +17,7 @@ #include "access/itup.h" #include "access/relscan.h" #include "access/sdir.h" +#include "nodes/primnodes.h" /* Struct for statistics returned by bulk-delete operation */ @@ -50,7 +51,8 @@ typedef SysScanDescData *SysScanDesc; * generalized index_ interface routines (in indexam.c) */ extern Relation index_open(Oid relationId); -extern Relation index_openr(const char *relationName); +extern Relation index_openrv(const RangeVar *relation); +extern Relation index_openr(const char *sysRelationName); 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 9798b5f76a..c0909584f9 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.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: heapam.h,v 1.72 2001/11/05 17:46:31 momjian Exp $ + * $Id: heapam.h,v 1.73 2002/03/26 19:16:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include "access/relscan.h" #include "access/tupmacs.h" #include "access/xlogutils.h" +#include "nodes/primnodes.h" #include "storage/block.h" #include "storage/lmgr.h" #include "utils/rel.h" @@ -134,11 +135,13 @@ extern Datum heap_getsysattr(HeapTuple tup, int attnum, bool *isnull); /* heapam.c */ extern Relation relation_open(Oid relationId, LOCKMODE lockmode); -extern Relation relation_openr(const char *relationName, LOCKMODE lockmode); +extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation relation_openr(const char *sysRelationName, 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_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation heap_openr(const char *sysRelationName, LOCKMODE lockmode); #define heap_close(r,l) relation_close(r,l) diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index b80641bd96..a2e3a0df19 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.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: bootstrap.h,v 1.27 2002/03/02 21:39:34 momjian Exp $ + * $Id: bootstrap.h,v 1.28 2002/03/26 19:16:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ extern Form_pg_attribute attrtypes[MAXATTR]; extern int numattr; extern int BootstrapMain(int ac, char *av[]); -extern void index_register(char *heap, char *ind, IndexInfo *indexInfo); +extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo); extern void err_out(void); extern void InsertOneTuple(Oid objectid); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 086df0b2f8..0d9c280fb0 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catversion.h,v 1.110 2002/03/22 21:34:44 tgl Exp $ + * $Id: catversion.h,v 1.111 2002/03/26 19:16:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200203221 +#define CATALOG_VERSION_NO 200203251 #endif diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index b2bcfb71bd..eb34ee1404 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.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: heap.h,v 1.46 2002/03/20 19:44:52 tgl Exp $ + * $Id: heap.h,v 1.47 2002/03/26 19:16:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,6 +19,7 @@ #include "parser/parse_node.h" #include "utils/rel.h" + typedef struct RawColumnDefault { AttrNumber attnum; /* attribute to attach default to */ @@ -26,15 +27,15 @@ typedef struct RawColumnDefault * tree) */ } RawColumnDefault; -extern Oid RelnameFindRelid(const char *relname); - -extern Relation heap_create(char *relname, TupleDesc tupDesc, +extern Relation heap_create(char *relname, Oid relnamespace, + TupleDesc tupDesc, bool istemp, bool storage_create, bool allow_system_table_mods); extern void heap_storage_create(Relation rel); -extern Oid heap_create_with_catalog(char *relname, TupleDesc tupdesc, +extern Oid heap_create_with_catalog(char *relname, Oid relnamespace, + TupleDesc tupdesc, char relkind, bool relhasoids, bool istemp, bool allow_system_table_mods); diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index c31900a7cc..86f0824e84 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.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: index.h,v 1.45 2002/03/10 06:02:24 momjian Exp $ + * $Id: index.h,v 1.46 2002/03/26 19:16:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -29,11 +29,12 @@ typedef void (*IndexBuildCallback) (Relation index, void *state); -extern Oid index_create(char *heapRelationName, +extern Oid index_create(Oid heapRelationId, char *indexRelationName, IndexInfo *indexInfo, Oid accessMethodObjectId, Oid *classObjectId, + bool istemp, bool primary, bool allow_system_table_mods); diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index c6291f2a3a..222e0da51e 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: indexing.h,v 1.58 2002/03/22 21:34:44 tgl Exp $ + * $Id: indexing.h,v 1.59 2002/03/26 19:16:26 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -58,7 +58,7 @@ #define AttrDefaultIndex "pg_attrdef_adrelid_adnum_index" #define AttributeRelidNameIndex "pg_attribute_relid_attnam_index" #define AttributeRelidNumIndex "pg_attribute_relid_attnum_index" -#define ClassNameIndex "pg_class_relname_index" +#define ClassNameNspIndex "pg_class_relname_nsp_index" #define ClassOidIndex "pg_class_oid_index" #define DatabaseNameIndex "pg_database_datname_index" #define DatabaseOidIndex "pg_database_oid_index" @@ -156,7 +156,7 @@ DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(ad DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops)); -DECLARE_UNIQUE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops)); +DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index on pg_class using btree(relname name_ops, relnamespace oid_ops)); DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops)); DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops)); diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h new file mode 100644 index 0000000000..cbe65a07f5 --- /dev/null +++ b/src/include/catalog/namespace.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * namespace.h + * prototypes for functions in backend/catalog/namespace.c + * + * + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $Id: namespace.h,v 1.1 2002/03/26 19:16:28 tgl Exp $ + * + *------------------------------------------------------------------------- + */ +#ifndef NAMESPACE_H +#define NAMESPACE_H + +#include "nodes/primnodes.h" + + +extern Oid RangeVarGetRelid(const RangeVar *relation, bool failOK); + +extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation); + +extern Oid RelnameGetRelid(const char *relname); + +#endif /* NAMESPACE_H */ diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index df7cec8397..e8166960d2 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_attribute.h,v 1.85 2002/03/20 19:44:55 tgl Exp $ + * $Id: pg_attribute.h,v 1.86 2002/03/26 19:16:29 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -437,52 +437,54 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p f i f f)); */ #define Schema_pg_class \ { 1259, {"relname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \ -{ 1259, {"reltype"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"relowner"}, 23, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"relam"}, 26, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"relfilenode"}, 26, 0, 4, 5, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"relpages"}, 23, 0, 4, 6, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"reltuples"}, 700, 0, 4, 7, 0, -1, -1, false, 'p', false, 'i', false, false }, \ -{ 1259, {"reltoastrelid"}, 26, 0, 4, 8, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"reltoastidxid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \ -{ 1259, {"relhasindex"}, 16, 0, 1, 10, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relisshared"}, 16, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relkind"}, 18, 0, 1, 12, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relnatts"}, 21, 0, 2, 13, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1259, {"relchecks"}, 21, 0, 2, 14, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1259, {"reltriggers"}, 21, 0, 2, 15, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1259, {"relukeys"}, 21, 0, 2, 16, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1259, {"relfkeys"}, 21, 0, 2, 17, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1259, {"relrefs"}, 21, 0, 2, 18, 0, -1, -1, true, 'p', false, 's', false, false }, \ -{ 1259, {"relhasoids"}, 16, 0, 1, 19, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relhaspkey"}, 16, 0, 1, 20, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relhasrules"}, 16, 0, 1, 21, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relhassubclass"},16, 0, 1, 22, 0, -1, -1, true, 'p', false, 'c', false, false }, \ -{ 1259, {"relacl"}, 1034, 0, -1, 23, 0, -1, -1, false, 'x', false, 'i', false, false } +{ 1259, {"relnamespace"}, 26, 0, 4, 2, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"reltype"}, 26, 0, 4, 3, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"relowner"}, 23, 0, 4, 4, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"relam"}, 26, 0, 4, 5, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"relfilenode"}, 26, 0, 4, 6, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"relpages"}, 23, 0, 4, 7, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"reltuples"}, 700, 0, 4, 8, 0, -1, -1, false, 'p', false, 'i', false, false }, \ +{ 1259, {"reltoastrelid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"reltoastidxid"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \ +{ 1259, {"relhasindex"}, 16, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relisshared"}, 16, 0, 1, 12, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relkind"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relnatts"}, 21, 0, 2, 14, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1259, {"relchecks"}, 21, 0, 2, 15, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1259, {"reltriggers"}, 21, 0, 2, 16, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1259, {"relukeys"}, 21, 0, 2, 17, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1259, {"relfkeys"}, 21, 0, 2, 18, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1259, {"relrefs"}, 21, 0, 2, 19, 0, -1, -1, true, 'p', false, 's', false, false }, \ +{ 1259, {"relhasoids"}, 16, 0, 1, 20, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relhaspkey"}, 16, 0, 1, 21, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relhasrules"}, 16, 0, 1, 22, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relhassubclass"},16, 0, 1, 23, 0, -1, -1, true, 'p', false, 'c', false, false }, \ +{ 1259, {"relacl"}, 1034, 0, -1, 24, 0, -1, -1, false, 'x', false, 'i', false, false } DATA(insert ( 1259 relname 19 DEFAULT_ATTSTATTARGET NAMEDATALEN 1 0 -1 -1 f p f i f f)); -DATA(insert ( 1259 reltype 26 0 4 2 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 relowner 23 0 4 3 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 relam 26 0 4 4 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 relfilenode 26 0 4 5 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 relpages 23 0 4 6 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 reltuples 700 0 4 7 0 -1 -1 f p f i f f)); -DATA(insert ( 1259 reltoastrelid 26 0 4 8 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 reltoastidxid 26 0 4 9 0 -1 -1 t p f i f f)); -DATA(insert ( 1259 relhasindex 16 0 1 10 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relisshared 16 0 1 11 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relkind 18 0 1 12 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relnatts 21 0 2 13 0 -1 -1 t p f s f f)); -DATA(insert ( 1259 relchecks 21 0 2 14 0 -1 -1 t p f s f f)); -DATA(insert ( 1259 reltriggers 21 0 2 15 0 -1 -1 t p f s f f)); -DATA(insert ( 1259 relukeys 21 0 2 16 0 -1 -1 t p f s f f)); -DATA(insert ( 1259 relfkeys 21 0 2 17 0 -1 -1 t p f s f f)); -DATA(insert ( 1259 relrefs 21 0 2 18 0 -1 -1 t p f s f f)); -DATA(insert ( 1259 relhasoids 16 0 1 19 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relhaspkey 16 0 1 20 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relhasrules 16 0 1 21 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relhassubclass 16 0 1 22 0 -1 -1 t p f c f f)); -DATA(insert ( 1259 relacl 1034 0 -1 23 0 -1 -1 f x f i f f)); +DATA(insert ( 1259 relnamespace 26 0 4 2 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 reltype 26 0 4 3 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 relowner 23 0 4 4 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 relam 26 0 4 5 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 relfilenode 26 0 4 6 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 relpages 23 0 4 7 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 reltuples 700 0 4 8 0 -1 -1 f p f i f f)); +DATA(insert ( 1259 reltoastrelid 26 0 4 9 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 reltoastidxid 26 0 4 10 0 -1 -1 t p f i f f)); +DATA(insert ( 1259 relhasindex 16 0 1 11 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relisshared 16 0 1 12 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relkind 18 0 1 13 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relnatts 21 0 2 14 0 -1 -1 t p f s f f)); +DATA(insert ( 1259 relchecks 21 0 2 15 0 -1 -1 t p f s f f)); +DATA(insert ( 1259 reltriggers 21 0 2 16 0 -1 -1 t p f s f f)); +DATA(insert ( 1259 relukeys 21 0 2 17 0 -1 -1 t p f s f f)); +DATA(insert ( 1259 relfkeys 21 0 2 18 0 -1 -1 t p f s f f)); +DATA(insert ( 1259 relrefs 21 0 2 19 0 -1 -1 t p f s f f)); +DATA(insert ( 1259 relhasoids 16 0 1 20 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relhaspkey 16 0 1 21 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relhasrules 16 0 1 22 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relhassubclass 16 0 1 23 0 -1 -1 t p f c f f)); +DATA(insert ( 1259 relacl 1034 0 -1 24 0 -1 -1 f x f i f f)); DATA(insert ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i f f)); DATA(insert ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i f f)); DATA(insert ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f)); diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index ccfc0ceef9..60f524b2a6 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_class.h,v 1.62 2002/03/19 02:18:22 momjian Exp $ + * $Id: pg_class.h,v 1.63 2002/03/26 19:16:35 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -43,6 +43,7 @@ CATALOG(pg_class) BOOTSTRAP { NameData relname; /* class name */ + Oid relnamespace; /* OID of namespace containing this class */ Oid reltype; /* OID of associated entry in pg_type */ int4 relowner; /* class owner */ Oid relam; /* index access method; 0 if not an index */ @@ -99,31 +100,32 @@ typedef FormData_pg_class *Form_pg_class; * relacl field. This is a kluge. * ---------------- */ -#define Natts_pg_class_fixed 22 -#define Natts_pg_class 23 +#define Natts_pg_class_fixed 23 +#define Natts_pg_class 24 #define Anum_pg_class_relname 1 -#define Anum_pg_class_reltype 2 -#define Anum_pg_class_relowner 3 -#define Anum_pg_class_relam 4 -#define Anum_pg_class_relfilenode 5 -#define Anum_pg_class_relpages 6 -#define Anum_pg_class_reltuples 7 -#define Anum_pg_class_reltoastrelid 8 -#define Anum_pg_class_reltoastidxid 9 -#define Anum_pg_class_relhasindex 10 -#define Anum_pg_class_relisshared 11 -#define Anum_pg_class_relkind 12 -#define Anum_pg_class_relnatts 13 -#define Anum_pg_class_relchecks 14 -#define Anum_pg_class_reltriggers 15 -#define Anum_pg_class_relukeys 16 -#define Anum_pg_class_relfkeys 17 -#define Anum_pg_class_relrefs 18 -#define Anum_pg_class_relhasoids 19 -#define Anum_pg_class_relhaspkey 20 -#define Anum_pg_class_relhasrules 21 -#define Anum_pg_class_relhassubclass 22 -#define Anum_pg_class_relacl 23 +#define Anum_pg_class_relnamespace 2 +#define Anum_pg_class_reltype 3 +#define Anum_pg_class_relowner 4 +#define Anum_pg_class_relam 5 +#define Anum_pg_class_relfilenode 6 +#define Anum_pg_class_relpages 7 +#define Anum_pg_class_reltuples 8 +#define Anum_pg_class_reltoastrelid 9 +#define Anum_pg_class_reltoastidxid 10 +#define Anum_pg_class_relhasindex 11 +#define Anum_pg_class_relisshared 12 +#define Anum_pg_class_relkind 13 +#define Anum_pg_class_relnatts 14 +#define Anum_pg_class_relchecks 15 +#define Anum_pg_class_reltriggers 16 +#define Anum_pg_class_relukeys 17 +#define Anum_pg_class_relfkeys 18 +#define Anum_pg_class_relrefs 19 +#define Anum_pg_class_relhasoids 20 +#define Anum_pg_class_relhaspkey 21 +#define Anum_pg_class_relhasrules 22 +#define Anum_pg_class_relhassubclass 23 +#define Anum_pg_class_relacl 24 /* ---------------- * initial contents of pg_class @@ -132,21 +134,21 @@ typedef FormData_pg_class *Form_pg_class; * ---------------- */ -DATA(insert OID = 1247 ( pg_type 71 PGUID 0 1247 0 0 0 0 f f r 22 0 0 0 0 0 t f f f _null_ )); +DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 f f r 22 0 0 0 0 0 t f f f _null_ )); DESCR(""); -DATA(insert OID = 1249 ( pg_attribute 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ )); +DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 f f r 15 0 0 0 0 0 f f f f _null_ )); DESCR(""); -DATA(insert OID = 1255 ( pg_proc 81 PGUID 0 1255 0 0 0 0 f f r 18 0 0 0 0 0 t f f f _null_ )); +DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 f f r 18 0 0 0 0 0 t f f f _null_ )); DESCR(""); -DATA(insert OID = 1259 ( pg_class 83 PGUID 0 1259 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ )); +DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 f f r 24 0 0 0 0 0 t f f f _null_ )); DESCR(""); -DATA(insert OID = 1260 ( pg_shadow 86 PGUID 0 1260 0 0 0 0 f t r 9 0 0 0 0 0 f f f f _null_ )); +DATA(insert OID = 1260 ( pg_shadow PGNSP 86 PGUID 0 1260 0 0 0 0 f t r 9 0 0 0 0 0 f f f f _null_ )); DESCR(""); -DATA(insert OID = 1261 ( pg_group 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ )); +DATA(insert OID = 1261 ( pg_group PGNSP 87 PGUID 0 1261 0 0 0 0 f t r 3 0 0 0 0 0 f f f f _null_ )); DESCR(""); -DATA(insert OID = 1262 ( pg_database 88 PGUID 0 1262 0 0 0 0 f t r 10 0 0 0 0 0 t f f f _null_ )); +DATA(insert OID = 1262 ( pg_database PGNSP 88 PGUID 0 1262 0 0 0 0 f t r 10 0 0 0 0 0 t f f f _null_ )); DESCR(""); -DATA(insert OID = 376 ( pg_xactlock 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ )); +DATA(insert OID = 376 ( pg_xactlock PGNSP 0 PGUID 0 0 0 0 0 0 f t s 1 0 0 0 0 0 f f f f _null_ )); DESCR(""); #define RelOid_pg_type 1247 diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h index d076007084..c04cca24b4 100644 --- a/src/include/commands/cluster.h +++ b/src/include/commands/cluster.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Id: cluster.h,v 1.12 2001/11/05 17:46:33 momjian Exp $ + * $Id: cluster.h,v 1.13 2002/03/26 19:16:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,6 @@ /* * functions */ -extern void cluster(char *oldrelname, char *oldindexname); +extern void cluster(RangeVar *oldrelation, char *oldindexname); #endif /* CLUSTER_H */ diff --git a/src/include/commands/command.h b/src/include/commands/command.h index 36757b1f70..1601898b40 100644 --- a/src/include/commands/command.h +++ b/src/include/commands/command.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: command.h,v 1.34 2002/03/21 16:01:41 tgl Exp $ + * $Id: command.h,v 1.35 2002/03/26 19:16:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -62,10 +62,9 @@ extern void AlterTableDropConstraint(const char *relationName, bool inh, const char *constrName, int behavior); -extern void AlterTableCreateToastTable(const char *relationName, - bool silent); +extern void AlterTableCreateToastTable(Oid relOid, bool silent); -extern void AlterTableOwner(const char *relationName, const char *newOwnerName); +extern void AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName); /* * LOCK diff --git a/src/include/commands/comment.h b/src/include/commands/comment.h index 4d83372bdd..f1e9a760b0 100644 --- a/src/include/commands/comment.h +++ b/src/include/commands/comment.h @@ -25,8 +25,8 @@ *------------------------------------------------------------------ */ -extern void CommentObject(int objtype, char *objname, char *objproperty, - List *objlist, char *comment); +extern void CommentObject(int objtype, char * schemaname, char *objname, + char *objproperty, List *objlist, char *comment); extern void DeleteComments(Oid oid, Oid classoid); diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 78b34614d5..97924979c2 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.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: defrem.h,v 1.31 2002/03/19 02:18:23 momjian Exp $ + * $Id: defrem.h,v 1.32 2002/03/26 19:16:47 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,7 +19,7 @@ /* * prototypes in indexcmds.c */ -extern void DefineIndex(char *heapRelationName, +extern void DefineIndex(RangeVar *heapRelation, char *indexRelationName, char *accessMethodName, List *attributeList, @@ -27,9 +27,9 @@ extern void DefineIndex(char *heapRelationName, bool primary, Expr *predicate, List *rangetable); -extern void RemoveIndex(char *name); -extern void ReindexIndex(const char *indexRelationName, bool force); -extern void ReindexTable(const char *relationName, bool force); +extern void RemoveIndex(RangeVar *relation); +extern void ReindexIndex(RangeVar *indexRelation, bool force); +extern void ReindexTable(RangeVar *relation, bool force); extern void ReindexDatabase(const char *databaseName, bool force, bool all); /* diff --git a/src/include/commands/rename.h b/src/include/commands/rename.h index 76b5167a83..7bfd047916 100644 --- a/src/include/commands/rename.h +++ b/src/include/commands/rename.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: rename.h,v 1.13 2001/11/05 17:46:33 momjian Exp $ + * $Id: rename.h,v 1.14 2002/03/26 19:16:49 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,7 +19,7 @@ extern void renameatt(char *relname, char *newattname, int recurse); -extern void renamerel(const char *oldrelname, +extern void renamerel(const RangeVar *relation, const char *newrelname); #endif /* RENAME_H */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 883130f90a..e66e7b8b64 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.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: parsenodes.h,v 1.164 2002/03/22 02:56:36 tgl Exp $ + * $Id: parsenodes.h,v 1.165 2002/03/26 19:16:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,14 +17,6 @@ #include "nodes/primnodes.h" -typedef enum InhOption -{ - INH_NO, /* Do NOT scan child tables */ - INH_YES, /* DO scan child tables */ - INH_DEFAULT /* Use current SQL_inheritance option */ -} InhOption; - - /***************************************************************************** * Query Tree *****************************************************************************/ @@ -49,7 +41,7 @@ typedef struct Query * statement */ int resultRelation; /* target relation (index into rtable) */ - struct RangeVar *into; /* target relation or portal (cursor) + RangeVar *into; /* target relation or portal (cursor) * for portal just name is meaningful */ bool isPortal; /* is this a retrieve into portal? */ bool isBinary; /* binary portal? */ @@ -368,39 +360,6 @@ typedef struct SortGroupBy Node *node; /* Expression */ } SortGroupBy; -/* - * Alias - - * specifies an alias for a range variable; the alias might also - * specify renaming of columns within the table. - */ -typedef struct Alias -{ - NodeTag type; - char *aliasname; /* aliased rel name (never qualified) */ - List *colnames; /* optional list of column aliases */ - /* Note: colnames is a list of Value nodes (always strings) */ -} Alias; - -/* - * RangeVar - range variable, used in FROM clauses - * - * Also used to represent table names in utility statements; there, the alias - * field is not used, and inhOpt shows whether to apply the operation - * recursively to child tables. In some contexts it is also useful to carry - * a TEMP table indication here. - */ -typedef struct RangeVar -{ - NodeTag type; - char *catalogname; /* the catalog (database) name, or NULL */ - char *schemaname; /* the schema name, or NULL */ - char *relname; /* the relation/sequence name */ - InhOption inhOpt; /* expand rel by inheritance? - * recursively act on children? */ - bool istemp; /* is this a temp relation/sequence? */ - Alias *alias; /* table alias & optional column aliases */ -} RangeVar; - /* * RangeSubselect - subquery appearing in a FROM clause */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index f732305825..dc01689e30 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: primnodes.h,v 1.59 2002/03/21 16:01:48 tgl Exp $ + * $Id: primnodes.h,v 1.60 2002/03/26 19:16:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -93,6 +93,47 @@ typedef struct Fjoin } Fjoin; +/* + * Alias - + * specifies an alias for a range variable; the alias might also + * specify renaming of columns within the table. + */ +typedef struct Alias +{ + NodeTag type; + char *aliasname; /* aliased rel name (never qualified) */ + List *colnames; /* optional list of column aliases */ + /* Note: colnames is a list of Value nodes (always strings) */ +} Alias; + +typedef enum InhOption +{ + INH_NO, /* Do NOT scan child tables */ + INH_YES, /* DO scan child tables */ + INH_DEFAULT /* Use current SQL_inheritance option */ +} InhOption; + +/* + * RangeVar - range variable, used in FROM clauses + * + * Also used to represent table names in utility statements; there, the alias + * field is not used, and inhOpt shows whether to apply the operation + * recursively to child tables. In some contexts it is also useful to carry + * a TEMP table indication here. + */ +typedef struct RangeVar +{ + NodeTag type; + char *catalogname; /* the catalog (database) name, or NULL */ + char *schemaname; /* the schema name, or NULL */ + char *relname; /* the relation/sequence name */ + InhOption inhOpt; /* expand rel by inheritance? + * recursively act on children? */ + bool istemp; /* is this a temp relation/sequence? */ + Alias *alias; /* table alias & optional column aliases */ +} RangeVar; + + /* ---------------------------------------------------------------- * node types for executable expressions * ---------------------------------------------------------------- @@ -527,7 +568,7 @@ typedef struct JoinExpr Node *rarg; /* right subtree */ List *using; /* USING clause, if any (list of String) */ Node *quals; /* qualifiers on join, if any */ - struct Alias *alias; /* user-written alias clause, if any */ + Alias *alias; /* user-written alias clause, if any */ int rtindex; /* RT index assigned for join */ } JoinExpr; diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index 034c061e7d..8e98f41c01 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catcache.h,v 1.40 2002/03/06 20:49:46 momjian Exp $ + * $Id: catcache.h,v 1.41 2002/03/26 19:16:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,8 +33,8 @@ typedef struct catcache { int id; /* cache identifier --- see syscache.h */ struct catcache *cc_next; /* link to next catcache */ - char *cc_relname; /* name of relation the tuples come from */ - char *cc_indname; /* name of index matching cache keys */ + const char *cc_relname; /* name of relation the tuples come from */ + const char *cc_indname; /* name of index matching cache keys */ Oid cc_reloid; /* OID of relation the tuples come from */ bool cc_relisshared; /* is relation shared? */ TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */ @@ -107,9 +107,9 @@ extern MemoryContext CacheMemoryContext; extern void CreateCacheMemoryContext(void); extern void AtEOXact_CatCache(bool isCommit); -extern CatCache *InitCatCache(int id, char *relname, char *indname, +extern CatCache *InitCatCache(int id, const char *relname, const char *indname, int reloidattr, - int nkeys, int *key); + int nkeys, const int *key); extern void InitCatCachePhase2(CatCache *cache); extern HeapTuple SearchCatCache(CatCache *cache, diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 89dda37bf7..a18ed52107 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lsyscache.h,v 1.45 2002/03/22 02:56:37 tgl Exp $ + * $Id: lsyscache.h,v 1.46 2002/03/26 19:16:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,6 +39,7 @@ extern RegProcedure get_oprrest(Oid opno); extern RegProcedure get_oprjoin(Oid opno); extern Oid get_func_rettype(Oid funcid); extern bool func_iscachable(Oid funcid); +extern Oid get_relname_relid(const char *relname, Oid relnamespace); extern char *get_rel_name(Oid relid); extern Oid get_rel_type_id(Oid relid); extern int16 get_typlen(Oid typid); diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 49814386ca..16398b4c08 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.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: rel.h,v 1.56 2002/02/19 20:11:19 tgl Exp $ + * $Id: rel.h,v 1.57 2002/03/26 19:16:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -282,6 +282,14 @@ typedef Relation *RelationPtr; RelationGetPhysicalRelationName(relation) \ ) +/* + * RelationGetNamespace + * + * Returns the rel's namespace OID. + */ +#define RelationGetNamespace(relation) \ + ((relation)->rd_rel->relnamespace) + /* added to prevent circular dependency. bjm 1999/11/15 */ extern char *get_temp_rel_by_physicalname(const char *relname); diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index e5af1bee61..6e6164b87c 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.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: relcache.h,v 1.30 2002/02/19 20:11:20 tgl Exp $ + * $Id: relcache.h,v 1.31 2002/03/26 19:16:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,11 +20,11 @@ * relation lookup routines */ extern Relation RelationIdGetRelation(Oid relationId); -extern Relation RelationNameGetRelation(const char *relationName); -extern Relation RelationNodeCacheGetRelation(RelFileNode rnode); +extern Relation RelationSysNameGetRelation(const char *relationName); /* finds an existing cache entry, but won't make a new one */ extern Relation RelationIdCacheGetRelation(Oid relationId); +extern Relation RelationNodeCacheGetRelation(RelFileNode rnode); extern void RelationClose(Relation relation); @@ -46,8 +46,10 @@ extern void RelationCacheInitializePhase3(void); * Routine to create a relcache entry for an about-to-be-created relation */ extern Relation RelationBuildLocalRelation(const char *relname, + Oid relnamespace, TupleDesc tupDesc, Oid relid, Oid dbid, + RelFileNode rnode, bool nailit); /* diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 45de795c9c..49af969075 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: syscache.h,v 1.39 2002/03/22 21:34:44 tgl Exp $ + * $Id: syscache.h,v 1.40 2002/03/26 19:16:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -51,7 +51,7 @@ #define OPEROID 20 #define PROCNAME 21 #define PROCOID 22 -#define RELNAME 23 +#define RELNAMENSP 23 #define RELOID 24 #define RULENAME 25 #define SHADOWNAME 26 diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 0e9ca176ac..44c5146eb6 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.38 2002/03/06 06:10:45 momjian Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.39 2002/03/26 19:17:02 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -46,6 +46,7 @@ #include "access/heapam.h" #include "catalog/catname.h" +#include "catalog/namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "catalog/pg_class.h" @@ -941,6 +942,7 @@ plpgsql_parse_dblwordtype(char *string) char *word2; PLpgSQL_nsitem *nse; bool old_nsstate; + Oid classOid; HeapTuple classtup; Form_pg_class classStruct; HeapTuple attrtup; @@ -998,8 +1000,14 @@ plpgsql_parse_dblwordtype(char *string) /* * First word could also be a table name */ - classtup = SearchSysCache(RELNAME, - PointerGetDatum(word1), + classOid = RelnameGetRelid(word1); + if (!OidIsValid(classOid)) + { + pfree(word1); + return T_ERROR; + } + classtup = SearchSysCache(RELOID, + ObjectIdGetDatum(classOid), 0, 0, 0); if (!HeapTupleIsValid(classtup)) { @@ -1024,7 +1032,7 @@ plpgsql_parse_dblwordtype(char *string) * Fetch the named table field and it's type */ attrtup = SearchSysCache(ATTNAME, - ObjectIdGetDatum(classtup->t_data->t_oid), + ObjectIdGetDatum(classOid), PointerGetDatum(word2), 0, 0); if (!HeapTupleIsValid(attrtup)) @@ -1049,7 +1057,7 @@ plpgsql_parse_dblwordtype(char *string) typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type)); typ->typname = strdup(NameStr(typeStruct->typname)); - typ->typoid = typetup->t_data->t_oid; + typ->typoid = attrStruct->atttypid; perm_fmgr_info(typeStruct->typinput, &(typ->typinput)); typ->typelem = typeStruct->typelem; typ->typbyval = typeStruct->typbyval; @@ -1074,6 +1082,7 @@ plpgsql_parse_dblwordtype(char *string) int plpgsql_parse_wordrowtype(char *string) { + Oid classOid; HeapTuple classtup; Form_pg_class classStruct; HeapTuple typetup; @@ -1093,8 +1102,11 @@ plpgsql_parse_wordrowtype(char *string) cp = strchr(word1, '%'); *cp = '\0'; - classtup = SearchSysCache(RELNAME, - PointerGetDatum(word1), + classOid = RelnameGetRelid(word1); + if (!OidIsValid(classOid)) + elog(ERROR, "%s: no such class", word1); + classtup = SearchSysCache(RELOID, + ObjectIdGetDatum(classOid), 0, 0, 0); if (!HeapTupleIsValid(classtup)) elog(ERROR, "%s: no such class", word1); @@ -1105,15 +1117,6 @@ plpgsql_parse_wordrowtype(char *string) classStruct->relkind != RELKIND_VIEW) elog(ERROR, "%s isn't a table", word1); - /* - * Fetch the table's pg_type tuple too - */ - typetup = SearchSysCache(TYPENAME, - PointerGetDatum(word1), - 0, 0, 0); - if (!HeapTupleIsValid(typetup)) - elog(ERROR, "cache lookup for %s in pg_type failed", word1); - /* * Create a row datum entry and all the required variables that it * will point to. @@ -1123,19 +1126,17 @@ plpgsql_parse_wordrowtype(char *string) row->dtype = PLPGSQL_DTYPE_ROW; row->nfields = classStruct->relnatts; - row->rowtypeclass = typetup->t_data->t_oid; + row->rowtypeclass = classStruct->reltype; row->fieldnames = malloc(sizeof(char *) * row->nfields); row->varnos = malloc(sizeof(int) * row->nfields); - ReleaseSysCache(typetup); - for (i = 0; i < row->nfields; i++) { /* * Get the attribute and it's type */ attrtup = SearchSysCache(ATTNUM, - ObjectIdGetDatum(classtup->t_data->t_oid), + ObjectIdGetDatum(classOid), Int16GetDatum(i + 1), 0, 0); if (!HeapTupleIsValid(attrtup)) @@ -1172,7 +1173,7 @@ plpgsql_parse_wordrowtype(char *string) strcat(var->refname, cp); var->datatype = malloc(sizeof(PLpgSQL_type)); var->datatype->typname = strdup(NameStr(typeStruct->typname)); - var->datatype->typoid = typetup->t_data->t_oid; + var->datatype->typoid = attrStruct->atttypid; perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput)); var->datatype->typelem = typeStruct->typelem; var->datatype->typbyval = typeStruct->typbyval;