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

  1. /*
  2.  * remove.c --
  3.  *    POSTGRES remove (function | type | operator ) utilty code.
  4.  */
  5.  
  6. #include "tmp/c.h"
  7.  
  8. RcsId("$Header: /private/postgres/src/commands/RCS/remove.c,v 1.20 1992/03/09 23:06:28 mer Exp $");
  9.  
  10. #include "access/attnum.h"
  11. #include "access/heapam.h"
  12. #include "access/htup.h"
  13. #include "access/skey.h"
  14. #include "access/tqual.h"    /* for NowTimeQual */
  15. #include "catalog/catname.h"
  16. #include "commands/defrem.h"
  17. #include "utils/log.h"
  18.  
  19. #include "catalog/pg_operator.h"
  20. #include "catalog/pg_aggregate.h"
  21. #include "catalog/pg_proc.h"
  22. #include "catalog/pg_type.h"
  23.  
  24. static String    Messages[] = {
  25. #define    NonexistantTypeMessage    (Messages[0])
  26.     "Define: type %s nonexistant",
  27. };
  28.  
  29. void
  30. RemoveOperator(operatorName, typeName1, typeName2)
  31.     Name     operatorName;        /* operator name */
  32.     Name     typeName1;        /* first type name */
  33.     Name     typeName2;        /* optional second type name */
  34. {
  35.     Relation     relation;
  36.     HeapScanDesc     scan;
  37.     HeapTuple     tup;
  38.     ObjectId    typeId1;
  39.     ObjectId        typeId2;
  40.     int         defined;
  41.     ItemPointerData    itemPointerData;
  42.     Buffer          buffer;
  43.     ScanKeyEntryData    operatorKey[3];
  44.  
  45.     Assert(NameIsValid(operatorName));
  46.     Assert(NameIsValid(typeName1));
  47.  
  48.     typeId1 = TypeGet(typeName1, &defined);
  49.     if (!ObjectIdIsValid(typeId1)) {
  50.         elog(WARN, NonexistantTypeMessage, typeName1);
  51.         return;
  52.     }
  53.  
  54.     typeId2 = InvalidObjectId;
  55.     if (NameIsValid(typeName2)) {
  56.         typeId2 = TypeGet(typeName2, &defined);
  57.         if (!ObjectIdIsValid(typeId2)) {
  58.             elog(WARN, NonexistantTypeMessage, typeName2);
  59.             return;
  60.         }
  61.     }
  62.  
  63.     ScanKeyEntryInitialize(&operatorKey[0], 0x0,
  64.                    OperatorNameAttributeNumber,
  65.                    NameEqualRegProcedure,
  66.                    NameGetDatum(operatorName));
  67.  
  68.     ScanKeyEntryInitialize(&operatorKey[1], 0x0,
  69.                    OperatorLeftAttributeNumber,
  70.                    ObjectIdEqualRegProcedure,
  71.                    ObjectIdGetDatum(typeId1));
  72.  
  73.     ScanKeyEntryInitialize(&operatorKey[2], 0x0,
  74.                    OperatorRightAttributeNumber,
  75.                    ObjectIdEqualRegProcedure,
  76.                    ObjectIdGetDatum(typeId2));
  77.  
  78.     relation = RelationNameOpenHeapRelation(OperatorRelationName);
  79.     scan = RelationBeginHeapScan(relation, 0, NowTimeQual, 3,
  80.                       (ScanKey) operatorKey);
  81.     tup = HeapScanGetNextTuple(scan, 0, &buffer);
  82.     if (HeapTupleIsValid(tup)) {
  83.         ItemPointerCopy(&tup->t_ctid, &itemPointerData);
  84.         RelationDeleteHeapTuple(relation, &itemPointerData);
  85.     } else {
  86.         if (ObjectIdIsValid(typeId2)) {
  87.             elog(WARN, "Remove: operator %s(%s, %s) nonexistant",
  88.                 operatorName, typeName1, typeName2);
  89.         } else {
  90.             elog(WARN, "Remove: operator %s(%s) nonexistant",
  91.                 operatorName, typeName1);
  92.         }
  93.     }
  94.     HeapScanEnd(scan);
  95.     RelationCloseHeapRelation(relation);
  96. }
  97.  
  98. /*
  99.  *  SingleOpOperatorRemove
  100.  *    Removes all operators that have operands or a result of type 'typeOid'.
  101.  */
  102. static
  103. void
  104. SingleOpOperatorRemove(typeOid)
  105.     OID     typeOid;
  106. {
  107.     Relation     rdesc;
  108.     struct skey     key[3];
  109.     HeapScanDesc     sdesc;
  110.     HeapTuple     tup;
  111.     ItemPointerData itemPointerData;
  112.     Buffer         buffer;
  113.     static         attnums[3] = { 7, 8, 9 }; /* left, right, return */
  114.     register    i;
  115.     
  116.     ScanKeyEntryInitialize((ScanKeyEntry)&key[0],
  117.                    0, 0, ObjectIdEqualRegProcedure, (Datum)typeOid);
  118.     rdesc = heap_openr(OperatorRelationName->data);
  119.     for (i = 0; i < 3; ++i) {
  120.         key[0].sk_attnum = attnums[i];
  121.         sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
  122.         while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
  123.             ItemPointerCopy(&tup->t_ctid, &itemPointerData);   
  124.             /* XXX LOCK not being passed */
  125.             heap_delete(rdesc, &itemPointerData);
  126.         }
  127.         heap_endscan(sdesc);
  128.     }
  129.     heap_close(rdesc);
  130. }
  131.  
  132. /*
  133.  *  AttributeAndRelationRemove
  134.  *    Removes all entries in the attribute and relation relations
  135.  *    that contain entries of type 'typeOid'.
  136.  *      Currently nothing calls this code, it is untested.
  137.  */
  138. static
  139. void
  140. AttributeAndRelationRemove(typeOid)
  141.     OID     typeOid;
  142. {
  143.     struct oidlist {
  144.         OID        reloid;
  145.         struct oidlist    *next;
  146.     };
  147.     struct oidlist    *oidptr, *optr;
  148.     Relation     rdesc;
  149.     struct skey    key[1];
  150.     HeapScanDesc     sdesc;
  151.     HeapTuple     tup;
  152.     ItemPointerData    itemPointerData;
  153.     Buffer         buffer;
  154.     
  155.     /*
  156.      * Get the oid's of the relations to be removed by scanning the
  157.      * entire attribute relation.
  158.      * We don't need to remove the attributes here,
  159.      * because amdestroy will remove all attributes of the relation.
  160.      * XXX should check for duplicate relations
  161.      */
  162.  
  163.     ScanKeyEntryInitialize((ScanKeyEntry)&key[0],
  164.                    0, 3, ObjectIdEqualRegProcedure, (Datum)typeOid);
  165.  
  166.     oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
  167.     oidptr->next = NULL;
  168.     optr = oidptr; 
  169.     rdesc = heap_openr(AttributeRelationName->data);
  170.     sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
  171.     while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
  172.         ItemPointerCopy(&tup->t_ctid, &itemPointerData);   
  173.         optr->reloid = ((AttributeTupleForm)GETSTRUCT(tup))->attrelid;
  174.         optr->next = (struct oidlist *) palloc(sizeof(*oidptr));     
  175.         optr = optr->next;
  176.         }
  177.     optr->next = NULL;
  178.     heap_endscan(sdesc);
  179.     heap_close(rdesc);
  180.     
  181.  
  182.     ScanKeyEntryInitialize((ScanKeyEntry) &key[0], 0,
  183.             /*bug fix from prototyping, unknown bug ---^ */
  184.                    ObjectIdAttributeNumber,
  185.                    ObjectIdEqualRegProcedure, (Datum)0);
  186.     optr = oidptr;
  187.     rdesc = heap_openr(RelationRelationName->data);
  188.     while (PointerIsValid((char *) optr->next)) {
  189.         key[0].sk_data = (DATUM) (optr++)->reloid;
  190.         sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
  191.         tup = heap_getnext(sdesc, 0, &buffer);
  192.         if (PointerIsValid(tup)) {
  193.             Name    name;
  194.  
  195.             name = &((RelationTupleForm)GETSTRUCT(tup))->relname;
  196.             RelationNameDestroyHeapRelation(name->data);
  197.         }
  198.     }
  199.     heap_endscan(sdesc);
  200.     heap_close(rdesc);
  201. }
  202.  
  203.  
  204. /*
  205.  *  TypeRemove
  206.  *    Removes the type 'typeName' and all attributes and relations that
  207.  *    use it.
  208.  */
  209. void
  210. RemoveType(typeName)
  211.     Name      typeName;             /* type name to be removed */
  212. {
  213.     Relation     relation;  
  214.     HeapScanDesc     scan;      
  215.     HeapTuple     tup;
  216.     ObjectId    typeOid;
  217.     ItemPointerData    itemPointerData;
  218.     Buffer          buffer;
  219.     static ScanKeyEntryData typeKey[1] = {
  220.         { 0, TypeNameAttributeNumber, NameEqualRegProcedure }
  221.     };
  222.     NameData arrayNameData;
  223.     Name arrayName = & arrayNameData;
  224.  
  225.     Assert(NameIsValid(typeName));
  226.     
  227.     relation = RelationNameOpenHeapRelation(TypeRelationName);
  228.     fmgr_info(typeKey[0].procedure, &typeKey[0].func, &typeKey[0].nargs);
  229.  
  230.     /* Delete the primary type */
  231.  
  232.     typeKey[0].argument = NameGetDatum(typeName);
  233.  
  234.     scan = RelationBeginHeapScan(relation, 0, NowTimeQual,
  235.                      1, (ScanKey) typeKey);
  236.     tup = HeapScanGetNextTuple(scan, 0, (Buffer *) 0);
  237.     if (!HeapTupleIsValid(tup)) {
  238.         HeapScanEnd(scan);
  239.         RelationCloseHeapRelation(relation);
  240.         elog(WARN, NonexistantTypeMessage, typeName);
  241.     }
  242.     typeOid = tup->t_oid;
  243.     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
  244.         RelationDeleteHeapTuple(relation, &itemPointerData);
  245.     HeapScanEnd(scan);
  246.  
  247.     /* Now, Delete the "array of" that type */
  248.  
  249.     arrayName->data[0] = '_';
  250.     arrayName->data[1] = '\0';
  251.  
  252.     strncat(arrayName, typeName, 15);
  253.  
  254.     typeKey[0].argument = NameGetDatum(arrayName);
  255.  
  256.     scan = RelationBeginHeapScan(relation, 0, NowTimeQual,
  257.                      1, (ScanKey) typeKey);
  258.     tup = HeapScanGetNextTuple(scan, 0, (Buffer *) 0);
  259.  
  260.     if (!HeapTupleIsValid(tup))
  261.     {
  262.         elog(WARN, "Array stub for type %s not found", typeName->data);
  263.     }
  264.     typeOid = tup->t_oid;
  265.     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
  266.         RelationDeleteHeapTuple(relation, &itemPointerData);
  267.     HeapScanEnd(scan);
  268.  
  269.     RelationCloseHeapRelation(relation);
  270. }
  271.  
  272. void
  273. RemoveFunction(functionName)
  274.     Name     functionName;             /* type name to be removed */
  275. {
  276.     Relation         relation;
  277.     HeapScanDesc         scan;
  278.     HeapTuple        tup;
  279.     Buffer           buffer;
  280. #ifdef USEPARGS
  281.     ObjectId         oid;
  282. #endif
  283.     ItemPointerData  itemPointerData;
  284.     static ScanKeyEntryData key[3] = {
  285.         { 0, ProcedureNameAttributeNumber, NameEqualRegProcedure }
  286.     };
  287.     
  288.     Assert(NameIsValid(functionName));
  289.  
  290.     key[0].argument = NameGetDatum(functionName);
  291.  
  292.     fmgr_info(key[0].procedure, &key[0].func, &key[0].nargs);
  293.  
  294.     relation = RelationNameOpenHeapRelation(ProcedureRelationName);
  295.     scan = RelationBeginHeapScan(relation, 0, NowTimeQual, 1,
  296.         (ScanKey)key);
  297.     tup = HeapScanGetNextTuple(scan, 0, (Buffer *) 0);
  298.     if (!HeapTupleIsValid(tup)) {    
  299.         HeapScanEnd(scan);
  300.         RelationCloseHeapRelation(relation);
  301.         elog(WARN, "Remove: function %s nonexistant", functionName);
  302.     }
  303. #ifdef USEPARGS
  304.     oid = tup->t_oid;
  305. #endif
  306.     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
  307.         RelationDeleteHeapTuple(relation, &itemPointerData);
  308.     HeapScanEnd(scan);
  309.     RelationCloseHeapRelation(relation);
  310.     
  311.     /*  
  312.      * Remove associated parameters from PARG catalog
  313.      *
  314.      * XXX NOT CURRENTLY DONE
  315.      */
  316. #ifdef USEPARGS
  317.     ScanKeyEntryInitialize(&typeKey, 0, 1, ObjectIdEqualRegProcedure,
  318.                            ObjectIdGetDatum(oid));
  319.     key[0].argument = NameGetDatum(functionName);
  320.     relation = RelationNameOpenHeapRelation(ProcedureArgumentRelationName);
  321.     scan = RelationBeginHeapScan(relation, 0, NowTimeQual,
  322.                      1, (ScanKey) typeKey);
  323.     tup = HeapScanGetNextTuple(scan, 0, (Buffer *) 0);
  324.     while (PointerIsValid(tup)) {
  325.         ItemPointerCopy(&tup->t_ctid, &itemPointerData);
  326.         RelationDeleteHeapTuple(relation, &itemPointerData);
  327.         tup = HeapScanGetNextTuple(scan, 0, (Buffer *) 0);
  328.     }
  329.     HeapScanEnd(scan);
  330.     RelationCloseHeapRelation(relation);
  331. #endif
  332. }
  333.  
  334. void
  335. RemoveAggregate(aggName)
  336.     Name    aggName;
  337. {
  338.     Relation     relation;
  339.     HeapScanDesc    scan;
  340.     HeapTuple    tup;
  341.     Buffer        buffer;
  342.     ItemPointerData      itemPointerData;
  343.     static ScanKeyEntryData key[3] = {
  344.         { 0, AggregateNameAttributeNumber, NameEqualRegProcedure }
  345.     };
  346.  
  347.     Assert(NameIsValid(aggName));
  348.     key[0].argument = NameGetDatum(aggName);
  349.  
  350.     fmgr_info(key[0].procedure, &key[0].func, &key[0].nargs);
  351.     relation = RelationNameOpenHeapRelation(AggregateRelationName);
  352.     scan = RelationBeginHeapScan(relation, 0, NowTimeQual, 1,
  353.          (ScanKey)key);
  354.     tup = HeapScanGetNextTuple(scan, 0, (Buffer *) 0);
  355.     if (!HeapTupleIsValid(tup)) {
  356.         HeapScanEnd(scan);
  357.         RelationCloseHeapRelation(relation);
  358.         elog(WARN, "Remove: aggregate %s nonexistant", aggName);
  359.     }
  360.     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
  361.     RelationDeleteHeapTuple(relation, &itemPointerData);
  362.     HeapScanEnd(scan);
  363.     RelationCloseHeapRelation(relation);
  364.  
  365. }
  366.  
  367.  
  368.