postgresql/src/backend/commands/purge.c
1996-07-09 06:22:35 +00:00

169 lines
5.0 KiB
C

/*-------------------------------------------------------------------------
*
* purge.c--
* the POSTGRES purge command.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/purge.c,v 1.1.1.1 1996/07/09 06:21:21 scrappy Exp $
*
* Note:
* XXX There are many instances of int32 instead of ...Time. These
* should be changed once it is decided the signed'ness will be.
*
*-------------------------------------------------------------------------
*/
#include "c.h"
#include "access/heapam.h"
#include "access/xact.h"
#include "utils/tqual.h" /* for NowTimeQual */
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "fmgr.h"
#include "utils/elog.h"
#include "utils/palloc.h"
#include "utils/nabstime.h"
#include "catalog/pg_class.h"
#include "commands/purge.h"
#include "utils/builtins.h" /* for isreltime() */
static char cmdname[] = "RelationPurge";
#define RELATIVE 01
#define ABSOLUTE 02
int32
RelationPurge(char *relationName,
char *absoluteTimeString,
char *relativeTimeString)
{
register i;
AbsoluteTime absoluteTime = INVALID_ABSTIME;
RelativeTime relativeTime = INVALID_RELTIME;
bits8 dateTag;
Relation relation;
HeapScanDesc scan;
static ScanKeyData key[1] = {
{ 0, Anum_pg_class_relname, F_NAMEEQ }
};
Buffer buffer;
HeapTuple newTuple, oldTuple;
AbsoluteTime currentTime;
char *values[Natts_pg_class];
char nulls[Natts_pg_class];
char replace[Natts_pg_class];
Relation idescs[Num_pg_class_indices];
/*
* XXX for some reason getmyrelids (in inval.c) barfs when
* you heap_replace tuples from these classes. i thought
* setheapoverride would fix it but it didn't. for now,
* just disallow purge on these classes.
*/
if (strcmp(RelationRelationName, relationName) == 0 ||
strcmp(AttributeRelationName, relationName) == 0 ||
strcmp(AccessMethodRelationName, relationName) == 0 ||
strcmp(AccessMethodOperatorRelationName, relationName) == 0) {
elog(WARN, "%s: cannot purge catalog \"%s\"",
cmdname, relationName);
}
if (PointerIsValid(absoluteTimeString)) {
absoluteTime = (int32) nabstimein(absoluteTimeString);
absoluteTimeString[0] = '\0';
if (absoluteTime == INVALID_ABSTIME) {
elog(NOTICE, "%s: bad absolute time string \"%s\"",
cmdname, absoluteTimeString);
elog(WARN, "purge not executed");
}
}
#ifdef PURGEDEBUG
elog(DEBUG, "%s: absolute time `%s' is %d.",
cmdname, absoluteTimeString, absoluteTime);
#endif /* defined(PURGEDEBUG) */
if (PointerIsValid(relativeTimeString)) {
if (isreltime(relativeTimeString, NULL, NULL, NULL) != 1) {
elog(WARN, "%s: bad relative time string \"%s\"",
cmdname, relativeTimeString);
}
relativeTime = reltimein(relativeTimeString);
#ifdef PURGEDEBUG
elog(DEBUG, "%s: relative time `%s' is %d.",
cmdname, relativeTimeString, relativeTime);
#endif /* defined(PURGEDEBUG) */
}
/*
* Find the RELATION relation tuple for the given relation.
*/
relation = heap_openr(RelationRelationName);
key[0].sk_argument = PointerGetDatum(relationName);
fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
oldTuple = heap_getnext(scan, 0, &buffer);
if (!HeapTupleIsValid(oldTuple)) {
heap_endscan(scan);
heap_close(relation);
elog(WARN, "%s: no such relation: %s", cmdname, relationName);
return(0);
}
/*
* Dig around in the tuple.
*/
currentTime = GetCurrentTransactionStartTime();
if (!RelativeTimeIsValid(relativeTime)) {
dateTag = ABSOLUTE;
if (!AbsoluteTimeIsValid(absoluteTime))
absoluteTime = currentTime;
} else if (!AbsoluteTimeIsValid(absoluteTime))
dateTag = RELATIVE;
else
dateTag = ABSOLUTE | RELATIVE;
for (i = 0; i < Natts_pg_class; ++i) {
nulls[i] = heap_attisnull(oldTuple, i+1) ? 'n' : ' ';
values[i] = NULL;
replace[i] = ' ';
}
if (dateTag & ABSOLUTE) {
values[Anum_pg_class_relexpires-1] =
(char *) UInt32GetDatum(absoluteTime);
replace[Anum_pg_class_relexpires-1] = 'r';
}
if (dateTag & RELATIVE) {
values[Anum_pg_class_relpreserved-1] =
(char *) UInt32GetDatum(relativeTime);
replace[Anum_pg_class_relpreserved-1] = 'r';
}
/*
* Change the RELATION relation tuple for the given relation.
*/
newTuple = heap_modifytuple(oldTuple, buffer, relation, (Datum*)values,
nulls, replace);
/* XXX How do you detect an insertion error?? */
(void) heap_replace(relation, &newTuple->t_ctid, newTuple);
/* keep the system catalog indices current */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, relation, newTuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
pfree(newTuple);
heap_endscan(scan);
heap_close(relation);
return(1);
}