diff options
Diffstat (limited to 'src/backend/commands/purge.c')
-rw-r--r-- | src/backend/commands/purge.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/backend/commands/purge.c b/src/backend/commands/purge.c new file mode 100644 index 00000000000..b8b8317ab96 --- /dev/null +++ b/src/backend/commands/purge.c @@ -0,0 +1,168 @@ +/*------------------------------------------------------------------------- + * + * 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); +} + |