home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / commands / purge.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  5.8 KB  |  205 lines

  1. /*
  2.  * purge.c --
  3.  *    the POSTGRES purge command.
  4.  *
  5.  * Note:
  6.  *    XXX There are many instances of int32 instead of ...Time.  These
  7.  *    should be changed once it is decided the signed'ness will be.
  8.  */
  9.  
  10. #include "tmp/c.h"
  11.  
  12. RcsId("$Header: /private/postgres/src/commands/RCS/purge.c,v 1.16 1992/06/18 18:16:11 mer Exp $");
  13.  
  14. #include "access/ftup.h"
  15. #include "access/heapam.h"
  16. #include "access/tqual.h"    /* for NowTimeQual */
  17. #include "catalog/catname.h"
  18. #include "utils/fmgr.h"
  19. #include "utils/log.h"
  20. #include "utils/nabstime.h"
  21.  
  22. #include "catalog/pg_relation.h"
  23.  
  24. static char    cmdname[] = "RelationPurge";
  25.  
  26. #define    RELATIVE    01
  27. #define    ABSOLUTE    02
  28.  
  29. int32
  30. RelationPurge(relationName, absoluteTimeString, relativeTimeString)
  31.     Name    relationName;
  32.     char    *absoluteTimeString, *relativeTimeString;
  33. {
  34.     register        i;
  35.     AbsoluteTime        absoluteTime = InvalidTime;
  36.     RelativeTime        relativeTime = InvalidTime;
  37.     bits8            dateTag;
  38.     Relation        relation;
  39.     HeapScanDesc        scan;
  40.     static ScanKeyEntryData    key[1] = {
  41.         { 0, RelationNameAttributeNumber, F_CHAR16EQ }
  42.     };
  43.     Buffer            buffer;
  44.     HeapTuple        newTuple, oldTuple;
  45.     Time            currentTime;
  46.     char            *values[RelationRelationNumberOfAttributes];
  47.     char            nulls[RelationRelationNumberOfAttributes];
  48.     char            replace[RelationRelationNumberOfAttributes];
  49.  
  50.     Assert(NameIsValid(relationName));
  51.     /* XXX check: pg_user.usecatupd permission? */
  52.  
  53.     if (PointerIsValid(absoluteTimeString)) {
  54.         if (!isabstime(absoluteTimeString, NULL)) {
  55.             elog(NOTICE, "%s: bad absolute time string \"%s\"",
  56.                  cmdname, absoluteTimeString);
  57.             absoluteTimeString[0] = '\0';
  58.             elog(WARN, "purge not executed");
  59.         }
  60.         absoluteTime = (int32) nabstimein(absoluteTimeString);
  61.         absoluteTimeString[0] = '\0';
  62.     }
  63.  
  64. #ifdef    PURGEDEBUG
  65.         elog(DEBUG, "RelationPurge: absolute time `%s' is %d.",
  66.             absoluteTimeString, absoluteTime);
  67. #endif    /* defined(PURGEDEBUG) */
  68.  
  69.     if (PointerIsValid(relativeTimeString)) {
  70.         if (isreltime(relativeTimeString, NULL, NULL, NULL) != 1) {
  71.             elog(WARN, "%s: bad relative time string \"%s\"",
  72.                  cmdname, relativeTimeString);
  73.         }
  74.         relativeTime = reltimein(relativeTimeString);
  75.  
  76. #ifdef    PURGEDEBUG
  77.         elog(DEBUG, "RelationPurge: relative time `%s' is %d.",
  78.             relativeTimeString, relativeTime);
  79. #endif    /* defined(PURGEDEBUG) */
  80.     }
  81.  
  82.     /*
  83.      * Find the RELATION relation tuple for the given relation.
  84.      */
  85.     relation = heap_openr(RelationRelationName->data);
  86.     key[0].argument = NameGetDatum(relationName);
  87.     fmgr_info(key[0].procedure, &key[0].func, &key[0].nargs);
  88.  
  89.     scan = heap_beginscan(relation, 0, NowTimeQual, 1, (ScanKey) key);
  90.     oldTuple = heap_getnext(scan, 0, &buffer);
  91.     if (!HeapTupleIsValid(oldTuple)) {
  92.         heap_endscan(scan);
  93.         heap_close(relation);
  94.         elog(WARN, "%s: no such relation: %s", cmdname, relationName);
  95.         return(0);
  96.     }
  97.  
  98.     /*
  99.      * Dig around in the tuple.
  100.      */
  101.     currentTime = GetCurrentTransactionStartTime();
  102.     if (!TimeIsValid(relativeTime)) {
  103.         dateTag = ABSOLUTE;
  104.         if (!TimeIsValid(absoluteTime))
  105.             absoluteTime = currentTime;
  106.     } else if (!TimeIsValid(absoluteTime))
  107.         dateTag = RELATIVE;
  108.     else
  109.         dateTag = ABSOLUTE | RELATIVE;
  110.     if (!assertConsistentTimes(absoluteTime, relativeTime, currentTime,
  111.                    dateTag, oldTuple)) {
  112.         heap_endscan(scan);
  113.         heap_close(relation);
  114.         elog(WARN, "%s: inconsistent times", cmdname);
  115.         return(0);
  116.     }
  117.     for (i = 0; i < RelationRelationNumberOfAttributes; ++i) {
  118.         nulls[i] = ' ';
  119.         values[i] = NULL;
  120.         replace[i] = ' ';
  121.     }
  122.     if (dateTag & ABSOLUTE) {
  123.         values[RelationExpiresAttributeNumber-1] =
  124.             (char *) absoluteTime;
  125.         replace[RelationExpiresAttributeNumber-1] = 'r';
  126.     }
  127.     if (dateTag & RELATIVE) {
  128.         values[RelationPreservedAttributeNumber-1] =
  129.             (char *) relativeTime;
  130.         replace[RelationPreservedAttributeNumber-1] = 'r';
  131.     }
  132.  
  133.     /*
  134.      * Change the RELATION relation tuple for the given relation.
  135.      */
  136.     newTuple = heap_modifytuple(oldTuple, buffer, relation, values,
  137.                     nulls, replace);
  138.     
  139.     /* XXX What do you do with a RuleLock?? */
  140.     /* XXX How do you detect an insertion error?? */
  141.     heap_replace(relation, &newTuple->t_ctid, newTuple);
  142.     pfree(newTuple);
  143.     
  144.     heap_endscan(scan);
  145.     heap_close(relation);
  146.     return(1);
  147. }
  148.  
  149.  
  150. assertConsistentTimes(absoluteTime, relativeTime, currentTime, dateTag, tuple)
  151.     Time        absoluteTime, relativeTime, currentTime;
  152.     bits8        dateTag;
  153.     HeapTuple    tuple;
  154. {
  155.     Time    currentExpires, currentPreserved;
  156.     bool    absError = false, relError = false;
  157.  
  158.     currentExpires =
  159.         ((RelationTupleForm) GETSTRUCT(tuple))->relexpires;
  160.     currentPreserved =
  161.         ((RelationTupleForm) GETSTRUCT(tuple))->relpreserved;
  162.     if (dateTag & ABSOLUTE) {
  163.         absError = true;
  164.         if (TimeIsValid(currentExpires) &&
  165.             TimeIsBefore(absoluteTime, currentExpires)) {
  166.             elog(NOTICE,
  167.                  "%s: expiration %s before current expiration %d",
  168.                  cmdname, absoluteTime, currentExpires);
  169.         } else if (TimeIsValid(currentPreserved) &&
  170.                 TimeIsBefore(absoluteTime,
  171.                     currentTime + currentPreserved)) {
  172.             elog(NOTICE,
  173.                  "%s: expiration %d before current relative %d",
  174.                  cmdname, absoluteTime, currentPreserved);
  175.         } else if (AbsoluteTimeIsAfter(absoluteTime, currentTime)) {
  176.             elog(NOTICE,
  177.                  "%s: expiration %d after current time %d",
  178.                  cmdname, absoluteTime, currentTime);
  179.         } else
  180.             absError = false;
  181.     }
  182.     if (dateTag & RELATIVE) {
  183.         relError = true;
  184.         if (TimeIsValid(currentExpires) &&
  185.                 TimeIsBefore(currentTime + relativeTime,
  186.                     currentExpires)) {
  187.             elog(NOTICE,
  188.                  "%s: relative %d before current expiration %d",
  189.                  cmdname, relativeTime, currentExpires);
  190.         } else if (TimeIsValid(currentPreserved) &&
  191.                 TimeIsBefore(relativeTime, currentPreserved)) {
  192.             /*
  193.              * XXX handle this by modifying both relative and
  194.              * current times.
  195.              */
  196.             elog(NOTICE,
  197.                  "%s: relative %d before current relative %d",
  198.                  cmdname, relativeTime, currentPreserved);
  199.         } else
  200.             relError = false;
  201.     }
  202.     /* XXX there must be cases when both are set and they interact... */
  203.     return(!(absError || relError));
  204. }
  205.