home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / ovqp / key.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-18  |  9.2 KB  |  446 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <symbol.h>
  4. # include    <tree.h>
  5. # include    <catalog.h>
  6. # include    "../decomp/globs.h"
  7. # include    "strategy.h"
  8. # include    <btree.h>
  9. # include    <sccs.h>
  10.  
  11. SCCSID(@(#)key.c    8.4    3/20/85)
  12.  
  13.  
  14.  
  15. /*
  16. **    Exactkey checks to see if the relation described
  17. **    by "ap" can be used in a hashed scan.
  18. **    All the key domains of the relation must
  19. **    have simple clauses of equality associated
  20. **    with them in the qualification.
  21. **
  22. **    Returns 0 if the relation can't be used.
  23. **
  24. **    Returns > 0 if it can.
  25. */
  26.  
  27. exactkey(ap, key)
  28. struct accessparam    *ap;
  29. struct key        *key;
  30. {
  31.     register struct accessparam    *a;
  32.     register struct key        *k;
  33.     register struct simp        *s;
  34.     int                d, i, j;
  35.  
  36. #    ifdef xOTR1
  37.     if (tTf(85, -1))
  38.         printf("Exactkey\n");
  39. #    endif
  40.  
  41.     a = ap;
  42.     k = key;
  43.     i = 0;
  44.     if (a->mode == EXACTKEY)
  45.     {
  46.  
  47.         for (i = 0; d = a->keydno[i]; i++)
  48.         {
  49.     
  50.             s = De.ov_simp;
  51.             for (j = 0; j < De.ov_nsimp; j++)
  52.             {
  53.                 if (s->relop == opEQ && s->att == d)
  54.                 {
  55.                     k->keysym = s->cons;
  56.                     k->dnumber = (a->sec_index == TRUE) ? i+1 : d;
  57.                     k++;
  58. #                    ifdef xOTR1
  59.                     if (tTf(85, 1))
  60.                     {
  61.                         printf("exact key on dom %d\tvalue=", d);
  62.                         prsym(s->cons);
  63.                     }
  64. #                    endif
  65.                     break;
  66.                 }
  67.                 s++;
  68.             }
  69.             if (j == De.ov_nsimp)
  70.             {
  71.                 i = 0;    /* failure. at lease one key isn't used */
  72.                 break;
  73.             }
  74.         }
  75.         k->dnumber = 0;    /* mark end of list */
  76.     }
  77. #    ifdef xOTR1
  78.     if (tTf(85, 9))
  79.         printf("exactkey returning %d\n", i);
  80. #    endif
  81.     return (i);
  82. }
  83.  
  84. /*
  85. **    Attempts to use the B-Tree for retrieval.
  86. **    There are two types of searches possible, exact and range searches.
  87. **    In order for an exact search to be possible, there must be a simple
  88. **    equality clause using the lid field.
  89. **    For a range search, either or both lid ranges must be provided.
  90. **
  91. **    Returns        1  exact BTREEKEY search possible
  92. **               -1  low lid key provided
  93. **               -2  high lid key provided
  94. **               -3  both lids provided
  95. */
  96.  
  97. btreekey(lkey, hkey)
  98.  
  99. struct key *lkey, *hkey;
  100. {
  101.     register struct key    *l, *h;
  102.     register struct simp    *s;
  103.     int            i, j, k;
  104.     int            provided[MAXLID];
  105.     SYMBOL            *(save[MAXLID]);
  106.  
  107. #    ifdef xOTR1
  108.     if (tTf(85, -1))
  109.         printf("Btreekey\n");
  110. #    endif
  111.  
  112.     l = lkey;
  113.     h = hkey;
  114.     i = 0;
  115.     for (j = 0; j < MAXLID; ++j)
  116.         provided[j] = 0;
  117.     if (De.ov_scanr->reldum.reldim > 0 && De.ov_scanr->reldum.reltups > 0)
  118.     {
  119.         s = De.ov_simp;
  120.         for (j = 0; j < De.ov_nsimp; ++j)
  121.         {
  122.             if (s->att >= De.ov_scanr->reldum.relatts - De.ov_scanr->reldum.reldim + 1)
  123.             {
  124.                 if (s->relop == opEQ || s->relop == opGTGE)
  125.                 {
  126.                     l->keysym = s->cons;
  127.                     l->dnumber = s->att;
  128.                     if (s->relop == opEQ)
  129.                     {
  130.                         provided[De.ov_scanr->reldum.relatts - s->att] = 1;
  131.                         save[De.ov_scanr->reldum.relatts - s->att] = l->keysym;
  132.  
  133.                     }
  134.                     else if (i == -2)
  135.                         i = -3;
  136.                     else if (!i)
  137.                         i = -1;
  138.                     ++l;
  139.                 }
  140.                 if (s->relop == opLTLE)
  141.                 {
  142.                     h->keysym = s->cons;
  143.                     h->dnumber = s->att;
  144.                     h++;
  145.                     if (i == -1)
  146.                         i = -3;
  147.                     else if (!i)
  148.                         i = -2;
  149.                 }
  150.             }
  151.             s++;
  152.             for (k = 0; k < De.ov_scanr->reldum.reldim; ++k)
  153.                 if (!provided[k])
  154.                     break;
  155.             if (k >= De.ov_scanr->reldum.reldim)
  156.             {
  157.                 i = 1;
  158.                 break;
  159.             }
  160.         }
  161.         if (i != 1)
  162.             for (k = 0; k < De.ov_scanr->reldum.reldim; ++k)
  163.                 if (provided[k])
  164.                 {
  165.                     h->keysym = save[k];
  166.                     h->dnumber = De.ov_scanr->reldum.relatts - k;
  167.                     h++;
  168.                     i = -3;
  169.                 }
  170.         /* mark ends of lists */
  171.         l->dnumber = 0;
  172.         h->dnumber = 0;
  173.     }
  174. #    ifdef xOTR1
  175.     if (tTf(85, 9))
  176.         printf("btreekey returning %d\n", i);
  177. #    endif
  178.     return(i);
  179. }
  180. /*
  181. **    Range key checks if the relation described by
  182. **    "ap" is ISAM and there are simple clauses
  183. **    on the first key and any additional keys.
  184. **
  185. **    Rangekey accumulates both high and low keys,
  186. **    which are not necessary the same. If it
  187. **    every finds a high or a low key on the first
  188. **    domain of the relation then success=TRUE.
  189. **
  190. **    Returns  1 if Rangekey ok
  191. **         0 if Rangekey is not ok
  192. **        -1 if Rangekey ok and all clauses are equality clauses
  193. */
  194.  
  195. rangekey(ap, l, h)
  196. struct accessparam    *ap;
  197. struct key        *l;
  198. struct key        *h;
  199. {
  200.     register struct key    *low, *high;
  201.     register struct simp    *s;
  202.     struct accessparam    *a;
  203.     int            sec_indx, d, i;
  204.     int            rel, success, ns, lowkey, allexact;
  205.  
  206. #    ifdef xOTR1
  207.     if (tTf(85, 5))
  208.         printf("Rangekey\n");
  209. #    endif
  210.  
  211.     a = ap;
  212.     sec_indx  = a->sec_index == TRUE;
  213.     low = l;
  214.     high = h;
  215.     allexact = -1;    /* assume all clauses equality clauses */
  216.     s = De.ov_simp;
  217.     success = FALSE;
  218.     if (a->mode == LRANGEKEY)
  219.     {
  220.  
  221.         for (ns = 0; ns < De.ov_nsimp; ns++)
  222.         {
  223.             rel = s->relop;
  224.             for (i = 0; d = a->keydno[i]; i++)
  225.             {
  226.                 if (d == s->att)
  227.                 {
  228.                     /* this is either a high range value or low range value */
  229.                     lowkey = (rel == opGTGE);
  230.                     if (lowkey || rel == opEQ)
  231.                     {
  232.                         /* low range key */
  233. #                        ifdef xOTR1
  234.                         if (tTf(85, 6))
  235.                             printf("low key on dom %d\t", d);
  236. #                        endif
  237.                         low->keysym = s->cons;
  238.                         low->dnumber = sec_indx ? i+1 : d;
  239.                         low++;
  240.                     }
  241.                     if (!lowkey || rel == opEQ)
  242.                     {
  243.                         /* high range key */
  244. #                        ifdef xOTR1
  245.                         if  (tTf(85, 6))
  246.                             printf("high key on dom %d\t", d);
  247. #                        endif
  248.                         high->keysym = s->cons;
  249.                         high->dnumber = sec_indx ? i+1 : d;
  250.                         high++;
  251.                     }
  252. #                    ifdef xOTR1
  253.                     if (tTf(85, 6))
  254.                         prsym(s->cons);
  255. #                    endif
  256.                     if (i == 0)
  257.                         success = TRUE;
  258.                     if (rel != opEQ)
  259.                         allexact = 1;    /* at least one inequality */
  260.                     break;
  261.                 }
  262.             }
  263.             s++;    /* try next simple clause */
  264.         }
  265.     }
  266.  
  267.     high->dnumber = 0;    /* mark end of list */
  268.     low->dnumber = 0;    /* mask end of list */
  269.  
  270.     /* if success then return whether all clauses were equality */
  271.     if (success)
  272.         success = allexact;
  273.  
  274. #    ifdef xOTR1
  275.     if (tTf(85, 5))
  276.         printf("rangekey returning %d\n", success);
  277. #    endif
  278.     return (success);
  279. }
  280. /*
  281. **    Setallkey takes a key struct, decodes it and
  282. **    calls setkey with each value.
  283. **
  284. **    Called from strategy().
  285. **
  286. **    returns 0 if ok.
  287. **    returns -1 in the special case of a deblanked hashkey
  288. **    being bigger than the corresponding domain.
  289. */
  290.  
  291. setallkey(relkey, keytuple)
  292. struct key    *relkey;
  293. char        *keytuple;
  294. {
  295.     register struct key    *k;
  296.     register SYMBOL        *sk;
  297.     register int        dnum;
  298.     struct symbol        **s;
  299.     char            *p, temp[256];
  300.     int            l;
  301.  
  302.     clearkeys(De.ov_scanr);
  303.     k = relkey;
  304.     while (dnum = k->dnumber)
  305.     {
  306.         s = &k->keysym;
  307.         sk = (SYMBOL *) De.ov_stack;
  308.         getsymbol(sk, &s);    /* copy symbol to stack. caution:getsym changes the value of s. */
  309.         rcvt(sk, De.ov_scanr->relfrmt[dnum], De.ov_scanr->relfrml[dnum]);    /* convert key to correct type */
  310.         p = (char *)&sk->value;
  311.  
  312.         if (sk->type == CHAR)
  313.         {
  314.             /*
  315.             ** The length of a character key must
  316.             ** be made equal to the domain length.
  317.             ** The key is copied to a temp place
  318.             ** and a null byte is inserted at the
  319.             ** end. In addition, if the key without
  320.             ** blanks is longer than the domain and
  321.             ** this is an exactkey, then the query
  322.             ** is false.
  323.             */
  324.             p = temp;
  325.             l = cmove(sk, p);    /* copy symbol to temp removing blanks & nulls */
  326. #            ifdef xOTR1
  327.             if (tTf(86, 9))
  328.                 printf("length is %d\n", l);
  329. #            endif
  330.             if (De.ov_fmode == EXACTKEY && l > (De.ov_scanr->relfrml[dnum] & I1MASK))
  331.                 /* key too large. qualification is false */
  332.                 return (-1);
  333.         }
  334.         setkey(De.ov_scanr, keytuple, p, dnum);    /* set the key */
  335.         k++;
  336.     }
  337. #    ifdef xOTR1
  338.     if (tTf(86, 8))
  339.         printup(De.ov_scanr, keytuple);
  340. #    endif
  341.     return (0);
  342. }
  343. /*
  344. **    Cmove copies a char symbol into "dest".
  345. **    It stops when the length is reached or
  346. **    when a null byte is found.
  347. **
  348. **    returns the number of non-blank chars
  349. **    in the string.
  350. */
  351.  
  352. cmove(sym, dest)
  353. SYMBOL    *sym;
  354. char    *dest;
  355. {
  356.     register char    *d, *s;
  357.     register int    l;
  358.     int        blank;
  359.  
  360.     s = sym->value.sym_data.cptype;    /* s points to the char string */
  361.     d = dest;
  362.     blank = 0;
  363.  
  364.     for (l = (sym->len & I1MASK); l--; s++)
  365.     {
  366.         *d++ = *s;
  367.         if (*s == ' ')
  368.             blank++;
  369.         if (*s == '\0')
  370.         {
  371.             d--;
  372.             break;
  373.         }
  374.     }
  375.  
  376.     *d = '\0';
  377.     return ((d - dest) - blank);    /* return length of string */
  378. }
  379. /*
  380. **    Indexcheck is called by scan() to check whether
  381. **    a secondary index tuple satisfies the simple
  382. **    clauses under which it was scanned.
  383. **
  384. **    Returns 1 if the tuple is ok,
  385. **        0 otherwise.
  386. */
  387.  
  388. indexcheck()
  389. {
  390.     register int    i;
  391.  
  392.     if (De.ov_fmode == EXACTKEY)
  393.         i = keycheck(De.ov_lkey_struct, De.ov_keyl, 0);    /* check for equality */
  394.     else
  395.     {
  396.         i = keycheck(De.ov_lkey_struct, De.ov_keyl, 1);    /* check for >= */
  397.         /* If the lowkey passed, check the highkey also */
  398.         if (i)
  399.             i = keycheck(De.ov_hkey_struct, De.ov_keyh, -1);    /* check for <= */
  400.     }
  401. #    ifdef xOTR1
  402.     if (tTf(86, 10))
  403.         printf("indexcheck ret %d\n", i);
  404. #    endif
  405.     return (i);
  406. }
  407. /*
  408. **    Keycheck compares De.ov_intup with keytuple
  409. **    according to the domains specified in the
  410. **    "keys" struct.
  411. **
  412. **    mode is either >0, =0, <0 depending on
  413. **    whether check is for De.ov_intup >= keytuple,
  414. **    De.ov_intup == keytuple, De.ov_intup <= keytuple respectively
  415. **
  416. **    returns TRUE or FALSE accordingly.
  417. */
  418.  
  419. keycheck(keys, keytuple, mode)
  420. struct key    *keys;
  421. char        *keytuple;
  422. int        mode;
  423. {
  424.     register struct key    *k;
  425.     register char        *kp;
  426.     register int        dnum;
  427.     int            offset, i, success;
  428.  
  429.     kp = keytuple;
  430.     success = TRUE;
  431.  
  432.     for (k = keys; dnum = k->dnumber; k++)
  433.     {
  434.  
  435.         offset = De.ov_scanr->reloff[dnum];
  436.         if (i = icompare(&De.ov_intup[offset], &kp[offset], De.ov_scanr->relfrmt[dnum], De.ov_scanr->relfrml[dnum] & I1MASK))
  437.         {
  438.             if (i < 0 && mode < 0 || i > 0 && mode > 0)
  439.                 continue;
  440.             success = FALSE;
  441.             break;
  442.         }
  443.     }
  444.     return (success);
  445. }
  446.