home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / dbu / index.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-05-10  |  5.4 KB  |  251 lines

  1. # include    <pv.h>
  2. # include    <func.h>
  3. # include    <symbol.h>
  4. # include    <ingres.h>
  5. # include    <aux.h>
  6. # include    <catalog.h>
  7. # include    <access.h>
  8. # include    <lock.h>
  9. # include    <sccs.h>
  10. # include    <errors.h>
  11.  
  12. SCCSID(@(#)index.c    8.6    5/10/86)
  13.  
  14. extern short    tTdbu[];
  15. extern int    indexx();
  16. extern int    null_fn();
  17.  
  18. struct fn_def    IndexFn =
  19. {
  20.     "INDEX",
  21.     indexx,
  22.     null_fn,
  23.     null_fn,
  24.     NULL,
  25.     0,
  26.     tTdbu,
  27.     100,
  28.     'Z',
  29.     0
  30. };
  31.  
  32.  
  33. /*
  34. **    This is the DBU routine INDEX
  35. **
  36. **  pc = # of parameters
  37. **  pv[0] points to primary relation name
  38. **  pv[1] points to index relation name
  39. **  pv[2] points to domain1
  40. **  pv[3] points to domain2
  41. **  .
  42. **  .
  43. **  .
  44. **  pv[pc] = NULL
  45. **
  46. */
  47.  
  48. struct dom
  49. {
  50.     int    id;
  51.     int    off;
  52.     int    frml;
  53.     char    frm[5];
  54. };
  55.  
  56. indexx(pc, pv)
  57. int    pc;
  58. PARM    pv[];
  59. {
  60.     register int        i;
  61.     int            j;
  62.     register struct dom    *dom;
  63.     register PARM        *p;
  64.     char            *primary, *indx;
  65.     int            ndoms, newpc;
  66.     struct tup_id        tid, hitid;
  67.     struct tup_id        xtid;
  68.     PARM            newpv[MAXKEYS * 2 + 4];
  69.     char            primtup[MAXTUP], systup[MAXTUP];
  70.     DESC            desc, pridesc;
  71.     extern DESC        Reldes;
  72.     extern DESC        Attdes;
  73.     extern DESC        Inddes;
  74.     struct relation        relkey, reltup;
  75.     struct attribute    attkey, atttup;
  76.     struct index        indtup;
  77.     struct dom        domain[MAXKEYS];
  78.  
  79.     primary = pv[0].pv_val.pv_str;
  80.     indx = pv[1].pv_val.pv_str;
  81. #    ifdef xZTR1
  82.     if (tTf(33, -1))
  83.         printf("index: (pri %s ind %s)\n", primary, indx);
  84. #    endif
  85.     i = openr(&pridesc, OR_READ, primary);
  86.     if (i == AMOPNVIEW_ERR)
  87.         return (error(NOINDVIEW, primary, 0));
  88.     if (i > 0)
  89.         return (error(NOPRIMREL, primary, 0));
  90.     if (i < 0)
  91.         syserr("INDEX : openr (%.14s) %d", primary, i);
  92.  
  93.     if (!bequal(pridesc.reldum.relowner, Usercode, UCODE_SZ))
  94.     {
  95.         i = NOTOWNED;
  96.     }
  97.     else if (pridesc.reldum.relstat & S_CATALOG)
  98.     {
  99.         i = NOINDXSYSREL;
  100.     }
  101.     else if (pridesc.reldum.relindxd == SECINDEX)
  102.     {
  103.         i = ALREADYINDX;
  104.     }
  105.  
  106.     if (i)
  107.     {
  108.         closer(&pridesc);
  109.         return (error(i, primary, 0));
  110.     }
  111.     /*
  112.     **  GATHER INFO. ON DOMAINS
  113.     */
  114.     opencatalog("attribute", OR_WRITE);
  115.     setkey(&Attdes, &attkey, primary, ATTRELID);
  116.     setkey(&Attdes, &attkey, pridesc.reldum.relowner, ATTOWNER);
  117.     pc -= 2;
  118.     p = &pv[2];
  119.     dom = domain;
  120.     for (i = 0; i < pc; i++)
  121.     {
  122.         if (i >= MAXKEYS)
  123.         {
  124.             closer(&pridesc);
  125.             return (error(TOOMUCHDOMS, (p->pv_val).pv_str, primary, 0));    /* too many keys */
  126.         }
  127.         setkey(&Attdes, &attkey, (p->pv_val).pv_str, ATTNAME);
  128.         j = getequal(&Attdes, &attkey, &atttup, &tid);
  129.         if (j < 0)
  130.             syserr("INDEX: geteq att %d", j);
  131.         if (j)
  132.         {
  133.             closer(&pridesc);
  134.             return (error(NODOM, (p->pv_val).pv_str, 0));    /* key not in relation */
  135.         }
  136.         if (pridesc.reldum.reldim > 0 && atttup.attid == pridesc.reldum.relatts)
  137.         /* attempting to use lid field as part of index */
  138.         {
  139.             closer(&pridesc);
  140.             return(error(NOINDXLID, primary, (p->pv_val).pv_str, 0));
  141.         }
  142.         dom->id = atttup.attid;
  143.         dom->off = atttup.attoff;
  144.         dom->frml = atttup.attfrml & I1MASK;
  145.         dom->frm[0] = atttup.attfrmt;
  146.         p++;
  147.         dom++;
  148.     }
  149.     ndoms = i;
  150.     noclose(&Attdes);
  151.  
  152.     /*
  153.     ** The "order" of the steps have been altered to improve
  154.     ** recovery possibilities
  155.     */
  156.     /*
  157.     **  STEP 1 & 2: CREATE INDEX RELATION.
  158.     */
  159.     newpv[0].pv_val.pv_str = "0202";
  160.     newpv[1].pv_val.pv_str = indx;
  161.     newpc = 2;
  162.     p = &pv[2];
  163.     dom = domain;
  164.     for (i = 0; i < pc; i++)
  165.     {
  166.         newpv[newpc++].pv_val.pv_str = (p->pv_val).pv_str;
  167.         itoa(dom->frml, &dom->frm[1]);
  168.         newpv[newpc++].pv_val.pv_str = dom->frm;
  169.         dom++;
  170.         p++;
  171.     }
  172.     newpv[newpc++].pv_val.pv_str = "tidp";
  173.     newpv[newpc++].pv_val.pv_str = "i4";
  174.     newpv[newpc].pv_type = PV_EOF;
  175.  
  176.     if (create(newpc, newpv))
  177.     {
  178.         closer(&pridesc);
  179.         return (-1);
  180.     }
  181.  
  182.     /* This is done for concurrency reasons */
  183.     if (noclose(&Reldes))
  184.         syserr("index: noclose");
  185.  
  186.     /*
  187.     **  STEP 5: FILL UP THE SECONDARY INDEX FILE ITSELF
  188.     */
  189.     if (Lockrel)
  190.         /* set a shared relation lock */
  191.         setrll(A_SLP, *(long *) &pridesc.reltid, M_SHARE);    /* pardon the kludge  */
  192.     if (i = openr(&desc, OR_WRITE, indx))
  193.         syserr("INDEX: openr %.14s %d", indx, i);
  194.     find(&pridesc, NOKEY, &tid, &hitid);
  195.     while ((i = get(&pridesc, &tid, &hitid, primtup, TRUE)) == 0)
  196.     {
  197.         dom = domain;
  198.         for (i = j = 0; j < ndoms; j++)
  199.         {
  200. # ifndef VAX
  201.             if (dom->frm[0] != 'c')
  202.                 i = ((i-1)|(dom->frml-1))+1;
  203. # endif
  204.             bmove(&primtup[dom->off], &systup[i], dom->frml);
  205.             i += dom->frml;
  206.             dom++;
  207.         }
  208. # ifndef VAX
  209.         i = ((i-1)|3)+1;
  210. # endif
  211.         bmove(&tid, &systup[i], sizeof tid);        /* move in pointer */
  212.         if ((j = insert(&desc, &xtid, systup, TRUE)) < 0)
  213.             syserr("INDEX: insert %.14s %d", indx, j);
  214.     }
  215.     if (i < 0)
  216.         syserr("INDEX: get %.14s %d", primary, i);
  217.     closer(&pridesc);
  218.     closer(&desc);
  219.  
  220.  
  221.     /*
  222.     **  STEP 3: ENTRIES TO INDEX-REL
  223.     */
  224.     pmove(primary, indtup.irelidp, MAXNAME, ' ');        /* mv in primary name  */
  225.     bmove(pridesc.reldum.relowner, indtup.iownerp, 2);    /* primary owner */
  226.     pmove(indx, indtup.irelidi, MAXNAME, ' ');        /* index name */
  227.     indtup.irelspeci = M_HEAP;
  228.     for (i = 0; i < MAXKEYS; i++)
  229.         indtup.idom[i] = (i < ndoms) ? domain[i].id : 0;
  230.     opencatalog("indexes", OR_WRITE);
  231.     if ((i = insert(&Inddes, &tid, &indtup, TRUE)) < 0)
  232.         syserr("INDEX: insert ix %d", i);
  233.  
  234.     /*
  235.     **  STEP 4: TURN BIT ON IN PRIMARY RELATION TO SHOW IT IS BEING INDEXED
  236.     */
  237.     opencatalog("relation", OR_WRITE);
  238.     setkey(&Reldes, &relkey, primary, RELID);
  239.     setkey(&Reldes, &relkey, pridesc.reldum.relowner, RELOWNER);
  240.     if (i = getequal(&Reldes, &relkey, &reltup, &tid))
  241.         syserr("INDEX: geteq rel %d", i);
  242.     reltup.relindxd = SECBASE;
  243.     if ((i = replace(&Reldes, &tid, &reltup, TRUE)) < 0)
  244.         syserr("INDEX: replace rel %d", i);
  245.  
  246.     if (Lockrel)
  247.         unlrl(*(long *) &pridesc.reltid);    /* release relation lock */
  248.  
  249.     return (0);
  250. }
  251.