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->const;
  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->const);
  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->const;
 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->const;
 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->const;
 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->const;
 249:                         high->dnumber = sec_indx ? i+1 : d;
 250:                         high++;
 251:                     }
 252: #					ifdef xOTR1
 253:                     if (tTf(85, 6))
 254:                         prsym(s->const);
 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: }

Defined functions

btreekey defined in line 97; used 1 times
cmove defined in line 352; used 1 times
exactkey defined in line 11; used 2 times
indexcheck defined in line 388; used 1 times
keycheck defined in line 419; used 3 times
rangekey defined in line 195; used 2 times
setallkey defined in line 291; used 4 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1365
Valid CSS Valid XHTML 1.0 Strict