mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
pg_class has a relnamespace column. You can create and access tables
in schemas other than the system namespace; however, there's no search path yet, and not all operations work yet on tables outside the system namespace.
This commit is contained in:
parent
da631e931f
commit
1dbf8aa7a8
@ -1,6 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
Documentation of the system catalogs, directed toward PostgreSQL developers
|
Documentation of the system catalogs, directed toward PostgreSQL developers
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.37 2002/03/22 21:34:43 tgl Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.38 2002/03/26 19:15:10 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="catalogs">
|
<chapter id="catalogs">
|
||||||
@ -568,6 +568,15 @@
|
|||||||
<entry>Name of the table, index, view, etc.</entry>
|
<entry>Name of the table, index, view, etc.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>relnamespace</entry>
|
||||||
|
<entry><type>oid</type></entry>
|
||||||
|
<entry>pg_namespace.oid</entry>
|
||||||
|
<entry>
|
||||||
|
The OID of the namespace that contains this relation
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>reltype</entry>
|
<entry>reltype</entry>
|
||||||
<entry><type>oid</type></entry>
|
<entry><type>oid</type></entry>
|
||||||
|
@ -8,15 +8,17 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
* relation_open - open any relation by relation OID
|
* 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
|
* relation_close - close any relation
|
||||||
* heap_open - open a heap relation by relation OID
|
* 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_close - (now just a macro for relation_close)
|
||||||
* heap_beginscan - begin relation scan
|
* heap_beginscan - begin relation scan
|
||||||
* heap_rescan - restart a relation scan
|
* heap_rescan - restart a relation scan
|
||||||
@ -44,6 +46,7 @@
|
|||||||
#include "access/valid.h"
|
#include "access/valid.h"
|
||||||
#include "access/xlogutils.h"
|
#include "access/xlogutils.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/inval.h"
|
#include "utils/inval.h"
|
||||||
#include "utils/relcache.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
|
||||||
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;
|
Relation r;
|
||||||
|
|
||||||
@ -500,25 +546,15 @@ relation_openr(const char *relationName, LOCKMODE lockmode)
|
|||||||
IncrHeapAccessStat(global_openr);
|
IncrHeapAccessStat(global_openr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for shared-cache-inval messages before trying to open the
|
* We assume we should not need to worry about the rel's OID changing,
|
||||||
* relation. This is needed to cover the case where the name
|
* hence no need for AcceptInvalidationMessages here.
|
||||||
* identifies a rel that has been dropped and recreated since the
|
|
||||||
* start of our transaction: if we don't flush the old relcache entry
|
|
||||||
* then we'll latch onto that entry and suffer an error when we do
|
|
||||||
* LockRelation. Note that relation_open does not need to do this,
|
|
||||||
* since a relation's OID never changes.
|
|
||||||
*
|
|
||||||
* We skip this if asked for NoLock, on the assumption that the caller
|
|
||||||
* has already ensured some appropriate lock is held.
|
|
||||||
*/
|
*/
|
||||||
if (lockmode != NoLock)
|
|
||||||
AcceptInvalidationMessages();
|
|
||||||
|
|
||||||
/* The relcache does all the real work... */
|
/* The relcache does all the real work... */
|
||||||
r = RelationNameGetRelation(relationName);
|
r = RelationSysNameGetRelation(sysRelationName);
|
||||||
|
|
||||||
if (!RelationIsValid(r))
|
if (!RelationIsValid(r))
|
||||||
elog(ERROR, "Relation \"%s\" does not exist", relationName);
|
elog(ERROR, "Relation \"%s\" does not exist", sysRelationName);
|
||||||
|
|
||||||
if (lockmode != NoLock)
|
if (lockmode != NoLock)
|
||||||
LockRelation(r, lockmode);
|
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
|
Relation
|
||||||
heap_openr(const char *relationName, LOCKMODE lockmode)
|
heap_openrv(const RangeVar *relation, LOCKMODE lockmode)
|
||||||
{
|
{
|
||||||
Relation r;
|
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)
|
if (r->rd_rel->relkind == RELKIND_INDEX)
|
||||||
elog(ERROR, "%s is an index relation",
|
elog(ERROR, "%s is an index relation",
|
||||||
|
@ -8,11 +8,12 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
* index_open - open an index relation by relation OID
|
* 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_close - close an index relation
|
||||||
* index_beginscan - start a scan of an index
|
* index_beginscan - start a scan of an index
|
||||||
* index_rescan - restart 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
|
Relation
|
||||||
index_openr(const char *relationName)
|
index_openrv(const RangeVar *relation)
|
||||||
{
|
{
|
||||||
Relation r;
|
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)
|
if (r->rd_rel->relkind != RELKIND_INDEX)
|
||||||
elog(ERROR, "%s is not an index relation",
|
elog(ERROR, "%s is not an index relation",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_am.h"
|
||||||
#include "catalog/pg_attribute.h"
|
#include "catalog/pg_attribute.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
|
#include "catalog/pg_namespace.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/nodes.h"
|
#include "nodes/nodes.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
@ -179,7 +181,9 @@ Boot_CreateStmt:
|
|||||||
}
|
}
|
||||||
|
|
||||||
tupdesc = CreateTupleDesc(numattr, attrtypes);
|
tupdesc = CreateTupleDesc(numattr, attrtypes);
|
||||||
reldesc = heap_create(LexIDStr($4), tupdesc,
|
reldesc = heap_create(LexIDStr($4),
|
||||||
|
PG_CATALOG_NAMESPACE,
|
||||||
|
tupdesc,
|
||||||
false, true, true);
|
false, true, true);
|
||||||
reldesc->rd_rel->relhasoids = ! ($3);
|
reldesc->rd_rel->relhasoids = ! ($3);
|
||||||
elog(DEBUG3, "bootstrap relation created");
|
elog(DEBUG3, "bootstrap relation created");
|
||||||
@ -191,6 +195,7 @@ Boot_CreateStmt:
|
|||||||
|
|
||||||
tupdesc = CreateTupleDesc(numattr,attrtypes);
|
tupdesc = CreateTupleDesc(numattr,attrtypes);
|
||||||
id = heap_create_with_catalog(LexIDStr($4),
|
id = heap_create_with_catalog(LexIDStr($4),
|
||||||
|
PG_CATALOG_NAMESPACE,
|
||||||
tupdesc,
|
tupdesc,
|
||||||
RELKIND_RELATION,
|
RELKIND_RELATION,
|
||||||
! ($3),
|
! ($3),
|
||||||
@ -232,7 +237,7 @@ Boot_DeclareIndexStmt:
|
|||||||
{
|
{
|
||||||
do_start();
|
do_start();
|
||||||
|
|
||||||
DefineIndex(LexIDStr($5),
|
DefineIndex(makeRangeVar(NULL, LexIDStr($5)),
|
||||||
LexIDStr($3),
|
LexIDStr($3),
|
||||||
LexIDStr($7),
|
LexIDStr($7),
|
||||||
$9, false, false, NULL, NIL);
|
$9, false, false, NULL, NIL);
|
||||||
@ -245,7 +250,7 @@ Boot_DeclareUniqueIndexStmt:
|
|||||||
{
|
{
|
||||||
do_start();
|
do_start();
|
||||||
|
|
||||||
DefineIndex(LexIDStr($6),
|
DefineIndex(makeRangeVar(NULL, LexIDStr($6)),
|
||||||
LexIDStr($4),
|
LexIDStr($4),
|
||||||
LexIDStr($8),
|
LexIDStr($8),
|
||||||
$10, true, false, NULL, NIL);
|
$10, true, false, NULL, NIL);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
typedef struct _IndexList
|
||||||
{
|
{
|
||||||
char *il_heap;
|
Oid il_heap;
|
||||||
char *il_ind;
|
Oid il_ind;
|
||||||
IndexInfo *il_info;
|
IndexInfo *il_info;
|
||||||
struct _IndexList *il_next;
|
struct _IndexList *il_next;
|
||||||
} IndexList;
|
} IndexList;
|
||||||
@ -1080,8 +1080,8 @@ AddStr(char *str, int strlength, int mderef)
|
|||||||
* are present in the index.
|
* are present in the index.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
index_register(char *heap,
|
index_register(Oid heap,
|
||||||
char *ind,
|
Oid ind,
|
||||||
IndexInfo *indexInfo)
|
IndexInfo *indexInfo)
|
||||||
{
|
{
|
||||||
IndexList *newind;
|
IndexList *newind;
|
||||||
@ -1103,8 +1103,8 @@ index_register(char *heap,
|
|||||||
oldcxt = MemoryContextSwitchTo(nogc);
|
oldcxt = MemoryContextSwitchTo(nogc);
|
||||||
|
|
||||||
newind = (IndexList *) palloc(sizeof(IndexList));
|
newind = (IndexList *) palloc(sizeof(IndexList));
|
||||||
newind->il_heap = pstrdup(heap);
|
newind->il_heap = heap;
|
||||||
newind->il_ind = pstrdup(ind);
|
newind->il_ind = ind;
|
||||||
newind->il_info = (IndexInfo *) palloc(sizeof(IndexInfo));
|
newind->il_info = (IndexInfo *) palloc(sizeof(IndexInfo));
|
||||||
|
|
||||||
memcpy(newind->il_info, indexInfo, sizeof(IndexInfo));
|
memcpy(newind->il_info, indexInfo, sizeof(IndexInfo));
|
||||||
@ -1126,8 +1126,8 @@ build_indices()
|
|||||||
Relation heap;
|
Relation heap;
|
||||||
Relation ind;
|
Relation ind;
|
||||||
|
|
||||||
heap = heap_openr(ILHead->il_heap, NoLock);
|
heap = heap_open(ILHead->il_heap, NoLock);
|
||||||
ind = index_openr(ILHead->il_ind);
|
ind = index_open(ILHead->il_ind);
|
||||||
index_build(heap, ind, ILHead->il_info);
|
index_build(heap, ind, ILHead->il_info);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for backend/catalog
|
# 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 = ../../..
|
top_builddir = ../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
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_aggregate.o pg_largeobject.o pg_namespace.o \
|
||||||
pg_operator.o pg_proc.o pg_type.o
|
pg_operator.o pg_proc.o pg_type.o
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_aggregate.h"
|
#include "catalog/pg_aggregate.h"
|
||||||
#include "catalog/pg_group.h"
|
#include "catalog/pg_group.h"
|
||||||
#include "catalog/pg_language.h"
|
#include "catalog/pg_language.h"
|
||||||
@ -200,7 +201,8 @@ ExecuteGrantStmt_Table(GrantStmt *stmt)
|
|||||||
|
|
||||||
foreach(i, stmt->objects)
|
foreach(i, stmt->objects)
|
||||||
{
|
{
|
||||||
char *relname = ((RangeVar *) lfirst(i))->relname;
|
RangeVar *relvar = (RangeVar *) lfirst(i);
|
||||||
|
Oid relOid;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_class pg_class_tuple;
|
Form_pg_class pg_class_tuple;
|
||||||
@ -216,27 +218,27 @@ ExecuteGrantStmt_Table(GrantStmt *stmt)
|
|||||||
|
|
||||||
/* open pg_class */
|
/* open pg_class */
|
||||||
relation = heap_openr(RelationRelationName, RowExclusiveLock);
|
relation = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCache(RELNAME,
|
relOid = RangeVarGetRelid(relvar, false);
|
||||||
PointerGetDatum(relname),
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(relOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
elog(ERROR, "relation \"%s\" not found",
|
elog(ERROR, "relation %u not found", relOid);
|
||||||
relname);
|
|
||||||
pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
|
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",
|
elog(ERROR, "%s: permission denied",
|
||||||
relname);
|
relvar->relname);
|
||||||
|
|
||||||
if (pg_class_tuple->relkind == RELKIND_INDEX)
|
if (pg_class_tuple->relkind == RELKIND_INDEX)
|
||||||
elog(ERROR, "\"%s\" is an index",
|
elog(ERROR, "\"%s\" is an index",
|
||||||
relname);
|
relvar->relname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's no ACL, create a default using the pg_class.relowner
|
* If there's no ACL, create a default using the pg_class.relowner
|
||||||
* field.
|
* field.
|
||||||
*/
|
*/
|
||||||
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
|
aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (isNull)
|
if (isNull)
|
||||||
old_acl = acldefault(pg_class_tuple->relowner);
|
old_acl = acldefault(pg_class_tuple->relowner);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# 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
|
# NOTES
|
||||||
# non-essential whitespace is removed from the generated file.
|
# non-essential whitespace is removed from the generated file.
|
||||||
@ -136,6 +136,14 @@ for dir in $INCLUDE_DIRS; do
|
|||||||
fi
|
fi
|
||||||
done
|
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
|
# Get FirstGenBKIObjectId from access/transam.h
|
||||||
for dir in $INCLUDE_DIRS; do
|
for dir in $INCLUDE_DIRS; do
|
||||||
if [ -f "$dir/access/transam.h" ]; then
|
if [ -f "$dir/access/transam.h" ]; then
|
||||||
@ -185,6 +193,7 @@ sed -e "s/;[ ]*$//g" \
|
|||||||
-e "s/(TransactionId/(xid/g" \
|
-e "s/(TransactionId/(xid/g" \
|
||||||
-e "s/PGUID/1/g" \
|
-e "s/PGUID/1/g" \
|
||||||
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
|
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
|
||||||
|
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
|
||||||
-e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \
|
-e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \
|
||||||
-e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \
|
-e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \
|
||||||
-e "s/INDEX_MAX_KEYS\*4/$INDEXMAXKEYS4/g" \
|
-e "s/INDEX_MAX_KEYS\*4/$INDEXMAXKEYS4/g" \
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
@ -38,7 +38,7 @@
|
|||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_attrdef.h"
|
#include "catalog/pg_attrdef.h"
|
||||||
#include "catalog/pg_inherits.h"
|
#include "catalog/pg_inherits.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_relcheck.h"
|
#include "catalog/pg_relcheck.h"
|
||||||
#include "catalog/pg_statistic.h"
|
#include "catalog/pg_statistic.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
@ -50,11 +50,9 @@
|
|||||||
#include "optimizer/planmain.h"
|
#include "optimizer/planmain.h"
|
||||||
#include "optimizer/prep.h"
|
#include "optimizer/prep.h"
|
||||||
#include "optimizer/var.h"
|
#include "optimizer/var.h"
|
||||||
#include "parser/parse_coerce.h"
|
|
||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
#include "parser/parse_target.h"
|
#include "parser/parse_target.h"
|
||||||
#include "parser/parse_type.h"
|
|
||||||
#include "rewrite/rewriteRemove.h"
|
#include "rewrite/rewriteRemove.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
@ -214,6 +212,7 @@ SystemAttributeByName(const char *attname, bool relhasoids)
|
|||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
heap_create(char *relname,
|
heap_create(char *relname,
|
||||||
|
Oid relnamespace,
|
||||||
TupleDesc tupDesc,
|
TupleDesc tupDesc,
|
||||||
bool istemp,
|
bool istemp,
|
||||||
bool storage_create,
|
bool storage_create,
|
||||||
@ -222,7 +221,8 @@ heap_create(char *relname,
|
|||||||
static unsigned int uniqueId = 0;
|
static unsigned int uniqueId = 0;
|
||||||
|
|
||||||
Oid relid;
|
Oid relid;
|
||||||
Oid tblNode = MyDatabaseId;
|
Oid dbid = MyDatabaseId;
|
||||||
|
RelFileNode rnode;
|
||||||
bool nailme = false;
|
bool nailme = false;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
|
|
||||||
@ -238,9 +238,11 @@ heap_create(char *relname,
|
|||||||
/*
|
/*
|
||||||
* Real ugly stuff to assign the proper relid in the relation
|
* Real ugly stuff to assign the proper relid in the relation
|
||||||
* descriptor follows. Note that only "bootstrapped" relations whose
|
* 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)
|
if (strcmp(TypeRelationName, relname) == 0)
|
||||||
{
|
{
|
||||||
@ -264,24 +266,24 @@ heap_create(char *relname,
|
|||||||
}
|
}
|
||||||
else if (strcmp(ShadowRelationName, relname) == 0)
|
else if (strcmp(ShadowRelationName, relname) == 0)
|
||||||
{
|
{
|
||||||
tblNode = InvalidOid;
|
dbid = InvalidOid;
|
||||||
relid = RelOid_pg_shadow;
|
relid = RelOid_pg_shadow;
|
||||||
}
|
}
|
||||||
else if (strcmp(GroupRelationName, relname) == 0)
|
else if (strcmp(GroupRelationName, relname) == 0)
|
||||||
{
|
{
|
||||||
tblNode = InvalidOid;
|
dbid = InvalidOid;
|
||||||
relid = RelOid_pg_group;
|
relid = RelOid_pg_group;
|
||||||
}
|
}
|
||||||
else if (strcmp(DatabaseRelationName, relname) == 0)
|
else if (strcmp(DatabaseRelationName, relname) == 0)
|
||||||
{
|
{
|
||||||
tblNode = InvalidOid;
|
dbid = InvalidOid;
|
||||||
relid = RelOid_pg_database;
|
relid = RelOid_pg_database;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
relid = newoid();
|
relid = newoid();
|
||||||
if (IsSharedSystemRelationName(relname))
|
if (IsSharedSystemRelationName(relname))
|
||||||
tblNode = InvalidOid;
|
dbid = InvalidOid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -297,11 +299,21 @@ heap_create(char *relname,
|
|||||||
PG_TEMP_REL_PREFIX, (int) MyProcPid, uniqueId++);
|
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.
|
* build the relcache entry.
|
||||||
*/
|
*/
|
||||||
rel = RelationBuildLocalRelation(relname, tupDesc,
|
rel = RelationBuildLocalRelation(relname,
|
||||||
relid, tblNode,
|
relnamespace,
|
||||||
|
tupDesc,
|
||||||
|
relid, dbid,
|
||||||
|
rnode,
|
||||||
nailme);
|
nailme);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -329,7 +341,7 @@ heap_storage_create(Relation rel)
|
|||||||
* 1) CheckAttributeNames() is used to make certain the tuple
|
* 1) CheckAttributeNames() is used to make certain the tuple
|
||||||
* descriptor contains a valid set of attribute names
|
* 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
|
* performs a scan to ensure that no relation with the
|
||||||
* same name already exists.
|
* 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
|
* AddNewAttributeTuples
|
||||||
*
|
*
|
||||||
@ -719,6 +664,7 @@ AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
|
|||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
heap_create_with_catalog(char *relname,
|
heap_create_with_catalog(char *relname,
|
||||||
|
Oid relnamespace,
|
||||||
TupleDesc tupdesc,
|
TupleDesc tupdesc,
|
||||||
char relkind,
|
char relkind,
|
||||||
bool relhasoids,
|
bool relhasoids,
|
||||||
@ -742,7 +688,7 @@ heap_create_with_catalog(char *relname,
|
|||||||
CheckAttributeNames(tupdesc, relhasoids);
|
CheckAttributeNames(tupdesc, relhasoids);
|
||||||
|
|
||||||
/* temp tables can mask non-temp tables */
|
/* temp tables can mask non-temp tables */
|
||||||
if ((!istemp && RelnameFindRelid(relname)) ||
|
if ((!istemp && get_relname_relid(relname, relnamespace)) ||
|
||||||
(istemp && is_temp_rel_name(relname)))
|
(istemp && is_temp_rel_name(relname)))
|
||||||
elog(ERROR, "Relation '%s' already exists", 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
|
* heap_storage_create() does all the "real" work of creating the disk
|
||||||
* file for the relation.
|
* file for the relation.
|
||||||
*/
|
*/
|
||||||
new_rel_desc = heap_create(relname, tupdesc, istemp, false,
|
new_rel_desc = heap_create(relname, relnamespace, tupdesc,
|
||||||
allow_system_table_mods);
|
istemp, false, allow_system_table_mods);
|
||||||
|
|
||||||
/* Fetch the relation OID assigned by heap_create */
|
/* Fetch the relation OID assigned by heap_create */
|
||||||
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
|
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
|
||||||
@ -916,10 +862,8 @@ RelationRemoveInheritance(Relation relation)
|
|||||||
heap_close(catalogRelation, RowExclusiveLock);
|
heap_close(catalogRelation, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/*
|
||||||
* RelationRemoveIndexes
|
* RelationRemoveIndexes
|
||||||
*
|
|
||||||
* --------------------------------
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
RelationRemoveIndexes(Relation relation)
|
RelationRemoveIndexes(Relation relation)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
@ -48,10 +48,12 @@
|
|||||||
#include "utils/catcache.h"
|
#include "utils/catcache.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/inval.h"
|
#include "utils/inval.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/temprel.h"
|
#include "utils/temprel.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* macros used in guessing how many tuples are on a page.
|
* macros used in guessing how many tuples are on a page.
|
||||||
*/
|
*/
|
||||||
@ -61,15 +63,13 @@
|
|||||||
((natts) * AVG_ATTR_SIZE + MAXALIGN(sizeof(HeapTupleHeaderData))))
|
((natts) * AVG_ATTR_SIZE + MAXALIGN(sizeof(HeapTupleHeaderData))))
|
||||||
|
|
||||||
/* non-export function prototypes */
|
/* non-export function prototypes */
|
||||||
static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName,
|
|
||||||
bool istemp);
|
|
||||||
static TupleDesc BuildFuncTupleDesc(Oid funcOid,
|
static TupleDesc BuildFuncTupleDesc(Oid funcOid,
|
||||||
Oid *classObjectId);
|
Oid *classObjectId);
|
||||||
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
|
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
|
||||||
int numatts, AttrNumber *attNums,
|
int numatts, AttrNumber *attNums,
|
||||||
Oid *classObjectId);
|
Oid *classObjectId);
|
||||||
static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);
|
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,
|
static void InitializeAttributeOids(Relation indexRelation,
|
||||||
int numatts, Oid indexoid);
|
int numatts, Oid indexoid);
|
||||||
static void AppendAttributeTuples(Relation indexRelation, int numatts);
|
static void AppendAttributeTuples(Relation indexRelation, int numatts);
|
||||||
@ -99,33 +99,6 @@ IsReindexProcessing(void)
|
|||||||
return reindexing;
|
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
|
static TupleDesc
|
||||||
BuildFuncTupleDesc(Oid funcOid,
|
BuildFuncTupleDesc(Oid funcOid,
|
||||||
Oid *classObjectId)
|
Oid *classObjectId)
|
||||||
@ -356,12 +329,11 @@ ConstructIndexReldesc(Relation indexRelation, Oid amoid)
|
|||||||
* UpdateRelationRelation
|
* UpdateRelationRelation
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
static Oid
|
static void
|
||||||
UpdateRelationRelation(Relation indexRelation, char *temp_relname)
|
UpdateRelationRelation(Relation indexRelation, char *temp_relname)
|
||||||
{
|
{
|
||||||
Relation pg_class;
|
Relation pg_class;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Oid tupleOid;
|
|
||||||
Relation idescs[Num_pg_class_indices];
|
Relation idescs[Num_pg_class_indices];
|
||||||
|
|
||||||
pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
|
pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
@ -372,9 +344,8 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
|
|||||||
(void *) indexRelation->rd_rel);
|
(void *) indexRelation->rd_rel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the new tuple must have the same oid as the relcache entry for the
|
* the new tuple must have the oid already chosen for the index.
|
||||||
* index. sure would be embarrassing to do this sort of thing in
|
* sure would be embarrassing to do this sort of thing in polite company.
|
||||||
* polite company.
|
|
||||||
*/
|
*/
|
||||||
tuple->t_data->t_oid = RelationGetRelid(indexRelation);
|
tuple->t_data->t_oid = RelationGetRelid(indexRelation);
|
||||||
heap_insert(pg_class, tuple);
|
heap_insert(pg_class, tuple);
|
||||||
@ -396,11 +367,8 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
|
|||||||
CatalogCloseIndices(Num_pg_class_indices, idescs);
|
CatalogCloseIndices(Num_pg_class_indices, idescs);
|
||||||
}
|
}
|
||||||
|
|
||||||
tupleOid = tuple->t_data->t_oid;
|
|
||||||
heap_freetuple(tuple);
|
heap_freetuple(tuple);
|
||||||
heap_close(pg_class, RowExclusiveLock);
|
heap_close(pg_class, RowExclusiveLock);
|
||||||
|
|
||||||
return tupleOid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
@ -586,24 +554,31 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
index_create(char *heapRelationName,
|
index_create(Oid heapRelationId,
|
||||||
char *indexRelationName,
|
char *indexRelationName,
|
||||||
IndexInfo *indexInfo,
|
IndexInfo *indexInfo,
|
||||||
Oid accessMethodObjectId,
|
Oid accessMethodObjectId,
|
||||||
Oid *classObjectId,
|
Oid *classObjectId,
|
||||||
|
bool istemp,
|
||||||
bool primary,
|
bool primary,
|
||||||
bool allow_system_table_mods)
|
bool allow_system_table_mods)
|
||||||
{
|
{
|
||||||
Relation heapRelation;
|
Relation heapRelation;
|
||||||
Relation indexRelation;
|
Relation indexRelation;
|
||||||
TupleDesc indexTupDesc;
|
TupleDesc indexTupDesc;
|
||||||
Oid heapoid;
|
Oid namespaceId;
|
||||||
Oid indexoid;
|
Oid indexoid;
|
||||||
bool istemp = is_temp_rel_name(heapRelationName);
|
|
||||||
char *temp_relname = NULL;
|
char *temp_relname = NULL;
|
||||||
|
|
||||||
SetReindexProcessing(false);
|
SetReindexProcessing(false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only SELECT ... FOR UPDATE are allowed while doing this
|
||||||
|
*/
|
||||||
|
heapRelation = heap_open(heapRelationId, ShareLock);
|
||||||
|
|
||||||
|
namespaceId = RelationGetNamespace(heapRelation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check parameters
|
* check parameters
|
||||||
*/
|
*/
|
||||||
@ -611,19 +586,15 @@ index_create(char *heapRelationName,
|
|||||||
indexInfo->ii_NumKeyAttrs < 1)
|
indexInfo->ii_NumKeyAttrs < 1)
|
||||||
elog(ERROR, "must index at least one column");
|
elog(ERROR, "must index at least one column");
|
||||||
|
|
||||||
if (heapRelationName && !allow_system_table_mods &&
|
if (!allow_system_table_mods &&
|
||||||
IsSystemRelationName(heapRelationName) && IsNormalProcessingMode())
|
IsSystemRelationName(RelationGetRelationName(heapRelation)) &&
|
||||||
|
IsNormalProcessingMode())
|
||||||
elog(ERROR, "User-defined indexes on system catalogs are not supported");
|
elog(ERROR, "User-defined indexes on system catalogs are not supported");
|
||||||
|
|
||||||
/*
|
if ((!istemp && get_relname_relid(indexRelationName, namespaceId)) ||
|
||||||
* get heap relation oid and open the heap relation
|
(istemp && is_temp_rel_name(indexRelationName)))
|
||||||
*/
|
elog(ERROR, "index named \"%s\" already exists",
|
||||||
heapoid = GetHeapRelationOid(heapRelationName, indexRelationName, istemp);
|
indexRelationName);
|
||||||
|
|
||||||
/*
|
|
||||||
* Only SELECT ... FOR UPDATE are allowed while doing this
|
|
||||||
*/
|
|
||||||
heapRelation = heap_open(heapoid, ShareLock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* construct tuple descriptor for index tuples
|
* construct tuple descriptor for index tuples
|
||||||
@ -649,8 +620,11 @@ index_create(char *heapRelationName,
|
|||||||
/*
|
/*
|
||||||
* create the index relation
|
* create the index relation
|
||||||
*/
|
*/
|
||||||
indexRelation = heap_create(indexRelationName, indexTupDesc,
|
indexRelation = heap_create(indexRelationName,
|
||||||
|
namespaceId,
|
||||||
|
indexTupDesc,
|
||||||
istemp, false, allow_system_table_mods);
|
istemp, false, allow_system_table_mods);
|
||||||
|
indexoid = RelationGetRelid(indexRelation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain exclusive lock on it. Although no other backends can see it
|
* Obtain exclusive lock on it. Although no other backends can see it
|
||||||
@ -671,7 +645,7 @@ index_create(char *heapRelationName,
|
|||||||
* (append RELATION tuple)
|
* (append RELATION tuple)
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
indexoid = UpdateRelationRelation(indexRelation, temp_relname);
|
UpdateRelationRelation(indexRelation, temp_relname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We create the disk file for this relation here
|
* 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
|
* (Or, could define a rule to maintain the predicate) --Nels, Feb '92
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
UpdateIndexRelation(indexoid, heapoid, indexInfo,
|
UpdateIndexRelation(indexoid, heapRelationId, indexInfo,
|
||||||
classObjectId, primary);
|
classObjectId, primary);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -725,7 +699,7 @@ index_create(char *heapRelationName,
|
|||||||
*/
|
*/
|
||||||
if (IsBootstrapProcessingMode())
|
if (IsBootstrapProcessingMode())
|
||||||
{
|
{
|
||||||
index_register(heapRelationName, indexRelationName, indexInfo);
|
index_register(heapRelationId, indexoid, indexInfo);
|
||||||
/* XXX shouldn't we close the heap and index rels here? */
|
/* XXX shouldn't we close the heap and index rels here? */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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] =
|
char *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
|
||||||
{AttrDefaultIndex};
|
{AttrDefaultIndex};
|
||||||
char *Name_pg_class_indices[Num_pg_class_indices] =
|
char *Name_pg_class_indices[Num_pg_class_indices] =
|
||||||
{ClassNameIndex, ClassOidIndex};
|
{ClassNameNspIndex, ClassOidIndex};
|
||||||
char *Name_pg_database_indices[Num_pg_database_indices] =
|
char *Name_pg_database_indices[Num_pg_database_indices] =
|
||||||
{DatabaseNameIndex, DatabaseOidIndex};
|
{DatabaseNameIndex, DatabaseOidIndex};
|
||||||
char *Name_pg_group_indices[Num_pg_group_indices] =
|
char *Name_pg_group_indices[Num_pg_group_indices] =
|
||||||
|
126
src/backend/catalog/namespace.c
Normal file
126
src/backend/catalog/namespace.c
Normal file
@ -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);
|
||||||
|
}
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 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);
|
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.
|
* hand, re-creating n indexes may blow out the space.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cluster(char *oldrelname, char *oldindexname)
|
cluster(RangeVar *oldrelation, char *oldindexname)
|
||||||
{
|
{
|
||||||
Oid OIDOldHeap,
|
Oid OIDOldHeap,
|
||||||
OIDOldIndex,
|
OIDOldIndex,
|
||||||
@ -64,34 +65,40 @@ cluster(char *oldrelname, char *oldindexname)
|
|||||||
bool istemp;
|
bool istemp;
|
||||||
char NewHeapName[NAMEDATALEN];
|
char NewHeapName[NAMEDATALEN];
|
||||||
char NewIndexName[NAMEDATALEN];
|
char NewIndexName[NAMEDATALEN];
|
||||||
char saveoldrelname[NAMEDATALEN];
|
RangeVar *saveoldrelation;
|
||||||
char saveoldindexname[NAMEDATALEN];
|
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);
|
saveoldrelation = copyObject(oldrelation);
|
||||||
StrNCpy(saveoldindexname, oldindexname, NAMEDATALEN);
|
saveoldindex = copyObject(oldrelation);
|
||||||
|
saveoldindex->relname = pstrdup(oldindexname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We grab exclusive access to the target rel and index for the
|
* We grab exclusive access to the target rel and index for the
|
||||||
* duration of the transaction.
|
* duration of the transaction.
|
||||||
*/
|
*/
|
||||||
OldHeap = heap_openr(saveoldrelname, AccessExclusiveLock);
|
OldHeap = heap_openrv(saveoldrelation, AccessExclusiveLock);
|
||||||
OIDOldHeap = RelationGetRelid(OldHeap);
|
OIDOldHeap = RelationGetRelid(OldHeap);
|
||||||
|
|
||||||
OldIndex = index_openr(saveoldindexname);
|
OldIndex = index_openrv(saveoldindex);
|
||||||
LockRelation(OldIndex, AccessExclusiveLock);
|
LockRelation(OldIndex, AccessExclusiveLock);
|
||||||
OIDOldIndex = RelationGetRelid(OldIndex);
|
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
|
* Check that index is in fact an index on the given relation
|
||||||
*/
|
*/
|
||||||
if (OldIndex->rd_index->indrelid != OIDOldHeap)
|
if (OldIndex->rd_index->indrelid != OIDOldHeap)
|
||||||
elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"",
|
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 */
|
/* Drop relcache refcnts, but do NOT give up the locks */
|
||||||
heap_close(OldHeap, NoLock);
|
heap_close(OldHeap, NoLock);
|
||||||
@ -117,21 +124,26 @@ cluster(char *oldrelname, char *oldindexname)
|
|||||||
/* Create new index over the tuples of the new heap. */
|
/* Create new index over the tuples of the new heap. */
|
||||||
snprintf(NewIndexName, NAMEDATALEN, "temp_%u", OIDOldIndex);
|
snprintf(NewIndexName, NAMEDATALEN, "temp_%u", OIDOldIndex);
|
||||||
|
|
||||||
copy_index(OIDOldIndex, OIDNewHeap, NewIndexName);
|
copy_index(OIDOldIndex, OIDNewHeap, NewIndexName, istemp);
|
||||||
|
|
||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
|
|
||||||
/* Destroy old heap (along with its index) and rename new. */
|
/* Destroy old heap (along with its index) and rename new. */
|
||||||
heap_drop_with_catalog(saveoldrelname, allowSystemTableMods);
|
heap_drop_with_catalog(saveoldrelation->relname, allowSystemTableMods);
|
||||||
|
|
||||||
CommandCounterIncrement();
|
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. */
|
/* This one might be unnecessary, but let's be safe. */
|
||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
|
|
||||||
renamerel(NewIndexName, saveoldindexname);
|
renamerel(NewIndex, saveoldindex->relname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Oid
|
static Oid
|
||||||
@ -151,7 +163,9 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp)
|
|||||||
*/
|
*/
|
||||||
tupdesc = CreateTupleDescCopyConstr(OldHeapDesc);
|
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->relkind,
|
||||||
OldHeap->rd_rel->relhasoids,
|
OldHeap->rd_rel->relhasoids,
|
||||||
istemp,
|
istemp,
|
||||||
@ -168,7 +182,7 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp)
|
|||||||
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so
|
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so
|
||||||
* that the TOAST table will be visible for insertion.
|
* that the TOAST table will be visible for insertion.
|
||||||
*/
|
*/
|
||||||
AlterTableCreateToastTable(NewName, true);
|
AlterTableCreateToastTable(OIDNewHeap, true);
|
||||||
|
|
||||||
heap_close(OldHeap, NoLock);
|
heap_close(OldHeap, NoLock);
|
||||||
|
|
||||||
@ -176,7 +190,7 @@ copy_heap(Oid OIDOldHeap, char *NewName, bool istemp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName)
|
copy_index(Oid OIDOldIndex, Oid OIDNewHeap, char *NewIndexName, bool istemp)
|
||||||
{
|
{
|
||||||
Relation OldIndex,
|
Relation OldIndex,
|
||||||
NewHeap;
|
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
|
* 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
|
* from pg_index, and add a new index with a temporary name (that will
|
||||||
* be changed later).
|
* 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);
|
indexInfo = BuildIndexInfo(OldIndex->rd_index);
|
||||||
|
|
||||||
index_create(RelationGetRelationName(NewHeap),
|
index_create(OIDNewHeap,
|
||||||
NewIndexName,
|
NewIndexName,
|
||||||
indexInfo,
|
indexInfo,
|
||||||
OldIndex->rd_rel->relam,
|
OldIndex->rd_rel->relam,
|
||||||
OldIndex->rd_index->indclass,
|
OldIndex->rd_index->indclass,
|
||||||
|
istemp,
|
||||||
OldIndex->rd_index->indisprimary,
|
OldIndex->rd_index->indisprimary,
|
||||||
allowSystemTableMods);
|
allowSystemTableMods);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* The PerformAddAttribute() code, like most of the relation
|
* The PerformAddAttribute() code, like most of the relation
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_attrdef.h"
|
#include "catalog/pg_attrdef.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
@ -34,7 +35,6 @@
|
|||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/command.h"
|
#include "commands/command.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "commands/defrem.h"
|
|
||||||
#include "executor/execdefs.h"
|
#include "executor/execdefs.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
@ -415,8 +415,8 @@ AlterTableAddColumn(const char *relationName,
|
|||||||
|
|
||||||
rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
reltup = SearchSysCache(RELNAME,
|
reltup = SearchSysCache(RELOID,
|
||||||
PointerGetDatum(relationName),
|
ObjectIdGetDatum(myrelid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
|
|
||||||
if (!HeapTupleIsValid(reltup))
|
if (!HeapTupleIsValid(reltup))
|
||||||
@ -424,7 +424,7 @@ AlterTableAddColumn(const char *relationName,
|
|||||||
relationName);
|
relationName);
|
||||||
|
|
||||||
if (SearchSysCacheExists(ATTNAME,
|
if (SearchSysCacheExists(ATTNAME,
|
||||||
ObjectIdGetDatum(reltup->t_data->t_oid),
|
ObjectIdGetDatum(myrelid),
|
||||||
PointerGetDatum(colDef->colname),
|
PointerGetDatum(colDef->colname),
|
||||||
0, 0))
|
0, 0))
|
||||||
elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in table \"%s\"",
|
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 = (Form_pg_attribute) GETSTRUCT(attributeTuple);
|
||||||
|
|
||||||
attribute->attrelid = reltup->t_data->t_oid;
|
attribute->attrelid = myrelid;
|
||||||
namestrcpy(&(attribute->attname), colDef->colname);
|
namestrcpy(&(attribute->attname), colDef->colname);
|
||||||
attribute->atttypid = typeTuple->t_data->t_oid;
|
attribute->atttypid = typeTuple->t_data->t_oid;
|
||||||
attribute->attstattarget = DEFAULT_ATTSTATTARGET;
|
attribute->attstattarget = DEFAULT_ATTSTATTARGET;
|
||||||
@ -532,7 +532,7 @@ AlterTableAddColumn(const char *relationName,
|
|||||||
*/
|
*/
|
||||||
if (colDef->constraints != NIL)
|
if (colDef->constraints != NIL)
|
||||||
{
|
{
|
||||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
rel = heap_open(myrelid, AccessExclusiveLock);
|
||||||
AddRelationRawConstraints(rel, NIL, colDef->constraints);
|
AddRelationRawConstraints(rel, NIL, colDef->constraints);
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
}
|
}
|
||||||
@ -541,7 +541,7 @@ AlterTableAddColumn(const char *relationName,
|
|||||||
* Automatically create the secondary relation for TOAST if it
|
* Automatically create the secondary relation for TOAST if it
|
||||||
* formerly had no such but now has toastable attributes.
|
* 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
|
else
|
||||||
{
|
{
|
||||||
htup = SearchSysCache(RELOID,
|
index_drop(index->indexrelid);
|
||||||
ObjectIdGetDatum(index->indexrelid),
|
|
||||||
0, 0, 0);
|
|
||||||
RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
|
|
||||||
ReleaseSysCache(htup);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1066,8 +1062,8 @@ AlterTableDropColumn(const char *relationName,
|
|||||||
* lock the pg_class tuple for update
|
* lock the pg_class tuple for update
|
||||||
*/
|
*/
|
||||||
rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
reltup = SearchSysCache(RELNAME,
|
reltup = SearchSysCache(RELOID,
|
||||||
PointerGetDatum(relationName),
|
ObjectIdGetDatum(myrelid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(reltup))
|
if (!HeapTupleIsValid(reltup))
|
||||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
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
|
* Get the target pg_attribute tuple and make a modifiable copy
|
||||||
*/
|
*/
|
||||||
tup = SearchSysCacheCopy(ATTNAME,
|
tup = SearchSysCacheCopy(ATTNAME,
|
||||||
ObjectIdGetDatum(reltup->t_data->t_oid),
|
ObjectIdGetDatum(myrelid),
|
||||||
PointerGetDatum(colName),
|
PointerGetDatum(colName),
|
||||||
0, 0);
|
0, 0);
|
||||||
if (!HeapTupleIsValid(tup))
|
if (!HeapTupleIsValid(tup))
|
||||||
@ -1370,7 +1366,8 @@ AlterTableAddConstraint(char *relationName,
|
|||||||
* someone doesn't delete rows out from under us.
|
* 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)
|
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "referenced table \"%s\" not a relation",
|
elog(ERROR, "referenced table \"%s\" not a relation",
|
||||||
fkconstraint->pktable->relname);
|
fkconstraint->pktable->relname);
|
||||||
@ -1557,43 +1554,48 @@ AlterTableDropConstraint(const char *relationName,
|
|||||||
* ALTER TABLE OWNER
|
* ALTER TABLE OWNER
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AlterTableOwner(const char *relationName, const char *newOwnerName)
|
AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName)
|
||||||
{
|
{
|
||||||
Oid relationOid;
|
Relation rel;
|
||||||
Relation relation;
|
Oid myrelid;
|
||||||
int32 newOwnerSysId;
|
int32 newOwnerSysId;
|
||||||
|
|
||||||
/* check that we are the superuser */
|
/* check that we are the superuser */
|
||||||
if (!superuser())
|
if (!superuser())
|
||||||
elog(ERROR, "ALTER TABLE: permission denied");
|
elog(ERROR, "ALTER TABLE: permission denied");
|
||||||
|
|
||||||
/* lookup the OID of the target relation */
|
/* lookup the OID of the target relation */
|
||||||
relation = RelationNameGetRelation(relationName);
|
rel = relation_openrv(tgtrel, AccessExclusiveLock);
|
||||||
relationOid = relation->rd_id;
|
myrelid = RelationGetRelid(rel);
|
||||||
RelationClose(relation);
|
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||||
|
|
||||||
/* lookup the sysid of the new owner */
|
/* lookup the sysid of the new owner */
|
||||||
newOwnerSysId = get_usesysid(newOwnerName);
|
newOwnerSysId = get_usesysid(newOwnerName);
|
||||||
|
|
||||||
/* do all the actual work */
|
/* do all the actual work */
|
||||||
AlterTableOwnerId(relationOid, newOwnerSysId);
|
AlterTableOwnerId(myrelid, newOwnerSysId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
|
AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
|
||||||
{
|
{
|
||||||
|
Relation target_rel;
|
||||||
Relation class_rel;
|
Relation class_rel;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Relation idescs[Num_pg_class_indices];
|
Relation idescs[Num_pg_class_indices];
|
||||||
Form_pg_class tuple_class;
|
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,
|
tuple = SearchSysCacheCopy(RELOID,
|
||||||
ObjectIdGetDatum(relationOid),
|
ObjectIdGetDatum(relationOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
elog(ERROR, "ALTER TABLE: object ID %hd not found",
|
elog(ERROR, "ALTER TABLE: relation %u not found", relationOid);
|
||||||
relationOid);
|
|
||||||
|
|
||||||
tuple_class = (Form_pg_class) GETSTRUCT(tuple);
|
tuple_class = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
|
|
||||||
/* Can we change the ownership of this 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
|
* Okay, this is a valid tuple: change its ownership and
|
||||||
* write to the heap.
|
* write to the heap.
|
||||||
*/
|
*/
|
||||||
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
|
||||||
tuple_class->relowner = newOwnerSysId;
|
tuple_class->relowner = newOwnerSysId;
|
||||||
simple_heap_update(class_rel, &tuple->t_self, tuple);
|
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
|
* indexes that belong to the table, as well as the table's toast
|
||||||
* table (if it has one)
|
* 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;
|
List *index_oid_list, *i;
|
||||||
|
|
||||||
/* Find all the indexes belonging to this relation */
|
/* Find all the indexes belonging to this relation */
|
||||||
target_rel = heap_open(relationOid, RowExclusiveLock);
|
|
||||||
index_oid_list = RelationGetIndexList(target_rel);
|
index_oid_list = RelationGetIndexList(target_rel);
|
||||||
heap_close(target_rel, RowExclusiveLock);
|
|
||||||
|
|
||||||
/* For each index, recursively change its ownership */
|
/* For each index, recursively change its ownership */
|
||||||
foreach (i, index_oid_list)
|
foreach(i, index_oid_list)
|
||||||
{
|
{
|
||||||
AlterTableOwnerId(lfirsti(i), newOwnerSysId);
|
AlterTableOwnerId(lfirsti(i), newOwnerSysId);
|
||||||
}
|
}
|
||||||
|
|
||||||
freeList(index_oid_list);
|
freeList(index_oid_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tuple_class->relkind == RELKIND_RELATION)
|
||||||
|
{
|
||||||
/* If it has a toast table, recurse to change its ownership */
|
/* If it has a toast table, recurse to change its ownership */
|
||||||
if (tuple_class->reltoastrelid != InvalidOid)
|
if (tuple_class->reltoastrelid != InvalidOid)
|
||||||
{
|
{
|
||||||
@ -1644,7 +1645,8 @@ AlterTableOwnerId(Oid relationOid, int32 newOwnerSysId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
heap_freetuple(tuple);
|
heap_freetuple(tuple);
|
||||||
heap_close(class_rel, NoLock);
|
heap_close(class_rel, RowExclusiveLock);
|
||||||
|
heap_close(target_rel, NoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1669,10 +1671,9 @@ CheckTupleType(Form_pg_class tuple_class)
|
|||||||
* ALTER TABLE CREATE TOAST TABLE
|
* ALTER TABLE CREATE TOAST TABLE
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AlterTableCreateToastTable(const char *relationName, bool silent)
|
AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
Oid myrelid;
|
|
||||||
HeapTuple reltup;
|
HeapTuple reltup;
|
||||||
HeapTupleData classtuple;
|
HeapTupleData classtuple;
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
@ -1690,14 +1691,13 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
|
|||||||
* Grab an exclusive lock on the target table, which we will NOT
|
* Grab an exclusive lock on the target table, which we will NOT
|
||||||
* release until end of transaction.
|
* release until end of transaction.
|
||||||
*/
|
*/
|
||||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
rel = heap_open(relOid, AccessExclusiveLock);
|
||||||
myrelid = RelationGetRelid(rel);
|
|
||||||
|
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
|
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");
|
elog(ERROR, "ALTER TABLE: permission denied");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1705,12 +1705,12 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
|
|||||||
*/
|
*/
|
||||||
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
reltup = SearchSysCache(RELNAME,
|
reltup = SearchSysCache(RELOID,
|
||||||
PointerGetDatum(relationName),
|
ObjectIdGetDatum(relOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(reltup))
|
if (!HeapTupleIsValid(reltup))
|
||||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
||||||
relationName);
|
RelationGetRelationName(rel));
|
||||||
classtuple.t_self = reltup->t_self;
|
classtuple.t_self = reltup->t_self;
|
||||||
ReleaseSysCache(reltup);
|
ReleaseSysCache(reltup);
|
||||||
|
|
||||||
@ -1739,7 +1739,7 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
elog(ERROR, "ALTER TABLE: relation \"%s\" already has a toast table",
|
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",
|
elog(ERROR, "ALTER TABLE: relation \"%s\" does not need a toast table",
|
||||||
relationName);
|
RelationGetRelationName(rel));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the toast table and its index
|
* Create the toast table and its index
|
||||||
*/
|
*/
|
||||||
sprintf(toast_relname, "pg_toast_%u", myrelid);
|
sprintf(toast_relname, "pg_toast_%u", relOid);
|
||||||
sprintf(toast_idxname, "pg_toast_%u_idx", myrelid);
|
sprintf(toast_idxname, "pg_toast_%u_idx", relOid);
|
||||||
|
|
||||||
/* this is pretty painful... need a tuple descriptor */
|
/* this is pretty painful... need a tuple descriptor */
|
||||||
tupdesc = CreateTemplateTupleDesc(3);
|
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,
|
* collision, and the toast rel will be destroyed when its master is,
|
||||||
* so there's no need to handle the toast rel as temp.
|
* 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,
|
RELKIND_TOASTVALUE, false,
|
||||||
false, true);
|
false, true);
|
||||||
|
|
||||||
@ -1825,9 +1827,9 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
|
|||||||
classObjectId[0] = OID_BTREE_OPS_OID;
|
classObjectId[0] = OID_BTREE_OPS_OID;
|
||||||
classObjectId[1] = INT4_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,
|
BTREE_AM_OID, classObjectId,
|
||||||
true, true);
|
false, true, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update toast rel's pg_class entry to show that it has an index. The
|
* 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)
|
foreach(p, lockstmt->relations)
|
||||||
{
|
{
|
||||||
RangeVar *relation = lfirst(p);
|
RangeVar *relation = lfirst(p);
|
||||||
char *relname = relation->relname;
|
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
int aclresult;
|
int32 aclresult;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't want to open the relation until we've checked privilege.
|
* We don't want to open the relation until we've checked privilege.
|
||||||
* So, manually get the relation OID.
|
* So, manually get the relation OID.
|
||||||
*/
|
*/
|
||||||
reloid = GetSysCacheOid(RELNAME,
|
reloid = RangeVarGetRelid(relation, false);
|
||||||
PointerGetDatum(relname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(reloid))
|
|
||||||
elog(ERROR, "LOCK TABLE: relation \"%s\" does not exist",
|
|
||||||
relname);
|
|
||||||
|
|
||||||
if (lockstmt->mode == AccessShareLock)
|
if (lockstmt->mode == AccessShareLock)
|
||||||
aclresult = pg_class_aclcheck(reloid, GetUserId(),
|
aclresult = pg_class_aclcheck(reloid, GetUserId(),
|
||||||
@ -1958,7 +1954,7 @@ LockTableCommand(LockStmt *lockstmt)
|
|||||||
/* Currently, we only allow plain tables to be locked */
|
/* Currently, we only allow plain tables to be locked */
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "LOCK TABLE: %s is not a table",
|
elog(ERROR, "LOCK TABLE: %s is not a table",
|
||||||
relname);
|
relation->relname);
|
||||||
|
|
||||||
relation_close(rel, NoLock); /* close rel, keep lock */
|
relation_close(rel, NoLock); /* close rel, keep lock */
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
|
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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/indexing.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_description.h"
|
#include "catalog/pg_description.h"
|
||||||
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
#include "catalog/pg_rewrite.h"
|
#include "catalog/pg_rewrite.h"
|
||||||
#include "catalog/pg_trigger.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 CommentAttribute(char *relation, char *attrib, char *comment);
|
||||||
static void CommentDatabase(char *database, char *comment);
|
static void CommentDatabase(char *database, char *comment);
|
||||||
static void CommentRewrite(char *rule, char *comment);
|
static void CommentRewrite(char *rule, char *comment);
|
||||||
@ -74,7 +76,7 @@ static void CommentTrigger(char *trigger, char *relation, char *comments);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
CommentObject(int objtype, char *objname, char *objproperty,
|
CommentObject(int objtype, char *schemaname, char *objname, char *objproperty,
|
||||||
List *objlist, char *comment)
|
List *objlist, char *comment)
|
||||||
{
|
{
|
||||||
switch (objtype)
|
switch (objtype)
|
||||||
@ -83,7 +85,7 @@ CommentObject(int objtype, char *objname, char *objproperty,
|
|||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
case TABLE:
|
case TABLE:
|
||||||
case VIEW:
|
case VIEW:
|
||||||
CommentRelation(objtype, objname, comment);
|
CommentRelation(objtype, schemaname, objname, comment);
|
||||||
break;
|
break;
|
||||||
case COLUMN:
|
case COLUMN:
|
||||||
CommentAttribute(objname, objproperty, comment);
|
CommentAttribute(objname, objproperty, comment);
|
||||||
@ -323,9 +325,16 @@ DeleteComments(Oid oid, Oid classoid)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CommentRelation(int reltype, char *relname, char *comment)
|
CommentRelation(int reltype, char *schemaname, char *relname, char *comment)
|
||||||
{
|
{
|
||||||
Relation relation;
|
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
|
* 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
|
* did, they'd fail to remove the entry we are about to make in
|
||||||
* pg_description.)
|
* pg_description.)
|
||||||
*/
|
*/
|
||||||
relation = relation_openr(relname, AccessShareLock);
|
relation = relation_openrv(tgtrel, AccessShareLock);
|
||||||
|
|
||||||
/* Check object security */
|
/* Check object security */
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
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 */
|
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
|
||||||
|
|
||||||
classoid = GetSysCacheOid(RELNAME,
|
classoid = get_relname_relid(RewriteRelationName, PG_CATALOG_NAMESPACE);
|
||||||
PointerGetDatum(RewriteRelationName),
|
|
||||||
0, 0, 0);
|
|
||||||
Assert(OidIsValid(classoid));
|
Assert(OidIsValid(classoid));
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* 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 */
|
/* pg_aggregate doesn't have a hard-coded OID, so must look it up */
|
||||||
|
|
||||||
classoid = GetSysCacheOid(RELNAME,
|
classoid = get_relname_relid(AggregateRelationName, PG_CATALOG_NAMESPACE);
|
||||||
PointerGetDatum(AggregateRelationName),
|
|
||||||
0, 0, 0);
|
|
||||||
Assert(OidIsValid(classoid));
|
Assert(OidIsValid(classoid));
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "access/heapam.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/indexing.h"
|
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
|
#include "catalog/indexing.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_inherits.h"
|
#include "catalog/pg_inherits.h"
|
||||||
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "commands/creatinh.h"
|
#include "commands/creatinh.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
@ -54,6 +56,7 @@ Oid
|
|||||||
DefineRelation(CreateStmt *stmt, char relkind)
|
DefineRelation(CreateStmt *stmt, char relkind)
|
||||||
{
|
{
|
||||||
char *relname = palloc(NAMEDATALEN);
|
char *relname = palloc(NAMEDATALEN);
|
||||||
|
Oid namespaceId;
|
||||||
List *schema = stmt->tableElts;
|
List *schema = stmt->tableElts;
|
||||||
int numberOfAttributes;
|
int numberOfAttributes;
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
@ -73,6 +76,12 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
*/
|
*/
|
||||||
StrNCpy(relname, (stmt->relation)->relname, NAMEDATALEN);
|
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
|
* Merge domain attributes into the known columns before processing table
|
||||||
* inheritance. Otherwise we risk adding double constraints to a
|
* 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,
|
relkind,
|
||||||
stmt->hasoids || parentHasOids,
|
stmt->hasoids || parentHasOids,
|
||||||
stmt->relation->istemp,
|
stmt->relation->istemp,
|
||||||
@ -330,7 +340,7 @@ MergeDomainAttributes(List *schema)
|
|||||||
* Input arguments:
|
* Input arguments:
|
||||||
* 'schema' is the column/attribute definition for the table. (It's a list
|
* 'schema' is the column/attribute definition for the table. (It's a list
|
||||||
* of ColumnDef's.) It is destructively changed.
|
* 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.
|
* 'istemp' is TRUE if we are creating a temp relation.
|
||||||
*
|
*
|
||||||
* Output arguments:
|
* 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
|
* Scan the parents left-to-right, and merge their attributes to form
|
||||||
* a list of inherited attributes (inhSchema). Also check to see if
|
* 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;
|
child_attno = 0;
|
||||||
foreach(entry, supers)
|
foreach(entry, supers)
|
||||||
{
|
{
|
||||||
char *name = ((RangeVar *) lfirst(entry))->relname;
|
RangeVar *parent = (RangeVar *) lfirst(entry);
|
||||||
Relation relation;
|
Relation relation;
|
||||||
TupleDesc tupleDesc;
|
TupleDesc tupleDesc;
|
||||||
TupleConstr *constr;
|
TupleConstr *constr;
|
||||||
AttrNumber *newattno;
|
AttrNumber *newattno;
|
||||||
AttrNumber parent_attno;
|
AttrNumber parent_attno;
|
||||||
|
|
||||||
relation = heap_openr(name, AccessShareLock);
|
relation = heap_openrv(parent, AccessShareLock);
|
||||||
|
|
||||||
if (relation->rd_rel->relkind != RELKIND_RELATION)
|
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 */
|
/* Permanent rels cannot inherit from temporary ones */
|
||||||
if (!istemp && is_temp_rel_name(name))
|
if (!istemp && is_temp_rel_name(parent->relname))
|
||||||
elog(ERROR, "CREATE TABLE: cannot inherit from temp relation \"%s\"", name);
|
elog(ERROR, "CREATE TABLE: cannot inherit from temp relation \"%s\"",
|
||||||
|
parent->relname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should have an UNDER permission flag for this, but for now,
|
* We should have an UNDER permission flag for this, but for now,
|
||||||
* demand that creator of a child table own the parent.
|
* demand that creator of a child table own the parent.
|
||||||
*/
|
*/
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
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;
|
parentHasOids |= relation->rd_rel->relhasoids;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "access/heapam.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/heap.h"
|
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
@ -33,6 +33,7 @@
|
|||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
#include "utils/temprel.h"
|
||||||
|
|
||||||
|
|
||||||
#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL)
|
#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.
|
* 'rangetable' is needed to interpret the predicate.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
DefineIndex(char *heapRelationName,
|
DefineIndex(RangeVar *heapRelation,
|
||||||
char *indexRelationName,
|
char *indexRelationName,
|
||||||
char *accessMethodName,
|
char *accessMethodName,
|
||||||
List *attributeList,
|
List *attributeList,
|
||||||
@ -73,6 +74,7 @@ DefineIndex(char *heapRelationName,
|
|||||||
Oid *classObjectId;
|
Oid *classObjectId;
|
||||||
Oid accessMethodId;
|
Oid accessMethodId;
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
|
bool istemp = is_temp_rel_name(heapRelation->relname);
|
||||||
Relation rel;
|
Relation rel;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_am accessMethodForm;
|
Form_pg_am accessMethodForm;
|
||||||
@ -93,20 +95,20 @@ DefineIndex(char *heapRelationName,
|
|||||||
/*
|
/*
|
||||||
* Open heap relation, acquire a suitable lock on it, remember its OID
|
* 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 */
|
/* Note: during bootstrap may see uncataloged relation */
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION &&
|
if (rel->rd_rel->relkind != RELKIND_RELATION &&
|
||||||
rel->rd_rel->relkind != RELKIND_UNCATALOGED)
|
rel->rd_rel->relkind != RELKIND_UNCATALOGED)
|
||||||
elog(ERROR, "DefineIndex: relation \"%s\" is not a table",
|
elog(ERROR, "DefineIndex: relation \"%s\" is not a table",
|
||||||
heapRelationName);
|
heapRelation->relname);
|
||||||
|
|
||||||
relationId = RelationGetRelid(rel);
|
relationId = RelationGetRelid(rel);
|
||||||
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
|
|
||||||
if (!IsBootstrapProcessingMode() &&
|
if (!IsBootstrapProcessingMode() &&
|
||||||
IsSystemRelationName(heapRelationName) &&
|
IsSystemRelationName(heapRelation->relname) &&
|
||||||
!IndexesAreActive(relationId, false))
|
!IndexesAreActive(relationId, false))
|
||||||
elog(ERROR, "Existing indexes are inactive. REINDEX first");
|
elog(ERROR, "Existing indexes are inactive. REINDEX first");
|
||||||
|
|
||||||
@ -187,9 +189,9 @@ DefineIndex(char *heapRelationName,
|
|||||||
relationId, accessMethodName, accessMethodId);
|
relationId, accessMethodName, accessMethodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
index_create(heapRelationName, indexRelationName,
|
index_create(relationId, indexRelationName,
|
||||||
indexInfo, accessMethodId, classObjectId,
|
indexInfo, accessMethodId, classObjectId,
|
||||||
primary, allowSystemTableMods);
|
istemp, primary, allowSystemTableMods);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We update the relation's pg_class tuple even if it already has
|
* We update the relation's pg_class tuple even if it already has
|
||||||
@ -500,23 +502,25 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
|
|||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
RemoveIndex(char *name)
|
RemoveIndex(RangeVar *relation)
|
||||||
{
|
{
|
||||||
|
Oid indOid;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
tuple = SearchSysCache(RELNAME,
|
indOid = RangeVarGetRelid(relation, false);
|
||||||
PointerGetDatum(name),
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(indOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
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)
|
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
|
||||||
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
||||||
name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
|
relation->relname, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
|
||||||
|
|
||||||
index_drop(tuple->t_data->t_oid);
|
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
index_drop(indOid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -528,8 +532,9 @@ RemoveIndex(char *name)
|
|||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ReindexIndex(const char *name, bool force /* currently unused */ )
|
ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ )
|
||||||
{
|
{
|
||||||
|
Oid indOid;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
bool overwrite = false;
|
bool overwrite = false;
|
||||||
|
|
||||||
@ -541,22 +546,24 @@ ReindexIndex(const char *name, bool force /* currently unused */ )
|
|||||||
if (IsTransactionBlock())
|
if (IsTransactionBlock())
|
||||||
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
|
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
|
||||||
|
|
||||||
tuple = SearchSysCache(RELNAME,
|
indOid = RangeVarGetRelid(indexRelation, false);
|
||||||
PointerGetDatum(name),
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(indOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
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)
|
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_INDEX)
|
||||||
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
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())
|
if (IsIgnoringSystemIndexes())
|
||||||
overwrite = true;
|
overwrite = true;
|
||||||
if (!reindex_index(tuple->t_data->t_oid, force, overwrite))
|
if (!reindex_index(indOid, force, overwrite))
|
||||||
elog(WARNING, "index \"%s\" wasn't reindexed", name);
|
elog(WARNING, "index \"%s\" wasn't reindexed", indexRelation->relname);
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -568,8 +575,9 @@ ReindexIndex(const char *name, bool force /* currently unused */ )
|
|||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ReindexTable(const char *name, bool force)
|
ReindexTable(RangeVar *relation, bool force)
|
||||||
{
|
{
|
||||||
|
Oid heapOid;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -580,20 +588,22 @@ ReindexTable(const char *name, bool force)
|
|||||||
if (IsTransactionBlock())
|
if (IsTransactionBlock())
|
||||||
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
|
elog(ERROR, "REINDEX cannot run inside a BEGIN/END block");
|
||||||
|
|
||||||
tuple = SearchSysCache(RELNAME,
|
heapOid = RangeVarGetRelid(relation, false);
|
||||||
PointerGetDatum(name),
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(heapOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
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)
|
if (((Form_pg_class) GETSTRUCT(tuple))->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
elog(ERROR, "relation \"%s\" is of type \"%c\"",
|
||||||
name, ((Form_pg_class) GETSTRUCT(tuple))->relkind);
|
relation->relname,
|
||||||
|
((Form_pg_class) GETSTRUCT(tuple))->relkind);
|
||||||
if (!reindex_relation(tuple->t_data->t_oid, force))
|
|
||||||
elog(WARNING, "table \"%s\" wasn't reindexed", name);
|
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
if (!reindex_relation(heapOid, force))
|
||||||
|
elog(WARNING, "table \"%s\" wasn't reindexed", relation->relname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/relcache.h"
|
#include "utils/relcache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "utils/temprel.h"
|
#include "utils/temprel.h"
|
||||||
@ -266,19 +267,20 @@ renameatt(char *relname,
|
|||||||
* renamerel - change the name of a relation
|
* renamerel - change the name of a relation
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
renamerel(const char *oldrelname, const char *newrelname)
|
renamerel(const RangeVar *relation, const char *newrelname)
|
||||||
{
|
{
|
||||||
Relation targetrelation;
|
Relation targetrelation;
|
||||||
Relation relrelation; /* for RELATION relation */
|
Relation relrelation; /* for RELATION relation */
|
||||||
HeapTuple reltup;
|
HeapTuple reltup;
|
||||||
|
Oid namespaceId;
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
char relkind;
|
char relkind;
|
||||||
bool relhastriggers;
|
bool relhastriggers;
|
||||||
Relation irelations[Num_pg_class_indices];
|
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",
|
elog(ERROR, "renamerel: system relation \"%s\" may not be renamed",
|
||||||
oldrelname);
|
relation->relname);
|
||||||
|
|
||||||
if (!allowSystemTableMods && IsSystemRelationName(newrelname))
|
if (!allowSystemTableMods && IsSystemRelationName(newrelname))
|
||||||
elog(ERROR, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs",
|
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
|
* Check for renaming a temp table, which only requires altering the
|
||||||
* temp-table mapping, not the underlying table.
|
* temp-table mapping, not the underlying table.
|
||||||
*/
|
*/
|
||||||
if (rename_temp_relation(oldrelname, newrelname))
|
if (rename_temp_relation(relation->relname, newrelname))
|
||||||
return; /* all done... */
|
return; /* all done... */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab an exclusive lock on the target table or index, which we will
|
* Grab an exclusive lock on the target table or index, which we will
|
||||||
* NOT release until end of transaction.
|
* NOT release until end of transaction.
|
||||||
*/
|
*/
|
||||||
targetrelation = relation_openr(oldrelname, AccessExclusiveLock);
|
targetrelation = relation_openrv(relation, AccessExclusiveLock);
|
||||||
|
|
||||||
|
namespaceId = RelationGetNamespace(targetrelation);
|
||||||
reloid = RelationGetRelid(targetrelation);
|
reloid = RelationGetRelid(targetrelation);
|
||||||
relkind = targetrelation->rd_rel->relkind;
|
relkind = targetrelation->rd_rel->relkind;
|
||||||
relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
|
relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
|
||||||
@ -323,13 +326,14 @@ renamerel(const char *oldrelname, const char *newrelname)
|
|||||||
*/
|
*/
|
||||||
relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
|
relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
reltup = SearchSysCacheCopy(RELNAME,
|
reltup = SearchSysCacheCopy(RELOID,
|
||||||
PointerGetDatum(oldrelname),
|
PointerGetDatum(reloid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(reltup))
|
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);
|
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.
|
* Also rename the associated type, if any.
|
||||||
*/
|
*/
|
||||||
if (relkind != RELKIND_INDEX)
|
if (relkind != RELKIND_INDEX)
|
||||||
TypeRename(oldrelname, newrelname);
|
TypeRename(relation->relname, newrelname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's a view, must also rename the associated ON SELECT rule.
|
* 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,
|
char *oldrulename,
|
||||||
*newrulename;
|
*newrulename;
|
||||||
|
|
||||||
oldrulename = MakeRetrieveViewRuleName(oldrelname);
|
oldrulename = MakeRetrieveViewRuleName(relation->relname);
|
||||||
newrulename = MakeRetrieveViewRuleName(newrelname);
|
newrulename = MakeRetrieveViewRuleName(newrelname);
|
||||||
RenameRewriteRule(oldrulename, newrulename);
|
RenameRewriteRule(oldrulename, newrulename);
|
||||||
}
|
}
|
||||||
@ -374,11 +378,11 @@ renamerel(const char *oldrelname, const char *newrelname)
|
|||||||
{
|
{
|
||||||
/* update tgargs where relname is primary key */
|
/* update tgargs where relname is primary key */
|
||||||
update_ri_trigger_args(reloid,
|
update_ri_trigger_args(reloid,
|
||||||
oldrelname, newrelname,
|
relation->relname, newrelname,
|
||||||
false, true);
|
false, true);
|
||||||
/* update tgargs where relname is foreign key */
|
/* update tgargs where relname is foreign key */
|
||||||
update_ri_trigger_args(reloid,
|
update_ri_trigger_args(reloid,
|
||||||
oldrelname, newrelname,
|
relation->relname, newrelname,
|
||||||
true, true);
|
true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 = "";
|
char *constrname = "";
|
||||||
Oid constrrelid = InvalidOid;
|
Oid constrrelid = InvalidOid;
|
||||||
|
|
||||||
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
|
rel = heap_openrv(stmt->relation, AccessExclusiveLock);
|
||||||
|
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
|
elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
|
||||||
@ -106,7 +106,7 @@ CreateTrigger(CreateTrigStmt *stmt)
|
|||||||
*/
|
*/
|
||||||
Relation conrel;
|
Relation conrel;
|
||||||
|
|
||||||
conrel = heap_openr(stmt->constrrel->relname, NoLock);
|
conrel = heap_openrv(stmt->constrrel, NoLock);
|
||||||
constrrelid = conrel->rd_id;
|
constrrelid = conrel->rd_id;
|
||||||
heap_close(conrel, NoLock);
|
heap_close(conrel, NoLock);
|
||||||
}
|
}
|
||||||
@ -285,8 +285,8 @@ CreateTrigger(CreateTrigStmt *stmt)
|
|||||||
* rebuild relcache entries.
|
* rebuild relcache entries.
|
||||||
*/
|
*/
|
||||||
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
|
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCacheCopy(RELNAME,
|
tuple = SearchSysCacheCopy(RELOID,
|
||||||
PointerGetDatum(stmt->relation->relname),
|
ObjectIdGetDatum(RelationGetRelid(rel)),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
elog(ERROR, "CreateTrigger: relation %s not found in pg_class",
|
elog(ERROR, "CreateTrigger: relation %s not found in pg_class",
|
||||||
@ -323,7 +323,7 @@ DropTrigger(DropTrigStmt *stmt)
|
|||||||
int found = 0;
|
int found = 0;
|
||||||
int tgfound = 0;
|
int tgfound = 0;
|
||||||
|
|
||||||
rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
|
rel = heap_openrv(stmt->relation, AccessExclusiveLock);
|
||||||
|
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
|
elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
|
||||||
@ -380,8 +380,8 @@ DropTrigger(DropTrigStmt *stmt)
|
|||||||
* rebuild relcache entries.
|
* rebuild relcache entries.
|
||||||
*/
|
*/
|
||||||
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
|
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCacheCopy(RELNAME,
|
tuple = SearchSysCacheCopy(RELOID,
|
||||||
PointerGetDatum(stmt->relation->relname),
|
ObjectIdGetDatum(RelationGetRelid(rel)),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
if (!HeapTupleIsValid(tuple))
|
||||||
elog(ERROR, "DropTrigger: relation %s not found in pg_class",
|
elog(ERROR, "DropTrigger: relation %s not found in pg_class",
|
||||||
@ -452,7 +452,7 @@ RelationRemoveTriggers(Relation rel)
|
|||||||
|
|
||||||
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
|
pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tup = SearchSysCacheCopy(RELOID,
|
tup = SearchSysCacheCopy(RELOID,
|
||||||
RelationGetRelid(rel),
|
ObjectIdGetDatum(RelationGetRelid(rel)),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tup))
|
if (!HeapTupleIsValid(tup))
|
||||||
elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
|
elog(ERROR, "RelationRemoveTriggers: relation %u not found in pg_class",
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* check to see if there is an ACL on pg_shadow
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CheckPgUserAclNotNull()
|
CheckPgUserAclNotNull(void)
|
||||||
{
|
{
|
||||||
HeapTuple htup;
|
HeapTuple htup;
|
||||||
|
|
||||||
htup = SearchSysCache(RELNAME,
|
htup = SearchSysCache(RELOID,
|
||||||
PointerGetDatum(ShadowRelationName),
|
ObjectIdGetDatum(RelOid_pg_shadow),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(htup))
|
if (!HeapTupleIsValid(htup))
|
||||||
elog(ERROR, "CheckPgUserAclNotNull: \"%s\" not found",
|
elog(ERROR, "CheckPgUserAclNotNull: \"%s\" not found",
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "access/heapam.h"
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "commands/command.h"
|
#include "commands/command.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
#include "executor/execdebug.h"
|
#include "executor/execdebug.h"
|
||||||
@ -696,10 +697,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
|
|
||||||
if (operation == CMD_SELECT)
|
if (operation == CMD_SELECT)
|
||||||
{
|
{
|
||||||
char *intoName;
|
|
||||||
Oid intoRelationId;
|
|
||||||
TupleDesc tupdesc;
|
|
||||||
|
|
||||||
if (!parseTree->isPortal)
|
if (!parseTree->isPortal)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -707,10 +704,16 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
*/
|
*/
|
||||||
if (parseTree->into != NULL)
|
if (parseTree->into != NULL)
|
||||||
{
|
{
|
||||||
|
char *intoName;
|
||||||
|
Oid namespaceId;
|
||||||
|
Oid intoRelationId;
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create the "into" relation
|
* create the "into" relation
|
||||||
*/
|
*/
|
||||||
intoName = parseTree->into->relname;
|
intoName = parseTree->into->relname;
|
||||||
|
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* have to copy tupType to get rid of constraints
|
* have to copy tupType to get rid of constraints
|
||||||
@ -719,6 +722,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
|
|
||||||
intoRelationId =
|
intoRelationId =
|
||||||
heap_create_with_catalog(intoName,
|
heap_create_with_catalog(intoName,
|
||||||
|
namespaceId,
|
||||||
tupdesc,
|
tupdesc,
|
||||||
RELKIND_RELATION, true,
|
RELKIND_RELATION, true,
|
||||||
parseTree->into->istemp,
|
parseTree->into->istemp,
|
||||||
@ -738,7 +742,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
|||||||
* with CommandCounterIncrement(), so that the TOAST table
|
* with CommandCounterIncrement(), so that the TOAST table
|
||||||
* will be visible for insertion.
|
* will be visible for insertion.
|
||||||
*/
|
*/
|
||||||
AlterTableCreateToastTable(intoName, true);
|
AlterTableCreateToastTable(intoRelationId, true);
|
||||||
|
|
||||||
intoRelationDesc = heap_open(intoRelationId,
|
intoRelationDesc = heap_open(intoRelationId,
|
||||||
AccessExclusiveLock);
|
AccessExclusiveLock);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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/catname.h"
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
@ -118,7 +119,7 @@ static void transformConstraintAttrs(List *constraintList);
|
|||||||
static void transformColumnType(ParseState *pstate, ColumnDef *column);
|
static void transformColumnType(ParseState *pstate, ColumnDef *column);
|
||||||
static void transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid);
|
static void transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid);
|
||||||
static void transformFkeyGetPrimaryKey(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 Oid transformFkeyGetColType(CreateStmtContext *cxt, char *colname);
|
||||||
static void release_pstate_resources(ParseState *pstate);
|
static void release_pstate_resources(ParseState *pstate);
|
||||||
static FromExpr *makeFromExpr(List *fromlist, Node *quals);
|
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 */
|
/* In ALTER TABLE case, a primary index might already exist */
|
||||||
if (cxt->pkey != NULL ||
|
if (cxt->pkey != NULL ||
|
||||||
(OidIsValid(cxt->relOid) &&
|
(OidIsValid(cxt->relOid) &&
|
||||||
relationHasPrimaryKey((cxt->relation)->relname)))
|
relationHasPrimaryKey(cxt->relOid)))
|
||||||
elog(ERROR, "%s / PRIMARY KEY multiple primary keys"
|
elog(ERROR, "%s / PRIMARY KEY multiple primary keys"
|
||||||
" for table '%s' are not allowed",
|
" for table '%s' are not allowed",
|
||||||
cxt->stmtType, (cxt->relation)->relname);
|
cxt->stmtType, (cxt->relation)->relname);
|
||||||
@ -1115,10 +1116,10 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
|
|||||||
int count;
|
int count;
|
||||||
|
|
||||||
Assert(IsA(inh, RangeVar));
|
Assert(IsA(inh, RangeVar));
|
||||||
rel = heap_openr(inh->relname, AccessShareLock);
|
rel = heap_openrv(inh, AccessShareLock);
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "inherited table \"%s\" is not a relation",
|
elog(ERROR, "inherited table \"%s\" is not a relation",
|
||||||
strVal(inh));
|
inh->relname);
|
||||||
for (count = 0; count < rel->rd_att->natts; count++)
|
for (count = 0; count < rel->rd_att->natts; count++)
|
||||||
{
|
{
|
||||||
Form_pg_attribute inhattr = rel->rd_att->attrs[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
|
* beforehand. We don't need to hold a refcount on the relcache
|
||||||
* entry, however.
|
* entry, however.
|
||||||
*/
|
*/
|
||||||
heap_close(heap_openr(stmt->relation->relname, AccessExclusiveLock),
|
heap_close(heap_openrv(stmt->relation, AccessExclusiveLock),
|
||||||
NoLock);
|
NoLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2562,9 +2563,7 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
|
|||||||
cxt.relation = stmt->relation;
|
cxt.relation = stmt->relation;
|
||||||
cxt.inhRelations = NIL;
|
cxt.inhRelations = NIL;
|
||||||
cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname);
|
cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname);
|
||||||
cxt.relOid = GetSysCacheOid(RELNAME,
|
cxt.relOid = RangeVarGetRelid(stmt->relation, false);
|
||||||
PointerGetDatum((stmt->relation)->relname),
|
|
||||||
0, 0, 0);
|
|
||||||
cxt.hasoids = SearchSysCacheExists(ATTNUM,
|
cxt.hasoids = SearchSysCacheExists(ATTNUM,
|
||||||
ObjectIdGetDatum(cxt.relOid),
|
ObjectIdGetDatum(cxt.relOid),
|
||||||
Int16GetDatum(ObjectIdAttributeNumber),
|
Int16GetDatum(ObjectIdAttributeNumber),
|
||||||
@ -2594,9 +2593,7 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
|
|||||||
cxt.relation = stmt->relation;
|
cxt.relation = stmt->relation;
|
||||||
cxt.inhRelations = NIL;
|
cxt.inhRelations = NIL;
|
||||||
cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname);
|
cxt.relation->istemp = is_temp_rel_name(stmt->relation->relname);
|
||||||
cxt.relOid = GetSysCacheOid(RELNAME,
|
cxt.relOid = RangeVarGetRelid(stmt->relation, false);
|
||||||
PointerGetDatum((stmt->relation)->relname),
|
|
||||||
0, 0, 0);
|
|
||||||
cxt.hasoids = SearchSysCacheExists(ATTNUM,
|
cxt.hasoids = SearchSysCacheExists(ATTNUM,
|
||||||
ObjectIdGetDatum(cxt.relOid),
|
ObjectIdGetDatum(cxt.relOid),
|
||||||
Int16GetDatum(ObjectIdAttributeNumber),
|
Int16GetDatum(ObjectIdAttributeNumber),
|
||||||
@ -2844,7 +2841,7 @@ transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid)
|
|||||||
/*
|
/*
|
||||||
* Open the referenced table
|
* Open the referenced table
|
||||||
*/
|
*/
|
||||||
pkrel = heap_openr(fkconstraint->pktable->relname, AccessShareLock);
|
pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock);
|
||||||
|
|
||||||
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
|
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "Referenced relation \"%s\" is not a table",
|
elog(ERROR, "Referenced relation \"%s\" is not a table",
|
||||||
@ -2937,7 +2934,7 @@ transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
|
|||||||
/*
|
/*
|
||||||
* Open the referenced table
|
* Open the referenced table
|
||||||
*/
|
*/
|
||||||
pkrel = heap_openr(fkconstraint->pktable->relname, AccessShareLock);
|
pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock);
|
||||||
|
|
||||||
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
|
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "Referenced relation \"%s\" is not a table",
|
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.
|
* See whether an existing relation has a primary key.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
relationHasPrimaryKey(char *relname)
|
relationHasPrimaryKey(Oid relationOid)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
List *indexoidlist,
|
List *indexoidlist,
|
||||||
*indexoidscan;
|
*indexoidscan;
|
||||||
|
|
||||||
rel = heap_openr(relname, AccessShareLock);
|
rel = heap_open(relationOid, AccessShareLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the list of index OIDs for the table from the relcache, and
|
* Get the list of index OIDs for the table from the relcache, and
|
||||||
@ -3084,10 +3081,10 @@ transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
|
|||||||
int count;
|
int count;
|
||||||
|
|
||||||
Assert(IsA(inh, RangeVar));
|
Assert(IsA(inh, RangeVar));
|
||||||
rel = heap_openr(inh->relname, AccessShareLock);
|
rel = heap_openrv(inh, AccessShareLock);
|
||||||
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
if (rel->rd_rel->relkind != RELKIND_RELATION)
|
||||||
elog(ERROR, "inherited table \"%s\" is not a relation",
|
elog(ERROR, "inherited table \"%s\" is not a relation",
|
||||||
strVal(inh));
|
inh->relname);
|
||||||
for (count = 0; count < rel->rd_att->natts; count++)
|
for (count = 0; count < rel->rd_att->natts; count++)
|
||||||
{
|
{
|
||||||
char *name = NameStr(rel->rd_att->attrs[count]->attname);
|
char *name = NameStr(rel->rd_att->attrs[count]->attname);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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*
|
* analyze.c will eventually do the corresponding heap_close(), but *not*
|
||||||
* release the lock.
|
* release the lock.
|
||||||
*/
|
*/
|
||||||
pstate->p_target_relation = heap_openr(relation->relname, RowExclusiveLock);
|
pstate->p_target_relation = heap_openrv(relation, RowExclusiveLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now build an RTE.
|
* Now build an RTE.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* access level depending on whether we're doing SELECT FOR UPDATE.
|
||||||
*/
|
*/
|
||||||
lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock;
|
lockmode = isForUpdate(pstate, refname) ? RowShareLock : AccessShareLock;
|
||||||
rel = heap_openr(relation->relname, lockmode);
|
rel = heap_openrv(relation, lockmode);
|
||||||
rte->relid = RelationGetRelid(rel);
|
rte->relid = RelationGetRelid(rel);
|
||||||
|
|
||||||
eref = alias ? (Alias *) copyObject(alias) : makeAlias(refname, NIL);
|
eref = alias ? (Alias *) copyObject(alias) : makeAlias(refname, NIL);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* actions. But for now, let's just grab AccessExclusiveLock all the
|
||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
event_relation = heap_openr(event_obj->relname, AccessExclusiveLock);
|
event_relation = heap_openrv(event_obj, AccessExclusiveLock);
|
||||||
ev_relid = RelationGetRelid(event_relation);
|
ev_relid = RelationGetRelid(event_relation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "access/heapam.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_shadow.h"
|
#include "catalog/pg_shadow.h"
|
||||||
#include "commands/async.h"
|
#include "commands/async.h"
|
||||||
#include "commands/cluster.h"
|
#include "commands/cluster.h"
|
||||||
@ -94,9 +95,10 @@ DropErrorMsg(char *relname, char wrongkind, char rightkind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CheckDropPermissions(char *name, char rightkind)
|
CheckDropPermissions(RangeVar *rel, char rightkind)
|
||||||
{
|
{
|
||||||
struct kindstrings *rentry;
|
struct kindstrings *rentry;
|
||||||
|
Oid relOid;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_class classform;
|
Form_pg_class classform;
|
||||||
|
|
||||||
@ -105,49 +107,54 @@ CheckDropPermissions(char *name, char rightkind)
|
|||||||
break;
|
break;
|
||||||
Assert(rentry->kind != '\0');
|
Assert(rentry->kind != '\0');
|
||||||
|
|
||||||
tuple = SearchSysCache(RELNAME,
|
relOid = RangeVarGetRelid(rel, true);
|
||||||
PointerGetDatum(name),
|
if (!OidIsValid(relOid))
|
||||||
|
elog(ERROR, "%s \"%s\" does not exist", rentry->name, rel->relname);
|
||||||
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(relOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
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);
|
classform = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
|
|
||||||
if (classform->relkind != rightkind)
|
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\"",
|
elog(ERROR, "you do not own %s \"%s\"",
|
||||||
rentry->name, name);
|
rentry->name, rel->relname);
|
||||||
|
|
||||||
if (!allowSystemTableMods && IsSystemRelationName(name) &&
|
if (!allowSystemTableMods && IsSystemRelationName(rel->relname) &&
|
||||||
!is_temp_relname(name))
|
!is_temp_relname(rel->relname))
|
||||||
elog(ERROR, "%s \"%s\" is a system %s",
|
elog(ERROR, "%s \"%s\" is a system %s",
|
||||||
rentry->name, name, rentry->name);
|
rentry->name, rel->relname, rentry->name);
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CheckOwnership(char *relname, bool noCatalogs)
|
CheckOwnership(RangeVar *rel, bool noCatalogs)
|
||||||
{
|
{
|
||||||
|
Oid relOid;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
tuple = SearchSysCache(RELNAME,
|
relOid = RangeVarGetRelid(rel, false);
|
||||||
PointerGetDatum(relname),
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(relOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tuple))
|
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()))
|
if (!pg_class_ownercheck(relOid, GetUserId()))
|
||||||
elog(ERROR, "%s: %s", relname,
|
elog(ERROR, "%s: %s", rel->relname,
|
||||||
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
|
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
|
||||||
|
|
||||||
if (noCatalogs)
|
if (noCatalogs)
|
||||||
{
|
{
|
||||||
if (!allowSystemTableMods && IsSystemRelationName(relname))
|
if (!allowSystemTableMods && IsSystemRelationName(rel->relname))
|
||||||
elog(ERROR, "relation \"%s\" is a system catalog",
|
elog(ERROR, "relation \"%s\" is a system catalog",
|
||||||
relname);
|
rel->relname);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
@ -251,47 +258,52 @@ ProcessUtility(Node *parsetree,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_CreateStmt:
|
case T_CreateStmt:
|
||||||
DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
|
{
|
||||||
|
Oid relOid;
|
||||||
|
|
||||||
/*
|
relOid = DefineRelation((CreateStmt *) parsetree,
|
||||||
* Let AlterTableCreateToastTable decide if this one needs a
|
RELKIND_RELATION);
|
||||||
* secondary relation too.
|
|
||||||
*/
|
/*
|
||||||
CommandCounterIncrement();
|
* Let AlterTableCreateToastTable decide if this one needs a
|
||||||
AlterTableCreateToastTable(((CreateStmt *) parsetree)->relation->relname,
|
* secondary relation too.
|
||||||
true);
|
*/
|
||||||
|
CommandCounterIncrement();
|
||||||
|
AlterTableCreateToastTable(relOid, true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_DropStmt:
|
case T_DropStmt:
|
||||||
{
|
{
|
||||||
DropStmt *stmt = (DropStmt *) parsetree;
|
DropStmt *stmt = (DropStmt *) parsetree;
|
||||||
List *args = stmt->objects;
|
|
||||||
List *arg;
|
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)
|
switch (stmt->removeType)
|
||||||
{
|
{
|
||||||
case DROP_TABLE:
|
case DROP_TABLE:
|
||||||
CheckDropPermissions(relname, RELKIND_RELATION);
|
CheckDropPermissions(rel, RELKIND_RELATION);
|
||||||
RemoveRelation(relname);
|
RemoveRelation(relname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DROP_SEQUENCE:
|
case DROP_SEQUENCE:
|
||||||
CheckDropPermissions(relname, RELKIND_SEQUENCE);
|
CheckDropPermissions(rel, RELKIND_SEQUENCE);
|
||||||
RemoveRelation(relname);
|
RemoveRelation(relname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DROP_VIEW:
|
case DROP_VIEW:
|
||||||
CheckDropPermissions(relname, RELKIND_VIEW);
|
CheckDropPermissions(rel, RELKIND_VIEW);
|
||||||
RemoveView(relname);
|
RemoveView(relname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DROP_INDEX:
|
case DROP_INDEX:
|
||||||
CheckDropPermissions(relname, RELKIND_INDEX);
|
CheckDropPermissions(rel, RELKIND_INDEX);
|
||||||
RemoveIndex(relname);
|
RemoveIndex(rel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DROP_RULE:
|
case DROP_RULE:
|
||||||
@ -329,13 +341,12 @@ ProcessUtility(Node *parsetree,
|
|||||||
|
|
||||||
case T_CommentStmt:
|
case T_CommentStmt:
|
||||||
{
|
{
|
||||||
CommentStmt *statement;
|
CommentStmt *stmt;
|
||||||
|
|
||||||
statement = ((CommentStmt *) parsetree);
|
stmt = ((CommentStmt *) parsetree);
|
||||||
|
|
||||||
CommentObject(statement->objtype, statement->objname,
|
CommentObject(stmt->objtype, stmt->objschema, stmt->objname,
|
||||||
statement->objproperty, statement->objlist,
|
stmt->objproperty, stmt->objlist, stmt->comment);
|
||||||
statement->comment);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -370,7 +381,7 @@ ProcessUtility(Node *parsetree,
|
|||||||
RenameStmt *stmt = (RenameStmt *) parsetree;
|
RenameStmt *stmt = (RenameStmt *) parsetree;
|
||||||
|
|
||||||
relname = stmt->relation->relname;
|
relname = stmt->relation->relname;
|
||||||
CheckOwnership(relname, true);
|
CheckOwnership(stmt->relation, true);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* XXX using len == 3 to tell the difference
|
* XXX using len == 3 to tell the difference
|
||||||
@ -389,7 +400,7 @@ ProcessUtility(Node *parsetree,
|
|||||||
* Note: we also rename the "type" tuple corresponding to
|
* Note: we also rename the "type" tuple corresponding to
|
||||||
* the relation.
|
* the relation.
|
||||||
*/
|
*/
|
||||||
renamerel(relname, /* old name */
|
renamerel(stmt->relation, /* old relation */
|
||||||
stmt->newname); /* new name */
|
stmt->newname); /* new name */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -454,11 +465,11 @@ ProcessUtility(Node *parsetree,
|
|||||||
stmt->behavior);
|
stmt->behavior);
|
||||||
break;
|
break;
|
||||||
case 'E': /* CREATE TOAST TABLE */
|
case 'E': /* CREATE TOAST TABLE */
|
||||||
AlterTableCreateToastTable(stmt->relation->relname,
|
AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false),
|
||||||
false);
|
false);
|
||||||
break;
|
break;
|
||||||
case 'U': /* ALTER OWNER */
|
case 'U': /* ALTER OWNER */
|
||||||
AlterTableOwner(stmt->relation->relname,
|
AlterTableOwner(stmt->relation,
|
||||||
stmt->name);
|
stmt->name);
|
||||||
break;
|
break;
|
||||||
default: /* oops */
|
default: /* oops */
|
||||||
@ -519,10 +530,9 @@ ProcessUtility(Node *parsetree,
|
|||||||
{
|
{
|
||||||
IndexStmt *stmt = (IndexStmt *) parsetree;
|
IndexStmt *stmt = (IndexStmt *) parsetree;
|
||||||
|
|
||||||
relname = stmt->relation->relname;
|
CheckOwnership(stmt->relation, true);
|
||||||
CheckOwnership(relname, true);
|
|
||||||
|
|
||||||
DefineIndex(stmt->relation->relname, /* relation */
|
DefineIndex(stmt->relation, /* relation */
|
||||||
stmt->idxname, /* index name */
|
stmt->idxname, /* index name */
|
||||||
stmt->accessMethod, /* am name */
|
stmt->accessMethod, /* am name */
|
||||||
stmt->indexParams, /* parameters */
|
stmt->indexParams, /* parameters */
|
||||||
@ -638,10 +648,9 @@ ProcessUtility(Node *parsetree,
|
|||||||
{
|
{
|
||||||
ClusterStmt *stmt = (ClusterStmt *) parsetree;
|
ClusterStmt *stmt = (ClusterStmt *) parsetree;
|
||||||
|
|
||||||
relname = stmt->relation->relname;
|
CheckOwnership(stmt->relation, true);
|
||||||
CheckOwnership(relname, true);
|
|
||||||
|
|
||||||
cluster(relname, stmt->indexname);
|
cluster(stmt->relation, stmt->indexname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -775,13 +784,12 @@ ProcessUtility(Node *parsetree,
|
|||||||
elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options",
|
elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options",
|
||||||
relname);
|
relname);
|
||||||
}
|
}
|
||||||
CheckOwnership(relname, false);
|
CheckOwnership(stmt->relation, false);
|
||||||
ReindexIndex(relname, stmt->force);
|
ReindexIndex(stmt->relation, stmt->force);
|
||||||
break;
|
break;
|
||||||
case TABLE:
|
case TABLE:
|
||||||
relname = (char *) stmt->relation->relname;
|
CheckOwnership(stmt->relation, false);
|
||||||
CheckOwnership(relname, false);
|
ReindexTable(stmt->relation, stmt->force);
|
||||||
ReindexTable(relname, stmt->force);
|
|
||||||
break;
|
break;
|
||||||
case DATABASE:
|
case DATABASE:
|
||||||
relname = (char *) stmt->name;
|
relname = (char *) stmt->name;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 "access/heapam.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_shadow.h"
|
#include "catalog/pg_shadow.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "lib/stringinfo.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
|
* has_table_privilege_name_name
|
||||||
* Check user privileges on a relation given
|
* Check user privileges on a relation given
|
||||||
* name usename, name relname, and text priv name.
|
* name username, name relname, and text priv name.
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* a boolean value
|
* a boolean value
|
||||||
@ -995,7 +996,8 @@ has_table_privilege_cname_id(char *username, Oid reloid,
|
|||||||
text *priv_type_text)
|
text *priv_type_text)
|
||||||
{
|
{
|
||||||
int32 usesysid;
|
int32 usesysid;
|
||||||
char *relname;
|
AclMode mode;
|
||||||
|
int32 result;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup userid based on username
|
* Lookup userid based on username
|
||||||
@ -1003,18 +1005,19 @@ has_table_privilege_cname_id(char *username, Oid reloid,
|
|||||||
usesysid = get_usesysid(username);
|
usesysid = get_usesysid(username);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup relname based on rel oid
|
* Convert priv_type_text to an AclMode
|
||||||
*/
|
*/
|
||||||
relname = get_rel_name(reloid);
|
mode = convert_priv_string(priv_type_text);
|
||||||
if (relname == NULL)
|
|
||||||
elog(ERROR, "has_table_privilege: invalid relation oid %u",
|
|
||||||
reloid);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make use of has_table_privilege_id_cname. It accepts the arguments
|
* Finally, check for the privilege
|
||||||
* we now have.
|
|
||||||
*/
|
*/
|
||||||
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.
|
* Convert relname to rel OID.
|
||||||
*/
|
*/
|
||||||
reloid = GetSysCacheOid(RELNAME,
|
reloid = RelnameGetRelid(relname);
|
||||||
PointerGetDatum(relname),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!OidIsValid(reloid))
|
if (!OidIsValid(reloid))
|
||||||
elog(ERROR, "has_table_privilege: relation \"%s\" does not exist",
|
elog(ERROR, "has_table_privilege: relation \"%s\" does not exist",
|
||||||
relname);
|
relname);
|
||||||
|
8
src/backend/utils/cache/catcache.c
vendored
8
src/backend/utils/cache/catcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 *
|
CatCache *
|
||||||
InitCatCache(int id,
|
InitCatCache(int id,
|
||||||
char *relname,
|
const char *relname,
|
||||||
char *indname,
|
const char *indname,
|
||||||
int reloidattr,
|
int reloidattr,
|
||||||
int nkeys,
|
int nkeys,
|
||||||
int *key)
|
const int *key)
|
||||||
{
|
{
|
||||||
CatCache *cp;
|
CatCache *cp;
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
|
23
src/backend/utils/cache/lsyscache.c
vendored
23
src/backend/utils/cache/lsyscache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
@ -634,6 +634,21 @@ func_iscachable(Oid funcid)
|
|||||||
|
|
||||||
/* ---------- RELATION CACHE ---------- */
|
/* ---------- 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
|
#ifdef NOT_USED
|
||||||
/*
|
/*
|
||||||
* get_relnatts
|
* get_relnatts
|
||||||
@ -664,10 +679,12 @@ get_relnatts(Oid relid)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* get_rel_name
|
* get_rel_name
|
||||||
*
|
|
||||||
* Returns the name of a given relation.
|
* 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 *
|
char *
|
||||||
get_rel_name(Oid relid)
|
get_rel_name(Oid relid)
|
||||||
|
238
src/backend/utils/cache/relcache.c
vendored
238
src/backend/utils/cache/relcache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
* RelationCacheInitialize - initialize relcache
|
* RelationCacheInitialize - initialize relcache
|
||||||
* RelationCacheInitializePhase2 - finish initializing 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
|
* 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
|
* RelationClose - close an open relation
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
@ -39,13 +38,13 @@
|
|||||||
#include "access/istrat.h"
|
#include "access/istrat.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/index.h"
|
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/pg_amop.h"
|
#include "catalog/pg_amop.h"
|
||||||
#include "catalog/pg_amproc.h"
|
#include "catalog/pg_amproc.h"
|
||||||
#include "catalog/pg_attrdef.h"
|
#include "catalog/pg_attrdef.h"
|
||||||
#include "catalog/pg_attribute.h"
|
#include "catalog/pg_attribute.h"
|
||||||
#include "catalog/pg_index.h"
|
#include "catalog/pg_index.h"
|
||||||
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_relcheck.h"
|
#include "catalog/pg_relcheck.h"
|
||||||
@ -70,7 +69,7 @@
|
|||||||
#define RELCACHE_INIT_FILENAME "pg_internal.init"
|
#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_class[Natts_pg_class] = {Schema_pg_class};
|
||||||
static FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
|
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
|
* 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.
|
* 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 *RelationIdCache;
|
||||||
|
static HTAB *RelationSysNameCache;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bufmgr uses RelFileNode for lookup. Actually, I would like to do
|
* 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
|
* RelationBuildDescInfo exists so code can be shared
|
||||||
* between RelationIdGetRelation() and RelationNameGetRelation()
|
* between RelationIdGetRelation() and RelationSysNameGetRelation()
|
||||||
*/
|
*/
|
||||||
typedef struct RelationBuildDescInfo
|
typedef struct RelationBuildDescInfo
|
||||||
{
|
{
|
||||||
@ -138,22 +140,22 @@ typedef struct RelationBuildDescInfo
|
|||||||
union
|
union
|
||||||
{
|
{
|
||||||
Oid info_id; /* relation object id */
|
Oid info_id; /* relation object id */
|
||||||
char *info_name; /* relation name */
|
char *info_name; /* system relation name */
|
||||||
} i;
|
} i;
|
||||||
} RelationBuildDescInfo;
|
} RelationBuildDescInfo;
|
||||||
|
|
||||||
typedef struct relnamecacheent
|
|
||||||
{
|
|
||||||
NameData relname;
|
|
||||||
Relation reldesc;
|
|
||||||
} RelNameCacheEnt;
|
|
||||||
|
|
||||||
typedef struct relidcacheent
|
typedef struct relidcacheent
|
||||||
{
|
{
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
Relation reldesc;
|
Relation reldesc;
|
||||||
} RelIdCacheEnt;
|
} RelIdCacheEnt;
|
||||||
|
|
||||||
|
typedef struct relnamecacheent
|
||||||
|
{
|
||||||
|
NameData relname;
|
||||||
|
Relation reldesc;
|
||||||
|
} RelNameCacheEnt;
|
||||||
|
|
||||||
typedef struct relnodecacheent
|
typedef struct relnodecacheent
|
||||||
{
|
{
|
||||||
RelFileNode relnode;
|
RelFileNode relnode;
|
||||||
@ -165,24 +167,14 @@ typedef struct relnodecacheent
|
|||||||
*/
|
*/
|
||||||
#define RelationCacheInsert(RELATION) \
|
#define RelationCacheInsert(RELATION) \
|
||||||
do { \
|
do { \
|
||||||
RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \
|
RelIdCacheEnt *idhentry; RelNodeCacheEnt *nodentry; bool found; \
|
||||||
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; \
|
|
||||||
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
|
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
|
||||||
(void *) &(RELATION->rd_id), \
|
(void *) &(RELATION->rd_id), \
|
||||||
HASH_ENTER, \
|
HASH_ENTER, \
|
||||||
&found); \
|
&found); \
|
||||||
if (idhentry == NULL) \
|
if (idhentry == NULL) \
|
||||||
elog(ERROR, "out of memory for relation descriptor cache"); \
|
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; \
|
idhentry->reldesc = RELATION; \
|
||||||
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
|
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
|
||||||
(void *) &(RELATION->rd_node), \
|
(void *) &(RELATION->rd_node), \
|
||||||
@ -190,19 +182,21 @@ do { \
|
|||||||
&found); \
|
&found); \
|
||||||
if (nodentry == NULL) \
|
if (nodentry == NULL) \
|
||||||
elog(ERROR, "out of memory for relation descriptor cache"); \
|
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; \
|
nodentry->reldesc = RELATION; \
|
||||||
} while(0)
|
if (RelationGetNamespace(RELATION) == PG_CATALOG_NAMESPACE) \
|
||||||
|
{ \
|
||||||
#define RelationNameCacheLookup(NAME, RELATION) \
|
char *relname = RelationGetPhysicalRelationName(RELATION); \
|
||||||
do { \
|
RelNameCacheEnt *namehentry; \
|
||||||
RelNameCacheEnt *hentry; \
|
namehentry = (RelNameCacheEnt*)hash_search(RelationSysNameCache, \
|
||||||
hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
|
relname, \
|
||||||
(void *) (NAME), HASH_FIND,NULL); \
|
HASH_ENTER, \
|
||||||
if (hentry) \
|
&found); \
|
||||||
RELATION = hentry->reldesc; \
|
if (namehentry == NULL) \
|
||||||
else \
|
elog(ERROR, "out of memory for relation descriptor cache"); \
|
||||||
RELATION = NULL; \
|
/* used to give notice if found -- now just keep quiet */ \
|
||||||
|
namehentry->reldesc = RELATION; \
|
||||||
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define RelationIdCacheLookup(ID, RELATION) \
|
#define RelationIdCacheLookup(ID, RELATION) \
|
||||||
@ -216,6 +210,17 @@ do { \
|
|||||||
RELATION = NULL; \
|
RELATION = NULL; \
|
||||||
} while(0)
|
} 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) \
|
#define RelationNodeCacheLookup(NODE, RELATION) \
|
||||||
do { \
|
do { \
|
||||||
RelNodeCacheEnt *hentry; \
|
RelNodeCacheEnt *hentry; \
|
||||||
@ -229,14 +234,7 @@ do { \
|
|||||||
|
|
||||||
#define RelationCacheDelete(RELATION) \
|
#define RelationCacheDelete(RELATION) \
|
||||||
do { \
|
do { \
|
||||||
RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
|
RelIdCacheEnt *idhentry; RelNodeCacheEnt *nodentry; \
|
||||||
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."); \
|
|
||||||
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
|
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
|
||||||
(void *)&(RELATION->rd_id), \
|
(void *)&(RELATION->rd_id), \
|
||||||
HASH_REMOVE, NULL); \
|
HASH_REMOVE, NULL); \
|
||||||
@ -247,6 +245,16 @@ do { \
|
|||||||
HASH_REMOVE, NULL); \
|
HASH_REMOVE, NULL); \
|
||||||
if (nodentry == NULL) \
|
if (nodentry == NULL) \
|
||||||
elog(WARNING, "trying to delete a reldesc that does not exist."); \
|
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)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
@ -275,11 +283,11 @@ static void RelationClearRelation(Relation relation, bool rebuildIt);
|
|||||||
static void RelationReloadClassinfo(Relation relation);
|
static void RelationReloadClassinfo(Relation relation);
|
||||||
#endif /* ENABLE_REINDEX_NAILED_RELATIONS */
|
#endif /* ENABLE_REINDEX_NAILED_RELATIONS */
|
||||||
static void RelationFlushRelation(Relation relation);
|
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 bool load_relcache_init_file(void);
|
||||||
static void write_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);
|
FormData_pg_attribute *att);
|
||||||
|
|
||||||
static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo);
|
static HeapTuple ScanPgRelation(RelationBuildDescInfo buildinfo);
|
||||||
@ -303,12 +311,6 @@ static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
StrategyNumber numSupport);
|
StrategyNumber numSupport);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RelationIdGetRelation() and RelationNameGetRelation()
|
|
||||||
* support functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ScanPgRelation
|
* ScanPgRelation
|
||||||
*
|
*
|
||||||
@ -326,7 +328,8 @@ ScanPgRelation(RelationBuildDescInfo buildinfo)
|
|||||||
Relation pg_class_desc;
|
Relation pg_class_desc;
|
||||||
const char *indexRelname;
|
const char *indexRelname;
|
||||||
SysScanDesc pg_class_scan;
|
SysScanDesc pg_class_scan;
|
||||||
ScanKeyData key;
|
ScanKeyData key[2];
|
||||||
|
int nkeys;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* form a scan key
|
* form a scan key
|
||||||
@ -334,19 +337,25 @@ ScanPgRelation(RelationBuildDescInfo buildinfo)
|
|||||||
switch (buildinfo.infotype)
|
switch (buildinfo.infotype)
|
||||||
{
|
{
|
||||||
case INFO_RELID:
|
case INFO_RELID:
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
F_OIDEQ,
|
F_OIDEQ,
|
||||||
ObjectIdGetDatum(buildinfo.i.info_id));
|
ObjectIdGetDatum(buildinfo.i.info_id));
|
||||||
|
nkeys = 1;
|
||||||
indexRelname = ClassOidIndex;
|
indexRelname = ClassOidIndex;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INFO_RELNAME:
|
case INFO_RELNAME:
|
||||||
ScanKeyEntryInitialize(&key, 0,
|
ScanKeyEntryInitialize(&key[0], 0,
|
||||||
Anum_pg_class_relname,
|
Anum_pg_class_relname,
|
||||||
F_NAMEEQ,
|
F_NAMEEQ,
|
||||||
NameGetDatum(buildinfo.i.info_name));
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -363,7 +372,7 @@ ScanPgRelation(RelationBuildDescInfo buildinfo)
|
|||||||
pg_class_scan = systable_beginscan(pg_class_desc, indexRelname,
|
pg_class_scan = systable_beginscan(pg_class_desc, indexRelname,
|
||||||
criticalRelcachesBuilt,
|
criticalRelcachesBuilt,
|
||||||
SnapshotNow,
|
SnapshotNow,
|
||||||
1, &key);
|
nkeys, key);
|
||||||
|
|
||||||
pg_class_tuple = systable_getnext(pg_class_scan);
|
pg_class_tuple = systable_getnext(pg_class_scan);
|
||||||
|
|
||||||
@ -512,12 +521,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
|
|||||||
(char *) attp,
|
(char *) attp,
|
||||||
ATTRIBUTE_TUPLE_SIZE);
|
ATTRIBUTE_TUPLE_SIZE);
|
||||||
|
|
||||||
|
/* Update constraint/default info */
|
||||||
|
if (attp->attnotnull)
|
||||||
/*
|
|
||||||
* Update constraint/default info
|
|
||||||
*/
|
|
||||||
if (attp->attnotnull)
|
|
||||||
constr->has_not_null = true;
|
constr->has_not_null = true;
|
||||||
|
|
||||||
if (attp->atthasdef)
|
if (attp->atthasdef)
|
||||||
@ -1333,7 +1338,7 @@ LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
* NOTE: we assume we are already switched into CacheMemoryContext.
|
* NOTE: we assume we are already switched into CacheMemoryContext.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
formrdesc(char *relationName,
|
formrdesc(const char *relationName,
|
||||||
int natts,
|
int natts,
|
||||||
FormData_pg_attribute *att)
|
FormData_pg_attribute *att)
|
||||||
{
|
{
|
||||||
@ -1374,7 +1379,8 @@ formrdesc(char *relationName,
|
|||||||
relation->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
relation->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
||||||
MemSet(relation->rd_rel, 0, 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
|
* 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
|
static Relation
|
||||||
RelationNameCacheGetRelation(const char *relationName)
|
RelationSysNameCacheGetRelation(const char *relationName)
|
||||||
{
|
{
|
||||||
Relation rd;
|
Relation rd;
|
||||||
NameData name;
|
NameData name;
|
||||||
@ -1503,7 +1509,7 @@ RelationNameCacheGetRelation(const char *relationName)
|
|||||||
* null-padded
|
* null-padded
|
||||||
*/
|
*/
|
||||||
namestrcpy(&name, relationName);
|
namestrcpy(&name, relationName);
|
||||||
RelationNameCacheLookup(NameStr(name), rd);
|
RelationSysNameCacheLookup(NameStr(name), rd);
|
||||||
|
|
||||||
if (RelationIsValid(rd))
|
if (RelationIsValid(rd))
|
||||||
RelationIncrementReferenceCount(rd);
|
RelationIncrementReferenceCount(rd);
|
||||||
@ -1539,12 +1545,6 @@ RelationIdGetRelation(Oid relationId)
|
|||||||
Relation rd;
|
Relation rd;
|
||||||
RelationBuildDescInfo buildinfo;
|
RelationBuildDescInfo buildinfo;
|
||||||
|
|
||||||
/*
|
|
||||||
* increment access statistics
|
|
||||||
*/
|
|
||||||
IncrHeapAccessStat(local_RelationIdGetRelation);
|
|
||||||
IncrHeapAccessStat(global_RelationIdGetRelation);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* first try and get a reldesc from the cache
|
* 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
|
Relation
|
||||||
RelationNameGetRelation(const char *relationName)
|
RelationSysNameGetRelation(const char *relationName)
|
||||||
{
|
{
|
||||||
char *temprelname;
|
char *temprelname;
|
||||||
Relation rd;
|
Relation rd;
|
||||||
RelationBuildDescInfo buildinfo;
|
RelationBuildDescInfo buildinfo;
|
||||||
|
|
||||||
/*
|
|
||||||
* increment access statistics
|
|
||||||
*/
|
|
||||||
IncrHeapAccessStat(local_RelationNameGetRelation);
|
|
||||||
IncrHeapAccessStat(global_RelationNameGetRelation);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if caller is looking for a temp relation, substitute its real name;
|
* if caller is looking for a temp relation, substitute its real name;
|
||||||
* we only index temp rels by their real names.
|
* 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
|
* first try and get a reldesc from the cache
|
||||||
*/
|
*/
|
||||||
rd = RelationNameCacheGetRelation(relationName);
|
rd = RelationSysNameCacheGetRelation(relationName);
|
||||||
if (RelationIsValid(rd))
|
if (RelationIsValid(rd))
|
||||||
return rd;
|
return rd;
|
||||||
|
|
||||||
@ -1951,17 +1945,17 @@ void
|
|||||||
RelationCacheInvalidate(void)
|
RelationCacheInvalidate(void)
|
||||||
{
|
{
|
||||||
HASH_SEQ_STATUS status;
|
HASH_SEQ_STATUS status;
|
||||||
RelNameCacheEnt *namehentry;
|
RelIdCacheEnt *idhentry;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
List *rebuildList = NIL;
|
List *rebuildList = NIL;
|
||||||
List *l;
|
List *l;
|
||||||
|
|
||||||
/* Phase 1 */
|
/* 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 */
|
/* Ignore xact-local relations, since they are never SI targets */
|
||||||
if (relation->rd_myxactonly)
|
if (relation->rd_myxactonly)
|
||||||
@ -2007,13 +2001,13 @@ void
|
|||||||
RelationCacheAbort(void)
|
RelationCacheAbort(void)
|
||||||
{
|
{
|
||||||
HASH_SEQ_STATUS status;
|
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)
|
if (relation->rd_isnailed)
|
||||||
RelationSetReferenceCount(relation, 1);
|
RelationSetReferenceCount(relation, 1);
|
||||||
@ -2029,8 +2023,10 @@ RelationCacheAbort(void)
|
|||||||
*/
|
*/
|
||||||
Relation
|
Relation
|
||||||
RelationBuildLocalRelation(const char *relname,
|
RelationBuildLocalRelation(const char *relname,
|
||||||
|
Oid relnamespace,
|
||||||
TupleDesc tupDesc,
|
TupleDesc tupDesc,
|
||||||
Oid relid, Oid dbid,
|
Oid relid, Oid dbid,
|
||||||
|
RelFileNode rnode,
|
||||||
bool nailit)
|
bool nailit)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
@ -2086,7 +2082,8 @@ RelationBuildLocalRelation(const char *relname,
|
|||||||
rel->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
rel->rd_rel = (Form_pg_class) palloc(CLASS_TUPLE_SIZE);
|
||||||
MemSet((char *) rel->rd_rel, 0, 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->relkind = RELKIND_UNCATALOGED;
|
||||||
rel->rd_rel->relhasoids = true;
|
rel->rd_rel->relhasoids = true;
|
||||||
@ -2094,10 +2091,8 @@ RelationBuildLocalRelation(const char *relname,
|
|||||||
rel->rd_rel->reltype = InvalidOid;
|
rel->rd_rel->reltype = InvalidOid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert relation OID and database/tablespace ID into the right
|
* Insert relation physical and logical identifiers (OIDs) into the
|
||||||
* places. XXX currently we assume physical tblspace/relnode are same
|
* right places.
|
||||||
* as logical dbid/reloid. Probably should pass an extra pair of
|
|
||||||
* parameters.
|
|
||||||
*/
|
*/
|
||||||
rel->rd_rel->relisshared = (dbid == InvalidOid);
|
rel->rd_rel->relisshared = (dbid == InvalidOid);
|
||||||
|
|
||||||
@ -2106,11 +2101,10 @@ RelationBuildLocalRelation(const char *relname,
|
|||||||
for (i = 0; i < natts; i++)
|
for (i = 0; i < natts; i++)
|
||||||
rel->rd_att->attrs[i]->attrelid = relid;
|
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;
|
RelationInitLockInfo(rel); /* see lmgr.c */
|
||||||
rel->rd_node.relNode = relid;
|
|
||||||
rel->rd_rel->relfilenode = relid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Okay to insert into the relcache hash tables.
|
* Okay to insert into the relcache hash tables.
|
||||||
@ -2201,8 +2195,8 @@ RelationCacheInitialize(void)
|
|||||||
MemSet(&ctl, 0, sizeof(ctl));
|
MemSet(&ctl, 0, sizeof(ctl));
|
||||||
ctl.keysize = sizeof(NameData);
|
ctl.keysize = sizeof(NameData);
|
||||||
ctl.entrysize = sizeof(RelNameCacheEnt);
|
ctl.entrysize = sizeof(RelNameCacheEnt);
|
||||||
RelationNameCache = hash_create("Relcache by name", INITRELCACHESIZE,
|
RelationSysNameCache = hash_create("Relcache by name", INITRELCACHESIZE,
|
||||||
&ctl, HASH_ELEM);
|
&ctl, HASH_ELEM);
|
||||||
|
|
||||||
ctl.keysize = sizeof(Oid);
|
ctl.keysize = sizeof(Oid);
|
||||||
ctl.entrysize = sizeof(RelIdCacheEnt);
|
ctl.entrysize = sizeof(RelIdCacheEnt);
|
||||||
@ -2252,7 +2246,7 @@ void
|
|||||||
RelationCacheInitializePhase2(void)
|
RelationCacheInitializePhase2(void)
|
||||||
{
|
{
|
||||||
HASH_SEQ_STATUS status;
|
HASH_SEQ_STATUS status;
|
||||||
RelNameCacheEnt *namehentry;
|
RelIdCacheEnt *idhentry;
|
||||||
|
|
||||||
if (IsBootstrapProcessingMode())
|
if (IsBootstrapProcessingMode())
|
||||||
return;
|
return;
|
||||||
@ -2290,7 +2284,7 @@ RelationCacheInitializePhase2(void)
|
|||||||
RelationSetReferenceCount(ird, 1); \
|
RelationSetReferenceCount(ird, 1); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
LOAD_CRIT_INDEX(ClassNameIndex);
|
LOAD_CRIT_INDEX(ClassNameNspIndex);
|
||||||
LOAD_CRIT_INDEX(ClassOidIndex);
|
LOAD_CRIT_INDEX(ClassOidIndex);
|
||||||
LOAD_CRIT_INDEX(AttributeRelidNumIndex);
|
LOAD_CRIT_INDEX(AttributeRelidNumIndex);
|
||||||
LOAD_CRIT_INDEX(IndexRelidIndex);
|
LOAD_CRIT_INDEX(IndexRelidIndex);
|
||||||
@ -2311,11 +2305,11 @@ RelationCacheInitializePhase2(void)
|
|||||||
* Also, if any of the relcache entries have rules or triggers,
|
* 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.
|
* 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.
|
* If it's a faked-up entry, read the real pg_class tuple.
|
||||||
@ -2399,8 +2393,8 @@ CreateDummyCaches(void)
|
|||||||
MemSet(&ctl, 0, sizeof(ctl));
|
MemSet(&ctl, 0, sizeof(ctl));
|
||||||
ctl.keysize = sizeof(NameData);
|
ctl.keysize = sizeof(NameData);
|
||||||
ctl.entrysize = sizeof(RelNameCacheEnt);
|
ctl.entrysize = sizeof(RelNameCacheEnt);
|
||||||
RelationNameCache = hash_create("Relcache by name", INITRELCACHESIZE,
|
RelationSysNameCache = hash_create("Relcache by name", INITRELCACHESIZE,
|
||||||
&ctl, HASH_ELEM);
|
&ctl, HASH_ELEM);
|
||||||
|
|
||||||
ctl.keysize = sizeof(Oid);
|
ctl.keysize = sizeof(Oid);
|
||||||
ctl.entrysize = sizeof(RelIdCacheEnt);
|
ctl.entrysize = sizeof(RelIdCacheEnt);
|
||||||
@ -2427,14 +2421,14 @@ DestroyDummyCaches(void)
|
|||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
|
||||||
|
|
||||||
if (RelationNameCache)
|
|
||||||
hash_destroy(RelationNameCache);
|
|
||||||
if (RelationIdCache)
|
if (RelationIdCache)
|
||||||
hash_destroy(RelationIdCache);
|
hash_destroy(RelationIdCache);
|
||||||
|
if (RelationSysNameCache)
|
||||||
|
hash_destroy(RelationSysNameCache);
|
||||||
if (RelationNodeCache)
|
if (RelationNodeCache)
|
||||||
hash_destroy(RelationNodeCache);
|
hash_destroy(RelationNodeCache);
|
||||||
|
|
||||||
RelationNameCache = RelationIdCache = RelationNodeCache = NULL;
|
RelationIdCache = RelationSysNameCache = RelationNodeCache = NULL;
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcxt);
|
MemoryContextSwitchTo(oldcxt);
|
||||||
}
|
}
|
||||||
@ -3001,7 +2995,7 @@ write_relcache_init_file(void)
|
|||||||
char tempfilename[MAXPGPATH];
|
char tempfilename[MAXPGPATH];
|
||||||
char finalfilename[MAXPGPATH];
|
char finalfilename[MAXPGPATH];
|
||||||
HASH_SEQ_STATUS status;
|
HASH_SEQ_STATUS status;
|
||||||
RelNameCacheEnt *namehentry;
|
RelIdCacheEnt *idhentry;
|
||||||
MemoryContext oldcxt;
|
MemoryContext oldcxt;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -3031,13 +3025,13 @@ write_relcache_init_file(void)
|
|||||||
/*
|
/*
|
||||||
* Write all the reldescs (in no particular order).
|
* Write all the reldescs (in no particular order).
|
||||||
*/
|
*/
|
||||||
hash_seq_init(&status, RelationNameCache);
|
hash_seq_init(&status, RelationIdCache);
|
||||||
|
|
||||||
initFileRelationIds = NIL;
|
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;
|
Form_pg_class relform = rel->rd_rel;
|
||||||
Size len;
|
Size len;
|
||||||
|
|
||||||
|
18
src/backend/utils/cache/syscache.c
vendored
18
src/backend/utils/cache/syscache.c
vendored
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* These routines allow the parser/planner/executor to perform
|
* These routines allow the parser/planner/executor to perform
|
||||||
@ -86,14 +86,14 @@
|
|||||||
*/
|
*/
|
||||||
struct cachedesc
|
struct cachedesc
|
||||||
{
|
{
|
||||||
char *name; /* name of the relation being cached */
|
const char *name; /* name of the relation being cached */
|
||||||
char *indname; /* name of index relation for this cache */
|
const char *indname; /* name of index relation for this cache */
|
||||||
int reloidattr; /* attr number of rel OID reference, or 0 */
|
int reloidattr; /* attr number of rel OID reference, or 0 */
|
||||||
int nkeys; /* # of keys needed for cache lookup */
|
int nkeys; /* # of keys needed for cache lookup */
|
||||||
int key[4]; /* attribute numbers of key attrs */
|
int key[4]; /* attribute numbers of key attrs */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cachedesc cacheinfo[] = {
|
static const struct cachedesc cacheinfo[] = {
|
||||||
{AggregateRelationName, /* AGGNAME */
|
{AggregateRelationName, /* AGGNAME */
|
||||||
AggregateNameTypeIndex,
|
AggregateNameTypeIndex,
|
||||||
0,
|
0,
|
||||||
@ -324,13 +324,13 @@ static struct cachedesc cacheinfo[] = {
|
|||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
{RelationRelationName, /* RELNAME */
|
{RelationRelationName, /* RELNAMENSP */
|
||||||
ClassNameIndex,
|
ClassNameNspIndex,
|
||||||
ObjectIdAttributeNumber,
|
ObjectIdAttributeNumber,
|
||||||
1,
|
2,
|
||||||
{
|
{
|
||||||
Anum_pg_class_relname,
|
Anum_pg_class_relname,
|
||||||
0,
|
Anum_pg_class_relnamespace,
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
}},
|
}},
|
||||||
@ -515,7 +515,7 @@ SearchSysCache(int cacheId,
|
|||||||
* when sought. This is a kluge ... temp table substitution should be
|
* when sought. This is a kluge ... temp table substitution should be
|
||||||
* happening at a higher level ...
|
* happening at a higher level ...
|
||||||
*/
|
*/
|
||||||
if (cacheId == RELNAME || cacheId == TYPENAME)
|
if (cacheId == RELNAMENSP || cacheId == TYPENAME)
|
||||||
{
|
{
|
||||||
char *nontemp_relname;
|
char *nontemp_relname;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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/itup.h"
|
||||||
#include "access/relscan.h"
|
#include "access/relscan.h"
|
||||||
#include "access/sdir.h"
|
#include "access/sdir.h"
|
||||||
|
#include "nodes/primnodes.h"
|
||||||
|
|
||||||
|
|
||||||
/* Struct for statistics returned by bulk-delete operation */
|
/* Struct for statistics returned by bulk-delete operation */
|
||||||
@ -50,7 +51,8 @@ typedef SysScanDescData *SysScanDesc;
|
|||||||
* generalized index_ interface routines (in indexam.c)
|
* generalized index_ interface routines (in indexam.c)
|
||||||
*/
|
*/
|
||||||
extern Relation index_open(Oid relationId);
|
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 void index_close(Relation relation);
|
||||||
extern InsertIndexResult index_insert(Relation relation,
|
extern InsertIndexResult index_insert(Relation relation,
|
||||||
Datum *datum, char *nulls,
|
Datum *datum, char *nulls,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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/relscan.h"
|
||||||
#include "access/tupmacs.h"
|
#include "access/tupmacs.h"
|
||||||
#include "access/xlogutils.h"
|
#include "access/xlogutils.h"
|
||||||
|
#include "nodes/primnodes.h"
|
||||||
#include "storage/block.h"
|
#include "storage/block.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
@ -134,11 +135,13 @@ extern Datum heap_getsysattr(HeapTuple tup, int attnum, bool *isnull);
|
|||||||
/* heapam.c */
|
/* heapam.c */
|
||||||
|
|
||||||
extern Relation relation_open(Oid relationId, LOCKMODE lockmode);
|
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 void relation_close(Relation relation, LOCKMODE lockmode);
|
||||||
|
|
||||||
extern Relation heap_open(Oid relationId, 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)
|
#define heap_close(r,l) relation_close(r,l)
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 numattr;
|
||||||
extern int BootstrapMain(int ac, char *av[]);
|
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 err_out(void);
|
||||||
extern void InsertOneTuple(Oid objectid);
|
extern void InsertOneTuple(Oid objectid);
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200203221
|
#define CATALOG_VERSION_NO 200203251
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 "parser/parse_node.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct RawColumnDefault
|
typedef struct RawColumnDefault
|
||||||
{
|
{
|
||||||
AttrNumber attnum; /* attribute to attach default to */
|
AttrNumber attnum; /* attribute to attach default to */
|
||||||
@ -26,15 +27,15 @@ typedef struct RawColumnDefault
|
|||||||
* tree) */
|
* tree) */
|
||||||
} RawColumnDefault;
|
} RawColumnDefault;
|
||||||
|
|
||||||
extern Oid RelnameFindRelid(const char *relname);
|
extern Relation heap_create(char *relname, Oid relnamespace,
|
||||||
|
TupleDesc tupDesc,
|
||||||
extern Relation heap_create(char *relname, TupleDesc tupDesc,
|
|
||||||
bool istemp, bool storage_create,
|
bool istemp, bool storage_create,
|
||||||
bool allow_system_table_mods);
|
bool allow_system_table_mods);
|
||||||
|
|
||||||
extern void heap_storage_create(Relation rel);
|
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,
|
char relkind, bool relhasoids, bool istemp,
|
||||||
bool allow_system_table_mods);
|
bool allow_system_table_mods);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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);
|
void *state);
|
||||||
|
|
||||||
|
|
||||||
extern Oid index_create(char *heapRelationName,
|
extern Oid index_create(Oid heapRelationId,
|
||||||
char *indexRelationName,
|
char *indexRelationName,
|
||||||
IndexInfo *indexInfo,
|
IndexInfo *indexInfo,
|
||||||
Oid accessMethodObjectId,
|
Oid accessMethodObjectId,
|
||||||
Oid *classObjectId,
|
Oid *classObjectId,
|
||||||
|
bool istemp,
|
||||||
bool primary,
|
bool primary,
|
||||||
bool allow_system_table_mods);
|
bool allow_system_table_mods);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 AttrDefaultIndex "pg_attrdef_adrelid_adnum_index"
|
||||||
#define AttributeRelidNameIndex "pg_attribute_relid_attnam_index"
|
#define AttributeRelidNameIndex "pg_attribute_relid_attnam_index"
|
||||||
#define AttributeRelidNumIndex "pg_attribute_relid_attnum_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 ClassOidIndex "pg_class_oid_index"
|
||||||
#define DatabaseNameIndex "pg_database_datname_index"
|
#define DatabaseNameIndex "pg_database_datname_index"
|
||||||
#define DatabaseOidIndex "pg_database_oid_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_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_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_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_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_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));
|
DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops));
|
||||||
|
26
src/include/catalog/namespace.h
Normal file
26
src/include/catalog/namespace.h
Normal file
@ -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 */
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* 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 \
|
#define Schema_pg_class \
|
||||||
{ 1259, {"relname"}, 19, DEFAULT_ATTSTATTARGET, NAMEDATALEN, 1, 0, -1, -1, false, 'p', false, 'i', false, false }, \
|
{ 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, {"relnamespace"}, 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, {"reltype"}, 26, 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, {"relowner"}, 23, 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, {"relam"}, 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, {"relfilenode"}, 26, 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, {"relpages"}, 23, 0, 4, 7, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1259, {"reltoastrelid"}, 26, 0, 4, 8, 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, {"reltoastidxid"}, 26, 0, 4, 9, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
{ 1259, {"reltoastrelid"}, 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, {"reltoastidxid"}, 26, 0, 4, 10, 0, -1, -1, true, 'p', false, 'i', false, false }, \
|
||||||
{ 1259, {"relisshared"}, 16, 0, 1, 11, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1259, {"relhasindex"}, 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, {"relisshared"}, 16, 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, {"relkind"}, 18, 0, 1, 13, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
||||||
{ 1259, {"relchecks"}, 21, 0, 2, 14, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
{ 1259, {"relnatts"}, 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, {"relchecks"}, 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, {"reltriggers"}, 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, {"relukeys"}, 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, {"relfkeys"}, 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, {"relrefs"}, 21, 0, 2, 19, 0, -1, -1, true, 'p', false, 's', false, false }, \
|
||||||
{ 1259, {"relhaspkey"}, 16, 0, 1, 20, 0, -1, -1, true, 'p', false, 'c', false, false }, \
|
{ 1259, {"relhasoids"}, 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, {"relhaspkey"}, 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, {"relhasrules"}, 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, {"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 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 relnamespace 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 reltype 26 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 relowner 23 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 relam 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 relfilenode 26 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 relpages 23 0 4 7 0 -1 -1 t 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 reltuples 700 0 4 8 0 -1 -1 f 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 reltoastrelid 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 reltoastidxid 26 0 4 10 0 -1 -1 t p f i f f));
|
||||||
DATA(insert ( 1259 relisshared 16 0 1 11 0 -1 -1 t p f c f f));
|
DATA(insert ( 1259 relhasindex 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 relisshared 16 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 relkind 18 0 1 13 0 -1 -1 t p f c f f));
|
||||||
DATA(insert ( 1259 relchecks 21 0 2 14 0 -1 -1 t p f s f f));
|
DATA(insert ( 1259 relnatts 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 relchecks 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 reltriggers 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 relukeys 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 relfkeys 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 relrefs 21 0 2 19 0 -1 -1 t p f s f f));
|
||||||
DATA(insert ( 1259 relhaspkey 16 0 1 20 0 -1 -1 t p f c f f));
|
DATA(insert ( 1259 relhasoids 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 relhaspkey 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 relhasrules 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 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 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 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));
|
DATA(insert ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -43,6 +43,7 @@
|
|||||||
CATALOG(pg_class) BOOTSTRAP
|
CATALOG(pg_class) BOOTSTRAP
|
||||||
{
|
{
|
||||||
NameData relname; /* class name */
|
NameData relname; /* class name */
|
||||||
|
Oid relnamespace; /* OID of namespace containing this class */
|
||||||
Oid reltype; /* OID of associated entry in pg_type */
|
Oid reltype; /* OID of associated entry in pg_type */
|
||||||
int4 relowner; /* class owner */
|
int4 relowner; /* class owner */
|
||||||
Oid relam; /* index access method; 0 if not an index */
|
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.
|
* relacl field. This is a kluge.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
#define Natts_pg_class_fixed 22
|
#define Natts_pg_class_fixed 23
|
||||||
#define Natts_pg_class 23
|
#define Natts_pg_class 24
|
||||||
#define Anum_pg_class_relname 1
|
#define Anum_pg_class_relname 1
|
||||||
#define Anum_pg_class_reltype 2
|
#define Anum_pg_class_relnamespace 2
|
||||||
#define Anum_pg_class_relowner 3
|
#define Anum_pg_class_reltype 3
|
||||||
#define Anum_pg_class_relam 4
|
#define Anum_pg_class_relowner 4
|
||||||
#define Anum_pg_class_relfilenode 5
|
#define Anum_pg_class_relam 5
|
||||||
#define Anum_pg_class_relpages 6
|
#define Anum_pg_class_relfilenode 6
|
||||||
#define Anum_pg_class_reltuples 7
|
#define Anum_pg_class_relpages 7
|
||||||
#define Anum_pg_class_reltoastrelid 8
|
#define Anum_pg_class_reltuples 8
|
||||||
#define Anum_pg_class_reltoastidxid 9
|
#define Anum_pg_class_reltoastrelid 9
|
||||||
#define Anum_pg_class_relhasindex 10
|
#define Anum_pg_class_reltoastidxid 10
|
||||||
#define Anum_pg_class_relisshared 11
|
#define Anum_pg_class_relhasindex 11
|
||||||
#define Anum_pg_class_relkind 12
|
#define Anum_pg_class_relisshared 12
|
||||||
#define Anum_pg_class_relnatts 13
|
#define Anum_pg_class_relkind 13
|
||||||
#define Anum_pg_class_relchecks 14
|
#define Anum_pg_class_relnatts 14
|
||||||
#define Anum_pg_class_reltriggers 15
|
#define Anum_pg_class_relchecks 15
|
||||||
#define Anum_pg_class_relukeys 16
|
#define Anum_pg_class_reltriggers 16
|
||||||
#define Anum_pg_class_relfkeys 17
|
#define Anum_pg_class_relukeys 17
|
||||||
#define Anum_pg_class_relrefs 18
|
#define Anum_pg_class_relfkeys 18
|
||||||
#define Anum_pg_class_relhasoids 19
|
#define Anum_pg_class_relrefs 19
|
||||||
#define Anum_pg_class_relhaspkey 20
|
#define Anum_pg_class_relhasoids 20
|
||||||
#define Anum_pg_class_relhasrules 21
|
#define Anum_pg_class_relhaspkey 21
|
||||||
#define Anum_pg_class_relhassubclass 22
|
#define Anum_pg_class_relhasrules 22
|
||||||
#define Anum_pg_class_relacl 23
|
#define Anum_pg_class_relhassubclass 23
|
||||||
|
#define Anum_pg_class_relacl 24
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initial contents of pg_class
|
* 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("");
|
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("");
|
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("");
|
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("");
|
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("");
|
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("");
|
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("");
|
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("");
|
DESCR("");
|
||||||
|
|
||||||
#define RelOid_pg_type 1247
|
#define RelOid_pg_type 1247
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* 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
|
* functions
|
||||||
*/
|
*/
|
||||||
extern void cluster(char *oldrelname, char *oldindexname);
|
extern void cluster(RangeVar *oldrelation, char *oldindexname);
|
||||||
|
|
||||||
#endif /* CLUSTER_H */
|
#endif /* CLUSTER_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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,
|
bool inh, const char *constrName,
|
||||||
int behavior);
|
int behavior);
|
||||||
|
|
||||||
extern void AlterTableCreateToastTable(const char *relationName,
|
extern void AlterTableCreateToastTable(Oid relOid, bool silent);
|
||||||
bool silent);
|
|
||||||
|
|
||||||
extern void AlterTableOwner(const char *relationName, const char *newOwnerName);
|
extern void AlterTableOwner(const RangeVar *tgtrel, const char *newOwnerName);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LOCK
|
* LOCK
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
*------------------------------------------------------------------
|
*------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void CommentObject(int objtype, char *objname, char *objproperty,
|
extern void CommentObject(int objtype, char * schemaname, char *objname,
|
||||||
List *objlist, char *comment);
|
char *objproperty, List *objlist, char *comment);
|
||||||
|
|
||||||
extern void DeleteComments(Oid oid, Oid classoid);
|
extern void DeleteComments(Oid oid, Oid classoid);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* prototypes in indexcmds.c
|
||||||
*/
|
*/
|
||||||
extern void DefineIndex(char *heapRelationName,
|
extern void DefineIndex(RangeVar *heapRelation,
|
||||||
char *indexRelationName,
|
char *indexRelationName,
|
||||||
char *accessMethodName,
|
char *accessMethodName,
|
||||||
List *attributeList,
|
List *attributeList,
|
||||||
@ -27,9 +27,9 @@ extern void DefineIndex(char *heapRelationName,
|
|||||||
bool primary,
|
bool primary,
|
||||||
Expr *predicate,
|
Expr *predicate,
|
||||||
List *rangetable);
|
List *rangetable);
|
||||||
extern void RemoveIndex(char *name);
|
extern void RemoveIndex(RangeVar *relation);
|
||||||
extern void ReindexIndex(const char *indexRelationName, bool force);
|
extern void ReindexIndex(RangeVar *indexRelation, bool force);
|
||||||
extern void ReindexTable(const char *relationName, bool force);
|
extern void ReindexTable(RangeVar *relation, bool force);
|
||||||
extern void ReindexDatabase(const char *databaseName, bool force, bool all);
|
extern void ReindexDatabase(const char *databaseName, bool force, bool all);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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,
|
char *newattname,
|
||||||
int recurse);
|
int recurse);
|
||||||
|
|
||||||
extern void renamerel(const char *oldrelname,
|
extern void renamerel(const RangeVar *relation,
|
||||||
const char *newrelname);
|
const char *newrelname);
|
||||||
|
|
||||||
#endif /* RENAME_H */
|
#endif /* RENAME_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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"
|
#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
|
* Query Tree
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -49,7 +41,7 @@ typedef struct Query
|
|||||||
* statement */
|
* statement */
|
||||||
|
|
||||||
int resultRelation; /* target relation (index into rtable) */
|
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 */
|
* for portal just name is meaningful */
|
||||||
bool isPortal; /* is this a retrieve into portal? */
|
bool isPortal; /* is this a retrieve into portal? */
|
||||||
bool isBinary; /* binary portal? */
|
bool isBinary; /* binary portal? */
|
||||||
@ -368,39 +360,6 @@ typedef struct SortGroupBy
|
|||||||
Node *node; /* Expression */
|
Node *node; /* Expression */
|
||||||
} SortGroupBy;
|
} 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
|
* RangeSubselect - subquery appearing in a FROM clause
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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;
|
} 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
|
* node types for executable expressions
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
@ -527,7 +568,7 @@ typedef struct JoinExpr
|
|||||||
Node *rarg; /* right subtree */
|
Node *rarg; /* right subtree */
|
||||||
List *using; /* USING clause, if any (list of String) */
|
List *using; /* USING clause, if any (list of String) */
|
||||||
Node *quals; /* qualifiers on join, if any */
|
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 */
|
int rtindex; /* RT index assigned for join */
|
||||||
} JoinExpr;
|
} JoinExpr;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 */
|
int id; /* cache identifier --- see syscache.h */
|
||||||
struct catcache *cc_next; /* link to next catcache */
|
struct catcache *cc_next; /* link to next catcache */
|
||||||
char *cc_relname; /* name of relation the tuples come from */
|
const char *cc_relname; /* name of relation the tuples come from */
|
||||||
char *cc_indname; /* name of index matching cache keys */
|
const char *cc_indname; /* name of index matching cache keys */
|
||||||
Oid cc_reloid; /* OID of relation the tuples come from */
|
Oid cc_reloid; /* OID of relation the tuples come from */
|
||||||
bool cc_relisshared; /* is relation shared? */
|
bool cc_relisshared; /* is relation shared? */
|
||||||
TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */
|
TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */
|
||||||
@ -107,9 +107,9 @@ extern MemoryContext CacheMemoryContext;
|
|||||||
extern void CreateCacheMemoryContext(void);
|
extern void CreateCacheMemoryContext(void);
|
||||||
extern void AtEOXact_CatCache(bool isCommit);
|
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 reloidattr,
|
||||||
int nkeys, int *key);
|
int nkeys, const int *key);
|
||||||
extern void InitCatCachePhase2(CatCache *cache);
|
extern void InitCatCachePhase2(CatCache *cache);
|
||||||
|
|
||||||
extern HeapTuple SearchCatCache(CatCache *cache,
|
extern HeapTuple SearchCatCache(CatCache *cache,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 RegProcedure get_oprjoin(Oid opno);
|
||||||
extern Oid get_func_rettype(Oid funcid);
|
extern Oid get_func_rettype(Oid funcid);
|
||||||
extern bool func_iscachable(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 char *get_rel_name(Oid relid);
|
||||||
extern Oid get_rel_type_id(Oid relid);
|
extern Oid get_rel_type_id(Oid relid);
|
||||||
extern int16 get_typlen(Oid typid);
|
extern int16 get_typlen(Oid typid);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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) \
|
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 */
|
/* added to prevent circular dependency. bjm 1999/11/15 */
|
||||||
extern char *get_temp_rel_by_physicalname(const char *relname);
|
extern char *get_temp_rel_by_physicalname(const char *relname);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* relation lookup routines
|
||||||
*/
|
*/
|
||||||
extern Relation RelationIdGetRelation(Oid relationId);
|
extern Relation RelationIdGetRelation(Oid relationId);
|
||||||
extern Relation RelationNameGetRelation(const char *relationName);
|
extern Relation RelationSysNameGetRelation(const char *relationName);
|
||||||
extern Relation RelationNodeCacheGetRelation(RelFileNode rnode);
|
|
||||||
|
|
||||||
/* finds an existing cache entry, but won't make a new one */
|
/* finds an existing cache entry, but won't make a new one */
|
||||||
extern Relation RelationIdCacheGetRelation(Oid relationId);
|
extern Relation RelationIdCacheGetRelation(Oid relationId);
|
||||||
|
extern Relation RelationNodeCacheGetRelation(RelFileNode rnode);
|
||||||
|
|
||||||
extern void RelationClose(Relation relation);
|
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
|
* Routine to create a relcache entry for an about-to-be-created relation
|
||||||
*/
|
*/
|
||||||
extern Relation RelationBuildLocalRelation(const char *relname,
|
extern Relation RelationBuildLocalRelation(const char *relname,
|
||||||
|
Oid relnamespace,
|
||||||
TupleDesc tupDesc,
|
TupleDesc tupDesc,
|
||||||
Oid relid, Oid dbid,
|
Oid relid, Oid dbid,
|
||||||
|
RelFileNode rnode,
|
||||||
bool nailit);
|
bool nailit);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 OPEROID 20
|
||||||
#define PROCNAME 21
|
#define PROCNAME 21
|
||||||
#define PROCOID 22
|
#define PROCOID 22
|
||||||
#define RELNAME 23
|
#define RELNAMENSP 23
|
||||||
#define RELOID 24
|
#define RELOID 24
|
||||||
#define RULENAME 25
|
#define RULENAME 25
|
||||||
#define SHADOWNAME 26
|
#define SHADOWNAME 26
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* procedural language
|
* procedural language
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "catalog/pg_class.h"
|
#include "catalog/pg_class.h"
|
||||||
@ -941,6 +942,7 @@ plpgsql_parse_dblwordtype(char *string)
|
|||||||
char *word2;
|
char *word2;
|
||||||
PLpgSQL_nsitem *nse;
|
PLpgSQL_nsitem *nse;
|
||||||
bool old_nsstate;
|
bool old_nsstate;
|
||||||
|
Oid classOid;
|
||||||
HeapTuple classtup;
|
HeapTuple classtup;
|
||||||
Form_pg_class classStruct;
|
Form_pg_class classStruct;
|
||||||
HeapTuple attrtup;
|
HeapTuple attrtup;
|
||||||
@ -998,8 +1000,14 @@ plpgsql_parse_dblwordtype(char *string)
|
|||||||
/*
|
/*
|
||||||
* First word could also be a table name
|
* First word could also be a table name
|
||||||
*/
|
*/
|
||||||
classtup = SearchSysCache(RELNAME,
|
classOid = RelnameGetRelid(word1);
|
||||||
PointerGetDatum(word1),
|
if (!OidIsValid(classOid))
|
||||||
|
{
|
||||||
|
pfree(word1);
|
||||||
|
return T_ERROR;
|
||||||
|
}
|
||||||
|
classtup = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(classOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(classtup))
|
if (!HeapTupleIsValid(classtup))
|
||||||
{
|
{
|
||||||
@ -1024,7 +1032,7 @@ plpgsql_parse_dblwordtype(char *string)
|
|||||||
* Fetch the named table field and it's type
|
* Fetch the named table field and it's type
|
||||||
*/
|
*/
|
||||||
attrtup = SearchSysCache(ATTNAME,
|
attrtup = SearchSysCache(ATTNAME,
|
||||||
ObjectIdGetDatum(classtup->t_data->t_oid),
|
ObjectIdGetDatum(classOid),
|
||||||
PointerGetDatum(word2),
|
PointerGetDatum(word2),
|
||||||
0, 0);
|
0, 0);
|
||||||
if (!HeapTupleIsValid(attrtup))
|
if (!HeapTupleIsValid(attrtup))
|
||||||
@ -1049,7 +1057,7 @@ plpgsql_parse_dblwordtype(char *string)
|
|||||||
typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
|
typ = (PLpgSQL_type *) malloc(sizeof(PLpgSQL_type));
|
||||||
|
|
||||||
typ->typname = strdup(NameStr(typeStruct->typname));
|
typ->typname = strdup(NameStr(typeStruct->typname));
|
||||||
typ->typoid = typetup->t_data->t_oid;
|
typ->typoid = attrStruct->atttypid;
|
||||||
perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
|
perm_fmgr_info(typeStruct->typinput, &(typ->typinput));
|
||||||
typ->typelem = typeStruct->typelem;
|
typ->typelem = typeStruct->typelem;
|
||||||
typ->typbyval = typeStruct->typbyval;
|
typ->typbyval = typeStruct->typbyval;
|
||||||
@ -1074,6 +1082,7 @@ plpgsql_parse_dblwordtype(char *string)
|
|||||||
int
|
int
|
||||||
plpgsql_parse_wordrowtype(char *string)
|
plpgsql_parse_wordrowtype(char *string)
|
||||||
{
|
{
|
||||||
|
Oid classOid;
|
||||||
HeapTuple classtup;
|
HeapTuple classtup;
|
||||||
Form_pg_class classStruct;
|
Form_pg_class classStruct;
|
||||||
HeapTuple typetup;
|
HeapTuple typetup;
|
||||||
@ -1093,8 +1102,11 @@ plpgsql_parse_wordrowtype(char *string)
|
|||||||
cp = strchr(word1, '%');
|
cp = strchr(word1, '%');
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
classtup = SearchSysCache(RELNAME,
|
classOid = RelnameGetRelid(word1);
|
||||||
PointerGetDatum(word1),
|
if (!OidIsValid(classOid))
|
||||||
|
elog(ERROR, "%s: no such class", word1);
|
||||||
|
classtup = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(classOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(classtup))
|
if (!HeapTupleIsValid(classtup))
|
||||||
elog(ERROR, "%s: no such class", word1);
|
elog(ERROR, "%s: no such class", word1);
|
||||||
@ -1105,15 +1117,6 @@ plpgsql_parse_wordrowtype(char *string)
|
|||||||
classStruct->relkind != RELKIND_VIEW)
|
classStruct->relkind != RELKIND_VIEW)
|
||||||
elog(ERROR, "%s isn't a table", word1);
|
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
|
* Create a row datum entry and all the required variables that it
|
||||||
* will point to.
|
* will point to.
|
||||||
@ -1123,19 +1126,17 @@ plpgsql_parse_wordrowtype(char *string)
|
|||||||
|
|
||||||
row->dtype = PLPGSQL_DTYPE_ROW;
|
row->dtype = PLPGSQL_DTYPE_ROW;
|
||||||
row->nfields = classStruct->relnatts;
|
row->nfields = classStruct->relnatts;
|
||||||
row->rowtypeclass = typetup->t_data->t_oid;
|
row->rowtypeclass = classStruct->reltype;
|
||||||
row->fieldnames = malloc(sizeof(char *) * row->nfields);
|
row->fieldnames = malloc(sizeof(char *) * row->nfields);
|
||||||
row->varnos = malloc(sizeof(int) * row->nfields);
|
row->varnos = malloc(sizeof(int) * row->nfields);
|
||||||
|
|
||||||
ReleaseSysCache(typetup);
|
|
||||||
|
|
||||||
for (i = 0; i < row->nfields; i++)
|
for (i = 0; i < row->nfields; i++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Get the attribute and it's type
|
* Get the attribute and it's type
|
||||||
*/
|
*/
|
||||||
attrtup = SearchSysCache(ATTNUM,
|
attrtup = SearchSysCache(ATTNUM,
|
||||||
ObjectIdGetDatum(classtup->t_data->t_oid),
|
ObjectIdGetDatum(classOid),
|
||||||
Int16GetDatum(i + 1),
|
Int16GetDatum(i + 1),
|
||||||
0, 0);
|
0, 0);
|
||||||
if (!HeapTupleIsValid(attrtup))
|
if (!HeapTupleIsValid(attrtup))
|
||||||
@ -1172,7 +1173,7 @@ plpgsql_parse_wordrowtype(char *string)
|
|||||||
strcat(var->refname, cp);
|
strcat(var->refname, cp);
|
||||||
var->datatype = malloc(sizeof(PLpgSQL_type));
|
var->datatype = malloc(sizeof(PLpgSQL_type));
|
||||||
var->datatype->typname = strdup(NameStr(typeStruct->typname));
|
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));
|
perm_fmgr_info(typeStruct->typinput, &(var->datatype->typinput));
|
||||||
var->datatype->typelem = typeStruct->typelem;
|
var->datatype->typelem = typeStruct->typelem;
|
||||||
var->datatype->typbyval = typeStruct->typbyval;
|
var->datatype->typbyval = typeStruct->typbyval;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user