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

  1. /*
  2.  * defind.c --
  3.  *    POSTGRES define and remove index code.
  4.  */
  5.  
  6. #include "tmp/postgres.h"
  7.  
  8. RcsId("$Header: /private/postgres/src/commands/RCS/defind.c,v 1.21 1992/02/26 22:51:19 olson Exp $");
  9.  
  10. #include "access/attnum.h"
  11. #include "access/genam.h"
  12. #include "access/heapam.h"
  13. #include "access/htup.h"
  14. #include "access/funcindex.h"
  15. #include "catalog/syscache.h"
  16. #include "catalog/pg_index.h"
  17. #include "nodes/pg_lisp.h"
  18. #include "nodes/plannodes.h"
  19. #include "nodes/primnodes.h"
  20. #include "nodes/relation.h"
  21. #include "utils/log.h"
  22. #include "utils/palloc.h"
  23.  
  24. #include "commands/defrem.h"
  25. #include "planner/prepqual.h"
  26. #include "planner/clause.h"
  27. #include "lib/copyfuncs.h"
  28.  
  29. #define IsFuncIndex(ATTR_LIST) (listp(CAAR(ATTR_LIST)))
  30.  
  31. void
  32. DefineIndex(heapRelationName, indexRelationName, accessMethodName,
  33.         attributeList, parameterList, predicate)
  34.  
  35.     Name        heapRelationName;
  36.     Name        indexRelationName;
  37.     Name        accessMethodName;
  38.     LispValue    attributeList;
  39.     LispValue    parameterList;
  40.     LispValue    predicate;
  41. {
  42.     ObjectId    *classObjectId;
  43.     ObjectId    accessMethodId;
  44.     ObjectId    relationId;
  45.     AttributeNumber    numberOfAttributes;
  46.     AttributeNumber    *attributeNumberA;
  47.     HeapTuple    tuple;
  48.     uint16        parameterCount;
  49.     Datum        *parameterA = NULL;
  50.     Datum        *nextP;
  51.     FuncIndexInfo    fInfo;
  52.     LispValue    cnfPred = LispNil;
  53.  
  54.     AssertArg(NameIsValid(heapRelationName));
  55.     AssertArg(NameIsValid(indexRelationName));
  56.     AssertArg(NameIsValid(accessMethodName));
  57.     AssertArg(listp(attributeList));
  58.     AssertArg(listp(parameterList));
  59.  
  60.     /*
  61.      * Handle attributes
  62.      */
  63.     numberOfAttributes = length(attributeList);
  64.     if (numberOfAttributes <= 0) {
  65.         elog(WARN, "DefineIndex: must specify at least one attribute");
  66.     }
  67.  
  68. #ifndef PARTIAL_IND
  69.     if (predicate != LispNil) {
  70.         elog (WARN, "partial indexes are unsupported in this version");
  71.     }
  72. #endif
  73.  
  74.     /*
  75.      * compute heap relation id
  76.      */
  77.     tuple = SearchSysCacheTuple(RELNAME, heapRelationName);
  78.     if (!HeapTupleIsValid(tuple)) {
  79.         elog(WARN, "DefineIndex: %s relation not found",
  80.             heapRelationName);
  81.     }
  82.     relationId = tuple->t_oid;
  83.  
  84.     /*
  85.      * compute access method id
  86.      */
  87.     tuple = SearchSysCacheTuple(AMNAME, accessMethodName);
  88.     if (!HeapTupleIsValid(tuple)) {
  89.         elog(WARN, "DefineIndex: %s access method not found",
  90.             accessMethodName);
  91.     }
  92.     accessMethodId = tuple->t_oid;
  93.  
  94.  
  95.     /*
  96.      * Handle parameters
  97.      */
  98.     parameterCount = length(parameterList) / 2;
  99. #ifndef    PERFECTPARSER
  100.     AssertArg(length(parameterList) == 2 * parameterCount);
  101. #endif
  102.     if (parameterCount >= 1) {
  103.         parameterA = LintCast(Datum *,
  104.             palloc(2 * parameterCount * sizeof *parameterA));
  105.  
  106.         nextP = ¶meterA[0];
  107.         while (!lispNullp(parameterList)) {
  108. #ifndef    PERFECTPARSER
  109.             AssertArg(lispStringp(CAR(parameterList)));
  110. #endif
  111.             *nextP = (Datum)CString(CAR(parameterList));
  112.             parameterList = CDR(parameterList);
  113.             nextP += 1;
  114.         }
  115.     }
  116.  
  117.     /*
  118.      * Convert the partial-index predicate from parsetree form to plan
  119.      * form, so it can be readily evaluated during index creation
  120.      */
  121.     if (predicate != LispNil) {
  122.         cnfPred = cnfify(lispCopy(predicate), true);
  123.         fix_opids(cnfPred);
  124.     }
  125.  
  126.     if (IsFuncIndex(attributeList))
  127.     {
  128.         int nargs;
  129.  
  130.         nargs = length(CDR(CAAR(attributeList)));
  131.         if (nargs > INDEX_MAX_KEYS)
  132.         {
  133.             elog(WARN, 
  134.                  "Too many args to function, limit of %d",
  135.                  INDEX_MAX_KEYS);
  136.         }
  137.  
  138.         FIgetnArgs(&fInfo) = nargs;
  139.         strncpy(FIgetname(&fInfo), 
  140.             CString(CAAR(CAR(attributeList))), 
  141.             sizeof(NameData));
  142.  
  143.         attributeNumberA = LintCast(AttributeNumber *,
  144.             palloc(nargs * sizeof attributeNumberA[0]));
  145.         classObjectId = LintCast(ObjectId *,
  146.             palloc(sizeof classObjectId[0]));
  147.  
  148.         FuncIndexArgs(attributeList, attributeNumberA, 
  149.             classObjectId, relationId);
  150.  
  151.         index_create(heapRelationName, indexRelationName,
  152.             &fInfo, accessMethodId, 
  153.             numberOfAttributes, attributeNumberA,
  154.             classObjectId, parameterCount, parameterA, cnfPred);
  155.     }
  156.     else
  157.     {
  158.         attributeNumberA = LintCast(AttributeNumber *,
  159.             palloc(numberOfAttributes*sizeof attributeNumberA[0]));
  160.         classObjectId = LintCast(ObjectId *,
  161.             palloc(numberOfAttributes * sizeof classObjectId[0]));
  162.  
  163.         NormIndexAttrs(attributeList, attributeNumberA, 
  164.             classObjectId, relationId);
  165.  
  166.         index_create(heapRelationName, indexRelationName, NULL,
  167.             accessMethodId, numberOfAttributes, attributeNumberA,
  168.             classObjectId, parameterCount, parameterA, cnfPred);
  169.     }
  170. }
  171.  
  172. FuncIndexArgs(attList, attNumP, opOidP, relId)
  173.     LispValue    attList;
  174.     AttributeNumber *attNumP;
  175.     ObjectId    *opOidP;
  176.     ObjectId    relId;
  177. {
  178.     LispValue    rest;
  179.     HeapTuple    tuple;
  180.  
  181.     tuple = SearchSysCacheTuple(CLANAME, CString(CADR(CAR(attList))));
  182.  
  183.     if (!HeapTupleIsValid(tuple)) 
  184.     {
  185.         elog(WARN, "DefineIndex: %s class not found",
  186.             CString(CADR(CAR(attList))));
  187.     }
  188.     *opOidP = tuple->t_oid;
  189.  
  190.     /*
  191.      * process the function arguments 
  192.      */
  193.     for (rest=CDR(CAAR(attList)); rest != LispNil; rest = CDR(rest)) 
  194.     {
  195.         LispValue    arg;
  196.  
  197.         AssertArg(listp(rest));
  198.  
  199.         arg = CAR(rest);
  200.         AssertArg(lispStringp(arg));
  201.  
  202.         tuple = SearchSysCacheTuple(ATTNAME, relId, CString(arg));
  203.  
  204.         if (!HeapTupleIsValid(tuple)) 
  205.         {
  206.             elog(WARN, 
  207.                  "DefineIndex: attribute \"%s\" not found",
  208.                  CString(arg));
  209.         }
  210.         *attNumP++ = ((Attribute)GETSTRUCT(tuple))->attnum;
  211.     }
  212. }
  213.  
  214. NormIndexAttrs(attList, attNumP, opOidP, relId)
  215.     LispValue    attList;
  216.     AttributeNumber *attNumP;
  217.     ObjectId    *opOidP;
  218.     ObjectId    relId;
  219. {
  220.     LispValue    rest;
  221.     HeapTuple    tuple;
  222.  
  223.     /*
  224.      * process attributeList
  225.      */
  226.     
  227.     for (rest=attList; rest != LispNil; rest = CDR(rest)) {
  228.  
  229.         LispValue    attribute;
  230.  
  231.         AssertArg(listp(rest));
  232.  
  233.         attribute = CAR(rest);
  234.         AssertArg(listp(attribute));
  235.  
  236.         if (length(attribute) != 2) {
  237.             if (length(attribute) != 1) {
  238.                 elog(WARN, "DefineIndex: malformed att");
  239.             }
  240.             elog(WARN,
  241.                  "DefineIndex: default index class unsupported");
  242.         }
  243.  
  244.         if (CADR(attribute) == LispNil || !lispStringp(CADR(attribute)))
  245.             elog(WARN, "missing opclass for define index");
  246.         if (CAR(attribute) == LispNil)
  247.             elog(WARN, "missing attribute for define index");
  248.  
  249.         tuple = SearchSysCacheTuple(ATTNAME, relId,
  250.             CString(CAR(attribute)));
  251.         if (!HeapTupleIsValid(tuple)) {
  252.             elog(WARN, 
  253.                  "DefineIndex: attribute \"%s\" not found",
  254.                  CString(CAR(attribute)));
  255.         }
  256.         *attNumP++ = ((Attribute)GETSTRUCT(tuple))->attnum;
  257.  
  258.         tuple = SearchSysCacheTuple(CLANAME, CString(CADR(attribute)));
  259.  
  260.         if (!HeapTupleIsValid(tuple)) {
  261.             elog(WARN, "DefineIndex: %s class not found",
  262.                 CString(CADR(attribute)));
  263.         }
  264.         *opOidP++ = tuple->t_oid;
  265.     }
  266. }
  267.  
  268. void
  269. RemoveIndex(name)
  270.     Name    name;
  271. {
  272.     ObjectId    id;
  273.     HeapTuple    tuple;
  274.  
  275.     tuple = SearchSysCacheTuple(RELNAME, name);
  276.  
  277.     if (!HeapTupleIsValid(tuple)) {
  278.         elog(WARN, "index \"%s\" nonexistant", name);
  279.     }
  280.  
  281.     if (((RelationTupleForm)GETSTRUCT(tuple))->relkind != 'i') {
  282.         elog(WARN, "relation \"%s\" is of type \"%c\"", name,
  283.             ((RelationTupleForm)GETSTRUCT(tuple))->relkind);
  284.     }
  285.  
  286.     index_destroy(tuple->t_oid);
  287. }
  288.