mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Add TEMP tables/indexes. Add COPY pfree(). Other cleanups.
This commit is contained in:
5
src/backend/utils/cache/Makefile
vendored
5
src/backend/utils/cache/Makefile
vendored
@ -4,7 +4,7 @@
|
||||
# Makefile for utils/cache
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.9 1998/08/24 01:13:52 momjian Exp $
|
||||
# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.10 1999/02/02 03:44:54 momjian Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -13,7 +13,8 @@ include ../../../Makefile.global
|
||||
|
||||
CFLAGS += -I../..
|
||||
|
||||
OBJS = catcache.o inval.o rel.o relcache.o syscache.o lsyscache.o fcache.o
|
||||
OBJS = catcache.o inval.o rel.o relcache.o syscache.o lsyscache.o \
|
||||
fcache.o temprel.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
3
src/backend/utils/cache/catcache.c
vendored
3
src/backend/utils/cache/catcache.c
vendored
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.36 1998/11/27 19:52:26 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.37 1999/02/02 03:44:58 momjian Exp $
|
||||
*
|
||||
* Notes:
|
||||
* XXX This needs to use exception.h to handle recovery when
|
||||
@ -196,7 +196,6 @@ CatalogCacheInitializeCache(struct catcache * cache,
|
||||
|
||||
if (cache->cc_key[i] > 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* Yoiks. The implementation of the hashing code and the
|
||||
* implementation of int28's are at loggerheads. The right
|
||||
|
45
src/backend/utils/cache/inval.c
vendored
45
src/backend/utils/cache/inval.c
vendored
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.18 1998/11/27 19:52:28 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.19 1999/02/02 03:45:01 momjian Exp $
|
||||
*
|
||||
* Note - this code is real crufty...
|
||||
*
|
||||
@ -20,6 +20,7 @@
|
||||
#include "access/heapam.h" /* XXX to support hacks below */
|
||||
#include "access/htup.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "storage/bufpage.h"
|
||||
#include "storage/buf.h" /* XXX for InvalidBuffer */
|
||||
#include "storage/ipc.h"
|
||||
@ -244,31 +245,17 @@ RelationIdRegisterLocalInvalid(Oid relationId, Oid objectId)
|
||||
static void
|
||||
getmyrelids()
|
||||
{
|
||||
HeapTuple tuple;
|
||||
MyRelationRelationId = RelnameFindRelid(RelationRelationName);
|
||||
Assert(RelationRelationName != InvalidOid);
|
||||
|
||||
tuple = SearchSysCacheTuple(RELNAME,
|
||||
PointerGetDatum(RelationRelationName),
|
||||
0, 0, 0);
|
||||
Assert(HeapTupleIsValid(tuple));
|
||||
MyRelationRelationId = tuple->t_data->t_oid;
|
||||
MyAttributeRelationId = RelnameFindRelid(AttributeRelationName);
|
||||
Assert(AttributeRelationName != InvalidOid);
|
||||
|
||||
tuple = SearchSysCacheTuple(RELNAME,
|
||||
PointerGetDatum(AttributeRelationName),
|
||||
0, 0, 0);
|
||||
Assert(HeapTupleIsValid(tuple));
|
||||
MyAttributeRelationId = tuple->t_data->t_oid;
|
||||
MyAMRelationId = RelnameFindRelid(AccessMethodRelationName);
|
||||
Assert(MyAMRelationId != InvalidOid);
|
||||
|
||||
tuple = SearchSysCacheTuple(RELNAME,
|
||||
PointerGetDatum(AccessMethodRelationName),
|
||||
0, 0, 0);
|
||||
Assert(HeapTupleIsValid(tuple));
|
||||
MyAMRelationId = tuple->t_data->t_oid;
|
||||
|
||||
tuple = SearchSysCacheTuple(RELNAME,
|
||||
PointerGetDatum(AccessMethodOperatorRelationName),
|
||||
0, 0, 0);
|
||||
Assert(HeapTupleIsValid(tuple));
|
||||
MyAMOPRelationId = tuple->t_data->t_oid;
|
||||
MyAMOPRelationId = RelnameFindRelid(AccessMethodOperatorRelationName);
|
||||
Assert(MyAMOPRelationId != InvalidOid);
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
@ -614,10 +601,6 @@ RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple)
|
||||
*/
|
||||
RelationInvalidateHeapTuple_DEBUG1;
|
||||
|
||||
/* ----------------
|
||||
*
|
||||
* ----------------
|
||||
*/
|
||||
RelationInvalidateCatalogCacheTuple(relation,
|
||||
tuple,
|
||||
CacheIdRegisterLocalInvalid);
|
||||
@ -625,12 +608,4 @@ RelationInvalidateHeapTuple(Relation relation, HeapTuple tuple)
|
||||
RelationInvalidateRelationCache(relation,
|
||||
tuple,
|
||||
RelationIdRegisterLocalInvalid);
|
||||
|
||||
#ifdef NOT_USED
|
||||
if (RefreshWhenInvalidate)
|
||||
/* what does this do? bjm 1998/08/20 */
|
||||
RelationInvalidateCatalogCacheTuple(relation,
|
||||
tuple,
|
||||
(void (*) ()) NULL);
|
||||
#endif
|
||||
}
|
||||
|
92
src/backend/utils/cache/relcache.c
vendored
92
src/backend/utils/cache/relcache.c
vendored
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.55 1999/01/22 18:47:37 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.56 1999/02/02 03:45:02 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -404,7 +404,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
|
||||
switch (buildinfo.infotype)
|
||||
{
|
||||
case INFO_RELID:
|
||||
return_tuple = ClassOidIndexScan(pg_class_desc, buildinfo.i.info_id);
|
||||
return_tuple = ClassOidIndexScan(pg_class_desc,buildinfo.i.info_id);
|
||||
break;
|
||||
|
||||
case INFO_RELNAME:
|
||||
@ -821,7 +821,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
|
||||
*/
|
||||
if (!HeapTupleIsValid(pg_class_tuple))
|
||||
{
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
return NULL;
|
||||
@ -867,8 +866,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
|
||||
*/
|
||||
if (OidIsValid(relam))
|
||||
{
|
||||
relation->rd_am = (Form_pg_am)
|
||||
AccessMethodObjectIdGetForm(relam);
|
||||
relation->rd_am = (Form_pg_am) AccessMethodObjectIdGetForm(relam);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
@ -927,7 +925,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo)
|
||||
* restore memory context and return the new reldesc.
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
RelationCacheInsert(relation);
|
||||
|
||||
/* -------------------
|
||||
@ -1197,8 +1194,7 @@ RelationIdGetRelation(Oid relationId)
|
||||
buildinfo.i.info_id = relationId;
|
||||
|
||||
rd = RelationBuildDesc(buildinfo);
|
||||
return
|
||||
rd;
|
||||
return rd;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
@ -1332,8 +1328,9 @@ RelationFlushRelation(Relation *relationPtr,
|
||||
|
||||
/* --------------------------------
|
||||
* RelationForgetRelation -
|
||||
* RelationFlushRelation + if the relation is local then get rid of
|
||||
* the relation descriptor from the newly created relation list.
|
||||
* RelationFlushRelation + if the relation is myxactonly then
|
||||
* get rid of the relation descriptor from the newly created
|
||||
* relation list.
|
||||
* --------------------------------
|
||||
*/
|
||||
void
|
||||
@ -1342,37 +1339,39 @@ RelationForgetRelation(Oid rid)
|
||||
Relation relation;
|
||||
|
||||
RelationIdCacheLookup(rid, relation);
|
||||
Assert(PointerIsValid(relation));
|
||||
|
||||
if (relation->rd_islocal)
|
||||
if (PointerIsValid(relation))
|
||||
{
|
||||
MemoryContext oldcxt;
|
||||
List *curr;
|
||||
List *prev = NIL;
|
||||
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
|
||||
|
||||
foreach(curr, newlyCreatedRelns)
|
||||
if (relation->rd_myxactonly)
|
||||
{
|
||||
Relation reln = lfirst(curr);
|
||||
|
||||
Assert(reln != NULL && reln->rd_islocal);
|
||||
if (RelationGetRelid(reln) == rid)
|
||||
break;
|
||||
prev = curr;
|
||||
MemoryContext oldcxt;
|
||||
List *curr;
|
||||
List *prev = NIL;
|
||||
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
|
||||
|
||||
foreach(curr, newlyCreatedRelns)
|
||||
{
|
||||
Relation reln = lfirst(curr);
|
||||
|
||||
Assert(reln != NULL && reln->rd_myxactonly);
|
||||
if (RelationGetRelid(reln) == rid)
|
||||
break;
|
||||
prev = curr;
|
||||
}
|
||||
if (curr == NIL)
|
||||
elog(FATAL, "Local relation %s not found in list",
|
||||
(RelationGetRelationName(relation))->data);
|
||||
if (prev == NIL)
|
||||
newlyCreatedRelns = lnext(newlyCreatedRelns);
|
||||
else
|
||||
lnext(prev) = lnext(curr);
|
||||
pfree(curr);
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
}
|
||||
if (curr == NIL)
|
||||
elog(FATAL, "Local relation %s not found in list",
|
||||
(RelationGetRelationName(relation))->data);
|
||||
if (prev == NIL)
|
||||
newlyCreatedRelns = lnext(newlyCreatedRelns);
|
||||
else
|
||||
lnext(prev) = lnext(curr);
|
||||
pfree(curr);
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
RelationFlushRelation(&relation, false);
|
||||
}
|
||||
|
||||
RelationFlushRelation(&relation, false);
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
@ -1393,9 +1392,8 @@ RelationIdInvalidateRelationCacheByRelationId(Oid relationId)
|
||||
* BufferSync also? But I'll leave it for now since I don't want to
|
||||
* break anything.) - ay 3/95
|
||||
*/
|
||||
if (PointerIsValid(relation) && !relation->rd_islocal)
|
||||
if (PointerIsValid(relation) && !relation->rd_myxactonly)
|
||||
{
|
||||
|
||||
/*
|
||||
* The boolean onlyFlushReferenceCountZero in RelationFlushReln()
|
||||
* should be set to true when we are incrementing the command
|
||||
@ -1502,13 +1500,13 @@ RelationRegisterRelation(Relation relation)
|
||||
|
||||
/*
|
||||
* we've just created the relation. It is invisible to anyone else
|
||||
* before the transaction is committed. Setting rd_islocal allows us
|
||||
* before the transaction is committed. Setting rd_myxactonly allows us
|
||||
* to use the local buffer manager for select/insert/etc before the
|
||||
* end of transaction. (We also need to keep track of relations
|
||||
* created during a transaction and does the necessary clean up at the
|
||||
* end of the transaction.) - ay 3/95
|
||||
*/
|
||||
relation->rd_islocal = TRUE;
|
||||
relation->rd_myxactonly = TRUE;
|
||||
newlyCreatedRelns = lcons(relation, newlyCreatedRelns);
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
@ -1516,7 +1514,7 @@ RelationRegisterRelation(Relation relation)
|
||||
|
||||
/*
|
||||
* RelationPurgeLocalRelation -
|
||||
* find all the Relation descriptors marked rd_islocal and reset them.
|
||||
* find all the Relation descriptors marked rd_myxactonly and reset them.
|
||||
* This should be called at the end of a transaction (commit/abort) when
|
||||
* the "local" relations will become visible to others and the multi-user
|
||||
* buffer pool should be used.
|
||||
@ -1536,7 +1534,7 @@ RelationPurgeLocalRelation(bool xactCommitted)
|
||||
List *l = newlyCreatedRelns;
|
||||
Relation reln = lfirst(l);
|
||||
|
||||
Assert(reln != NULL && reln->rd_islocal);
|
||||
Assert(reln != NULL && reln->rd_myxactonly);
|
||||
|
||||
if (!xactCommitted)
|
||||
{
|
||||
@ -1545,18 +1543,18 @@ RelationPurgeLocalRelation(bool xactCommitted)
|
||||
* remove the file if we abort. This is so that files for
|
||||
* tables created inside a transaction block get removed.
|
||||
*/
|
||||
if (reln->rd_istemp)
|
||||
if (reln->rd_isnoname)
|
||||
{
|
||||
if (!(reln->rd_tmpunlinked))
|
||||
if (!(reln->rd_nonameunlinked))
|
||||
{
|
||||
smgrunlink(DEFAULT_SMGR, reln);
|
||||
reln->rd_tmpunlinked = TRUE;
|
||||
reln->rd_nonameunlinked = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
smgrunlink(DEFAULT_SMGR, reln);
|
||||
}
|
||||
else if (!IsBootstrapProcessingMode() && !(reln->rd_istemp))
|
||||
else if (!IsBootstrapProcessingMode() && !(reln->rd_isnoname))
|
||||
|
||||
/*
|
||||
* RelationFlushRelation () below will flush relation
|
||||
@ -1568,7 +1566,7 @@ RelationPurgeLocalRelation(bool xactCommitted)
|
||||
*/
|
||||
smgrclose(DEFAULT_SMGR, reln);
|
||||
|
||||
reln->rd_islocal = FALSE;
|
||||
reln->rd_myxactonly = FALSE;
|
||||
|
||||
if (!IsBootstrapProcessingMode())
|
||||
RelationFlushRelation(&reln, FALSE);
|
||||
|
165
src/backend/utils/cache/temprel.c
vendored
Normal file
165
src/backend/utils/cache/temprel.c
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* temprel.c--
|
||||
* POSTGRES temporary relation handling
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/temprel.c,v 1.1 1999/02/02 03:45:03 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implements temp tables by modifying the relname cache lookups
|
||||
* of pg_class.
|
||||
* When a temp table is created, a linked list of temp table tuples is
|
||||
* stored here. When a relname cache lookup is done, references to user-named
|
||||
* temp tables are converted to the internal temp table names.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "postgres.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/pg_list.h"
|
||||
#include "utils/mcxt.h"
|
||||
#include "utils/temprel.h"
|
||||
#include "access/htup.h"
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/pg_class.h"
|
||||
|
||||
GlobalMemory CacheCxt;
|
||||
|
||||
/* ----------------
|
||||
* global variables
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
static List *temp_rels = NIL;
|
||||
|
||||
typedef struct TempTable
|
||||
{
|
||||
char *user_relname;
|
||||
HeapTuple pg_class_tuple;
|
||||
} TempTable;
|
||||
|
||||
|
||||
void
|
||||
create_temp_relation(char *relname, HeapTuple pg_class_tuple)
|
||||
{
|
||||
MemoryContext oldcxt;
|
||||
TempTable *temp_rel;
|
||||
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
|
||||
|
||||
temp_rel = palloc(sizeof(TempTable));
|
||||
temp_rel->user_relname = palloc(NAMEDATALEN);
|
||||
|
||||
/* save user-supplied name */
|
||||
strcpy(temp_rel->user_relname, relname);
|
||||
|
||||
temp_rel->pg_class_tuple = heap_copytuple(pg_class_tuple);
|
||||
|
||||
temp_rels = lcons(temp_rel, temp_rels);
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
}
|
||||
|
||||
void
|
||||
remove_all_temp_relations(void)
|
||||
{
|
||||
List *l, *next;
|
||||
|
||||
l = temp_rels;
|
||||
while (l != NIL)
|
||||
{
|
||||
TempTable *temp_rel = lfirst(l);
|
||||
Form_pg_class classtuple;
|
||||
|
||||
classtuple = (Form_pg_class)GETSTRUCT(temp_rel->pg_class_tuple);
|
||||
|
||||
next = lnext(l); /* do this first, l is deallocated */
|
||||
|
||||
if (classtuple->relkind != RELKIND_INDEX)
|
||||
{
|
||||
char relname[NAMEDATALEN];
|
||||
|
||||
/* safe from deallocation */
|
||||
strcpy(relname, temp_rel->user_relname);
|
||||
heap_destroy_with_catalog(relname);
|
||||
}
|
||||
else
|
||||
index_destroy(temp_rel->pg_class_tuple->t_data->t_oid);
|
||||
|
||||
l = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* we don't have the relname for indexes, so we just pass the oid */
|
||||
void
|
||||
remove_temp_relation(Oid relid)
|
||||
{
|
||||
|
||||
MemoryContext oldcxt;
|
||||
List *l, *prev;
|
||||
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);
|
||||
|
||||
prev = NIL;
|
||||
l = temp_rels;
|
||||
while (l != NIL)
|
||||
{
|
||||
TempTable *temp_rel = lfirst(l);
|
||||
|
||||
if (temp_rel->pg_class_tuple->t_data->t_oid == relid)
|
||||
{
|
||||
pfree(temp_rel->user_relname);
|
||||
pfree(temp_rel->pg_class_tuple);
|
||||
pfree(temp_rel);
|
||||
/* remove from linked list */
|
||||
if (prev != NIL)
|
||||
{
|
||||
lnext(prev) = lnext(l);
|
||||
pfree(l);
|
||||
l = lnext(prev);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_rels = lnext(l);
|
||||
pfree(l);
|
||||
l = temp_rels;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = l;
|
||||
l = lnext(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
}
|
||||
|
||||
HeapTuple
|
||||
get_temp_rel_by_name(char *user_relname)
|
||||
{
|
||||
List *l;
|
||||
|
||||
foreach(l, temp_rels)
|
||||
{
|
||||
TempTable *temp_rel = lfirst(l);
|
||||
|
||||
if (strcmp(temp_rel->user_relname, user_relname) == 0)
|
||||
return temp_rel->pg_class_tuple;
|
||||
}
|
||||
return NULL;
|
||||
}
|
Reference in New Issue
Block a user