1: # include   "../ingres.h"
   2: # include   "../aux.h"
   3: # include   "../catalog.h"
   4: # include   "../symbol.h"
   5: # include   "../tree.h"
   6: # include   "../pipes.h"
   7: # include   "ovqp.h"
   8: # include   "strategy.h"
   9: 
  10: /**
  11: ** STRATEGY
  12: **
  13: **	Attempts to limit access scan to less than the entire Source
  14: **	relation by finding a key which can be used for associative
  15: **	access to the Source reln or an index thereon.  The key is
  16: **	constructed from domain-value specifications found in the
  17: **	clauses of the qualification list using sub-routine findsimp
  18: **	in findsimp.c and other subroutines in file key.c
  19: **/
  20: 
  21: 
  22: 
  23: strategy()
  24: {
  25:     register int            i, allexact;
  26:     struct accessparam      sourceparam, indexparam;
  27:     struct index            itup, rtup;
  28:     struct key          lowikey[MAXKEYS+1], highikey[MAXKEYS+1];
  29:     register struct descriptor  *d;
  30:     extern struct descriptor    Inddes;
  31:     struct descriptor       *openindex();
  32: 
  33: #	ifdef xOTR1
  34:     if (tTf(31, 0))
  35:         printf("STRATEGY\tSource=%.12s\tNewq = %d\n", Source ? Source->relid : "(none)", Newq);
  36: #	endif
  37: 
  38:     while (Newq)    /* if Newq=TRUE then compute a new strategy */
  39:             /* NOTE: This while loop is executed only once */
  40:     {
  41:         Scanr = Source;
  42: 
  43:         if (!Scanr)
  44:             return (1); /* return immediately if there is no source relation */
  45: 
  46:         Fmode = NOKEY;  /* assume a find mode with no key */
  47: 
  48:         if (!Qlist)
  49:             break;  /* if no qualification then you must scan entire rel */
  50: 
  51:         /* copy structure of source relation into sourceparam */
  52:         paramd(Source, &sourceparam);
  53: 
  54:         /* if source is unkeyed and has no sec index then give up */
  55:         if (sourceparam.mode == NOKEY && Source->relindxd <= 0)
  56:             break;
  57: 
  58:         /* find all simple clauses if any */
  59:         if (!findsimps())
  60:             break;  /* break if there are no simple clauses */
  61: 
  62:         /* Four steps are now performed to try and find a key.
  63: 		** First if the relation is hashed then an exact key is search for
  64: 		**
  65: 		** Second if there are secondary indexes, then a search is made
  66: 		** for an exact key. If that fails then a  check is made for
  67: 		** a range key. The result of the rangekey check is saved.
  68: 		**
  69: 		** Third if the relation is an ISAM a check is  made for
  70: 		** an exact key or a range key.
  71: 		**
  72: 		** Fourth if there is a secondary index, then if step two
  73: 		** found a key, that key is used.
  74: 		**
  75: 		**  Lastly, give up and scan the  entire relation
  76: 		*/
  77: 
  78:         /* step one. Try to find exact key on primary */
  79:         if (exactkey(&sourceparam, &Lkey_struct))
  80:         {
  81:             Fmode = EXACTKEY;
  82:             break;
  83:         }
  84: 
  85:         /* step two. If there is an index, try to find an exactkey on one of them */
  86:         if (Source->relindxd)
  87:         {
  88: 
  89:             opencatalog("indexes", 0);
  90:             setkey(&Inddes, &itup, Source->relid, IRELIDP);
  91:             setkey(&Inddes, &itup, Source->relowner, IOWNERP);
  92:             if (i = find(&Inddes, EXACTKEY, &Lotid, &Hitid, &itup))
  93:                 syserr("strategy:find indexes %d", i);
  94: 
  95:             while (!(i = get(&Inddes, &Lotid, &Hitid, &itup, NXTTUP)))
  96:             {
  97: #				ifdef xOTR1
  98:                 if (tTf(31, 3))
  99:                     printup(&Inddes, &itup);
 100: #				endif
 101:                 if (!bequal(itup.irelidp, Source->relid, MAXNAME) ||
 102:                     !bequal(itup.iownerp, Source->relowner, 2))
 103:                     continue;
 104:                 parami(&itup, &indexparam);
 105:                 if (exactkey(&indexparam, &Lkey_struct))
 106:                 {
 107:                     Fmode = EXACTKEY;
 108:                     d = openindex(itup.irelidi);
 109:                     /* temp check for 6.0 index */
 110:                     if (d->relindxd == -1)
 111:                         ov_err(BADSECINDX);
 112:                     Scanr = d;
 113:                     break;
 114:                 }
 115:                 if (Fmode == LRANGEKEY)
 116:                     continue;   /* a range key on a s.i. has already been found */
 117:                 if (allexact = rangekey(&indexparam, &lowikey, &highikey))
 118:                 {
 119:                     bmove(&itup, &rtup, sizeof itup);   /* save tuple */
 120:                     Fmode = LRANGEKEY;
 121:                 }
 122:             }
 123:             if (i < 0)
 124:                 syserr("stragery:bad get from index-rel %d", i);
 125:             /* If an exactkey on a secondary index was found, look no more. */
 126:             if (Fmode == EXACTKEY)
 127:                 break;
 128:         }
 129: 
 130: 
 131:         /* step three. Look for a range key on primary */
 132:         if (i = rangekey(&sourceparam, &Lkey_struct, &Hkey_struct))
 133:         {
 134:             if (i < 0)
 135:                 Fmode = EXACTKEY;
 136:             else
 137:                 Fmode = LRANGEKEY;
 138:             break;
 139:         }
 140: 
 141:         /* last step. If a secondary index range key was found, use it */
 142:         if (Fmode == LRANGEKEY)
 143:         {
 144:             if (allexact < 0)
 145:                 Fmode = EXACTKEY;
 146:             d = openindex(rtup.irelidi);
 147:             /* temp check for 6.0 index */
 148:             if (d->relindxd == -1)
 149:                 ov_err(BADSECINDX);
 150:             Scanr = d;
 151:             bmove(&lowikey, &Lkey_struct, sizeof lowikey);
 152:             bmove(&highikey, &Hkey_struct, sizeof highikey);
 153:             break;
 154:         }
 155: 
 156:         /* nothing will work. give up! */
 157:         break;
 158: 
 159:     }
 160: 
 161:     /* check for Newq = FALSE and no source relation */
 162:     if (!Scanr)
 163:         return (1);
 164:     /*
 165: 	** At this point the strategy is determined.
 166: 	**
 167: 	** If Fmode is EXACTKEY then Lkey_struct contains
 168: 	** the pointers to the keys.
 169: 	**
 170: 	** If Fmode is LRANGEKEY then Lkey_struct contains
 171: 	** the pointers to the low keys and Hkey_struct
 172: 	** contains pointers to the high keys.
 173: 	**
 174: 	** If Fmode is NOKEY, then a full scan will be performed
 175: 	*/
 176: #	ifdef xOTR1
 177:     if (tTf(31, -1))
 178:         printf("Fmode= %d\n",Fmode);
 179: #	endif
 180: 
 181:     /* set up the key tuples */
 182:     if (Fmode != NOKEY)
 183:     {
 184:         if (setallkey(&Lkey_struct, Keyl))
 185:             return (0); /* query false. There is a simple
 186: 					** clause which can never be satisfied.
 187: 					** These simple clauses can be choosey!
 188: 					*/
 189:     }
 190: 
 191:     if (i = find(Scanr, Fmode, &Lotid, &Hitid, Keyl))
 192:         syserr("strategy:find1 %.12s, %d", Scanr->relid, i);
 193: 
 194:     if (Fmode == LRANGEKEY)
 195:     {
 196:         setallkey(&Hkey_struct, Keyh);
 197:         if (i = find(Scanr, HRANGEKEY, &Lotid, &Hitid, Keyh))
 198:             syserr("strategy:find2 %.12s, %d", Scanr->relid, i);
 199:     }
 200: 
 201: #	ifdef xOTR1
 202:     if (tTf(31, 1))
 203:     {
 204:         printf("Lo");
 205:         dumptid(&Lotid);
 206:         printf("Hi");
 207:         dumptid(&Hitid);
 208:     }
 209: #	endif
 210: 
 211:     return (1);
 212: }

Defined functions

Last modified: 1995-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3096
Valid CSS Valid XHTML 1.0 Strict