mirror of https://github.com/postgres/postgres
parent
7fc75517df
commit
4390b0bfbe
File diff suppressed because it is too large
Load Diff
@ -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; |
||||
} |
@ -0,0 +1,25 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* temprel.h-- |
||||
* Temporary relation functions |
||||
* |
||||
* |
||||
* Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* $Id: temprel.h,v 1.1 1999/02/02 03:45:28 momjian Exp $ |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#ifndef TEMPREL_H |
||||
#define TEMPREL_H |
||||
|
||||
#include "access/htup.h" |
||||
#include "access/attnum.h" |
||||
|
||||
void create_temp_relation(char *relname, HeapTuple pg_class_tuple); |
||||
void remove_all_temp_relations(void); |
||||
void remove_temp_relation(Oid relid); |
||||
HeapTuple get_temp_rel_by_name(char *user_relname); |
||||
|
||||
#endif /* TEMPREL_H */ |
||||
|
@ -1,10 +1,10 @@ |
||||
QUERY: SELECT * |
||||
INTO TABLE temp1 |
||||
FROM temp |
||||
INTO TABLE tmp1 |
||||
FROM tmp |
||||
WHERE onek.unique1 < 2; |
||||
QUERY: DROP TABLE temp1; |
||||
QUERY: DROP TABLE tmp1; |
||||
QUERY: SELECT * |
||||
INTO TABLE temp1 |
||||
FROM temp |
||||
INTO TABLE tmp1 |
||||
FROM tmp |
||||
WHERE onek2.unique1 < 2; |
||||
QUERY: DROP TABLE temp1; |
||||
QUERY: DROP TABLE tmp1; |
||||
|
@ -0,0 +1,29 @@ |
||||
QUERY: CREATE TABLE temptest(col int); |
||||
QUERY: CREATE INDEX i_temptest ON temptest(col); |
||||
QUERY: CREATE TEMP TABLE temptest(col int); |
||||
QUERY: CREATE INDEX i_temptest ON temptest(col); |
||||
QUERY: DROP INDEX i_temptest; |
||||
QUERY: DROP TABLE temptest; |
||||
QUERY: DROP INDEX i_temptest; |
||||
QUERY: DROP TABLE temptest; |
||||
QUERY: CREATE TABLE temptest(col int); |
||||
QUERY: INSERT INTO temptest VALUES (1); |
||||
QUERY: CREATE TEMP TABLE temptest(col int); |
||||
QUERY: INSERT INTO temptest VALUES (2); |
||||
QUERY: SELECT * FROM temptest; |
||||
col |
||||
--- |
||||
2 |
||||
(1 row) |
||||
|
||||
QUERY: DROP TABLE temptest; |
||||
QUERY: SELECT * FROM temptest; |
||||
col |
||||
--- |
||||
1 |
||||
(1 row) |
||||
|
||||
QUERY: DROP TABLE temptest; |
||||
QUERY: CREATE TEMP TABLE temptest(col int); |
||||
QUERY: SELECT * FROM temptest; |
||||
ERROR: temptest: Table does not exist. |
@ -1,14 +1,14 @@ |
||||
SELECT * |
||||
INTO TABLE temp1 |
||||
FROM temp |
||||
INTO TABLE tmp1 |
||||
FROM tmp |
||||
WHERE onek.unique1 < 2; |
||||
|
||||
DROP TABLE temp1; |
||||
DROP TABLE tmp1; |
||||
|
||||
SELECT * |
||||
INTO TABLE temp1 |
||||
FROM temp |
||||
INTO TABLE tmp1 |
||||
FROM tmp |
||||
WHERE onek2.unique1 < 2; |
||||
|
||||
DROP TABLE temp1; |
||||
DROP TABLE tmp1; |
||||
|
||||
|
@ -0,0 +1,47 @@ |
||||
-- |
||||
-- Test temp relations and indexes |
||||
-- |
||||
|
||||
-- test temp table/index masking |
||||
|
||||
CREATE TABLE temptest(col int); |
||||
|
||||
CREATE INDEX i_temptest ON temptest(col); |
||||
|
||||
CREATE TEMP TABLE temptest(col int); |
||||
|
||||
CREATE INDEX i_temptest ON temptest(col); |
||||
|
||||
DROP INDEX i_temptest; |
||||
|
||||
DROP TABLE temptest; |
||||
|
||||
DROP INDEX i_temptest; |
||||
|
||||
DROP TABLE temptest; |
||||
|
||||
-- test temp table selects |
||||
|
||||
CREATE TABLE temptest(col int); |
||||
|
||||
INSERT INTO temptest VALUES (1); |
||||
|
||||
CREATE TEMP TABLE temptest(col int); |
||||
|
||||
INSERT INTO temptest VALUES (2); |
||||
|
||||
SELECT * FROM temptest; |
||||
|
||||
DROP TABLE temptest; |
||||
|
||||
SELECT * FROM temptest; |
||||
|
||||
DROP TABLE temptest; |
||||
|
||||
CREATE TEMP TABLE temptest(col int); |
||||
|
||||
-- test temp table deletion |
||||
|
||||
\c regression |
||||
|
||||
SELECT * FROM temptest; |
Loading…
Reference in new issue