1: # include   "../ingres.h"
   2: # include   "../symbol.h"
   3: # include   "../tree.h"
   4: # include   "../pipes.h"
   5: # include   "ovqp.h"
   6: # include   "strategy.h"
   7: 
   8: /*
   9: **	Findsimps searches the qualification for
  10: **	occurances of simple clauses. In its
  11: **	current crude implementation it only finds
  12: **	cluases of the form:
  13: **
  14: **	var relop constant  or  constant relop var
  15: **
  16: **	it does not use simple clauses with 'OR's
  17: **	nor does it accept clauses of the form
  18: **
  19: **	var relop constant + constant    etc.
  20: **
  21: **	Findsimps knows about pattern matching characters
  22: **	and treats char constants containing pm chars
  23: **	specially. For example
  24: **		var >= "xx*"  --> var >= "xx"
  25: **		var <= "xx*"  --> var <= "xx\0177"
  26: **		var =  "xx*"  --> var >= "xx" and var <= "xx\0177"
  27: **	If the first char is a pm char then the clause is not
  28: **	considered as a simple clause. Also notice that the conversion
  29: **	is done only once. If the next time Newq = FALSE, then findsimps()
  30: **	isn't called. This works because a pm char can only come from
  31: **	the user and not from a relation. Thus during tuple substition
  32: **	a constant with a pm will never change.
  33: */
  34: 
  35: findsimps()
  36: {
  37:     register struct symbol  *c;
  38:     register int        t;
  39:     int         length;
  40:     register struct symbol  **q;
  41:     int         attno, rel, found;
  42:     struct symbol       *cpsym(), *xc;
  43: 
  44: #	ifdef xOTR1
  45:     if (tTf(21, 0))
  46:         printf("FINDSIMPS\n");
  47: #	endif
  48:     Nsimp = 0;
  49:     found = FALSE;
  50:     q = Qlist;  /* q holds pointer to qualification */
  51: 
  52:     if (!q)
  53:         return (0);
  54: 
  55: 
  56:     for (t = (*q)->type & 0377; t != QLEND; t = (*++q)->type & 0377)
  57:     {
  58:         switch (t)
  59:         {
  60:           case VAR:
  61:             attno = *(*q)->value & 0377;    /* save att number */
  62:             if ((t = (*++q)->type & 0377) == INT
  63:                || t == FLOAT || t == CHAR || t == S_VAR)
  64:             {
  65:                 c = *q; /* save pointer to value symbol */
  66:                 t = (*++q)->type & 0377;
  67:                 if ((rel = relop(*q, FALSE)) >= 0
  68:                    && (t = (*++q)->type & 0377) == AND)
  69:                 {
  70:                     /* found a simple clause */
  71:                     found = TRUE;
  72:                 }
  73:             }
  74:             break;
  75: 
  76:           case S_VAR:
  77:           case INT:
  78:           case FLOAT:
  79:           case CHAR:
  80:             c = *q++;
  81:             if ((t = (*q)->type & 0377) == VAR)
  82:             {
  83:                 attno = *(*q)->value & 0377;
  84:                 t = (*++q)->type & 0377;
  85:                 if ((rel = relop(*q, TRUE)) >= 0 && (t = (*++q)->type & 0377) == AND)
  86:                 {
  87:                     /* found a simple clause */
  88:                     found = TRUE;
  89:                 }
  90:             }
  91:         }
  92:         if (found)
  93:         {
  94:             /* a simple clause has been found.
  95: 			** Check that the constant contains
  96: 			** at least one char before any pattern
  97: 			** matching char. If there is a pattern
  98: 			** matching char then special processing
  99: 			** must be done.
 100: 			*/
 101: 
 102:             found = FALSE;
 103:             if (length = check(c))
 104:             {
 105: 
 106:                 /*
 107: 				** If length is zero then the first char was
 108: 				** a pattern matching char. If length < 0 then
 109: 				** no pattern matching char, and finally
 110: 				** if length > 0 then length is the number of
 111: 				** chars before the first pattern matching char
 112: 				*/
 113:                 if (length > 0)
 114:                 {
 115:                     switch (rel)
 116:                     {
 117: 
 118:                       case opEQ:
 119:                         /*
 120: 						** Create two simple clauses:
 121: 						** One below the value and the
 122: 						** other above the value.
 123: 						*/
 124:                         xc = cpsym(c, length, opLTLE);
 125:                         add_simp(xc, opLTLE, attno);
 126:                         rel = opGTGE;
 127:                         /* fall through to GTGE case */
 128: 
 129:                       case opGTGE:
 130:                         c = cpsym(c, length, opGTGE);
 131:                         break;
 132: 
 133:                       case opLTLE:
 134:                         c = cpsym(c, length, opLTLE);
 135:                         break;
 136:                     }
 137:                 }
 138: 
 139:                 if (add_simp(c, rel, attno))
 140:                     break;  /* no more room in simps */
 141:             }
 142:         }
 143:         while (t != AND)    /* skip to next AND */
 144:             t = (*++q)->type & 0377;
 145:     }
 146: #	ifdef xOTR1
 147:     if (tTf(21, 2))
 148:         printf("findsimps returning %d\n", Nsimp);
 149: #	endif
 150:     return (Nsimp);
 151: }
 152: 
 153: 
 154: relop(s, reverse)
 155: struct symbol   *s;
 156: int     reverse;
 157: 
 158: /*
 159: **	relop determines whether a symbol is a
 160: **	usable relational operator ie. =,>,>=,<,<=
 161: **
 162: **	returns the type of the relational
 163: **	operator if found, else it returns
 164: **	-1
 165: **
 166: **	Items are normalized to be in the form:
 167: **	var relop constant. If reverse is TRUE then
 168: **	complement the sense of the relop. Reverse will
 169: **	be TRUE is the simple clause was found in the
 170: **	form constant relop var.
 171: */
 172: 
 173: {
 174:     register int    v;
 175: 
 176:     v = -1; /* assume failure */
 177:     if (s->type == BOP)
 178:     {
 179:         switch (*s->value & 0377)
 180:         {
 181: 
 182:           case opEQ:
 183:             v = opEQ;
 184:             break;
 185: 
 186:           case opLT:
 187:           case opLE:
 188:             v = opLTLE;
 189:             if (reverse)
 190:                 v = opGTGE;
 191:             break;
 192: 
 193:           case opGT:
 194:           case opGE:
 195:             v = opGTGE;
 196:             if (reverse)
 197:                 v = opLTLE;
 198:             break;
 199: 
 200:         }
 201:     }
 202:     return (v);
 203: }
 204: 
 205: 
 206: 
 207: check(sym)
 208: struct symbol   *sym;
 209: 
 210: /*
 211: **	check checks the symbol for
 212: **	pattern matching characters.
 213: **	If any are found then check returns
 214: **	the number of characters before the
 215: **	first pattern matching character.
 216: **
 217: **	If no pattern matching chars are found
 218: **	then check returns -1.
 219: **
 220: **	note that PAT_RBRAC need not be checked for
 221: **	since it is not a pattern matching char unless
 222: **	PAT_LBRAC appears before it.
 223: **
 224: **	PAT_LBRAC is treated specially in cpsym().
 225: **	If any are detected, then length until the
 226: **	first PAT_ANY or PAT_ONE is returned.
 227: */
 228: 
 229: {
 230:     register struct symbol  *s;
 231:     register char       *cp;
 232:     register int        len;
 233:     int         flag;
 234: 
 235:     s = sym;
 236: #	ifdef xOTR1
 237:     if (tTf(21, 4))
 238:     {
 239:         printf("Checksym:");
 240:         prsym(s);
 241:     }
 242: #	endif
 243:     if (s->type == CHAR)
 244:     {
 245:         flag = FALSE;
 246:         cp = (char *) s->value; /* the string is a literal */
 247:         len = s->len & 0377;
 248:         while (len--)
 249:         {
 250:             switch(*cp++)
 251:             {
 252: 
 253:               case PAT_ANY:
 254:               case PAT_ONE:
 255:                 return ((s->len & 0377) - len - 1);
 256: 
 257:               case PAT_LBRAC:
 258:                 flag = TRUE;
 259: 
 260:             }
 261:         }
 262:         if (flag)
 263:             return (s->len & 0377); /* constant had PAT_LBRAC char */
 264:     }
 265:     return (-1);    /* ok */
 266: }
 267: 
 268: 
 269: struct symbol *cpsym(const, len, op)
 270: struct symbol   *const;
 271: int     len;
 272: int     op;
 273: 
 274: /*
 275: ** Cpsym -- copy a symbol to a new buffer area.
 276: **	If op is opLTLE then add a pad character
 277: **	whose value is the largest possible char
 278: **	value.
 279: **
 280: **	If any ranges of characters are found,
 281: **	then the lowest/highest char is taken from
 282: **	range.
 283: */
 284: 
 285: {
 286:     register struct symbol  *s;
 287:     register char       *cp;
 288:     register int        i;
 289:     char            *sp, c, nc;
 290:     extern char     *Ovqpbuf;
 291:     extern char     *need();
 292: 
 293:     i = len;
 294:     s = (struct symbol *) need(Ovqpbuf, op == opLTLE ? i + 3 : i + 2);
 295:     s->type = CHAR;
 296:     sp = (char *) s->value;
 297:     cp = (char *) const->value;
 298: 
 299:     while (i--)
 300:     {
 301:         /* copy chars processing LBRAC chars if any */
 302:         if ((c = *cp++) == PAT_LBRAC)
 303:         {
 304:             /* if string is empty, ignore it */
 305:             if (i == 0)
 306:                 break;
 307: 
 308:             c = *cp++;
 309:             i--;
 310: 
 311:             if (c == PAT_RBRAC)
 312:                 continue;   /* empty [] */
 313: 
 314:             while (i-- && ((nc = *cp++) != PAT_RBRAC))
 315:             {
 316:                 /* ignore '-' */
 317:                 if (nc == '-')
 318:                     continue;
 319: 
 320:                 /* check for char larger/smaller than 'c' */
 321:                 if (op == opLTLE)
 322:                 {
 323:                     if (nc > c)
 324:                         c = nc;
 325:                 }
 326:                 else
 327:                 {
 328:                     if (nc < c)
 329:                         c = nc;
 330:                 }
 331:             }
 332:         }
 333: 
 334:         *sp++ = c;  /* copy next char */
 335:     }
 336:     if (op == opLTLE)
 337:         *sp++ = 0177;
 338:     s->len = sp - s->value;
 339: 
 340:     return (s);
 341: }
 342: 
 343: 
 344: add_simp(const, rel, attno)
 345: struct symbol   *const;
 346: int     rel;
 347: int     attno;
 348: 
 349: /*
 350: ** Add_simp -- add a simple clause to the list of
 351: **	simple clauses. As a side effect the Nsimp
 352: **	is incremented. If there is no room return
 353: **	TRUE else return FALSE
 354: */
 355: 
 356: {
 357:     register struct symbol  *s;
 358: 
 359:     if (Nsimp == NSIMP)
 360:         return (TRUE);  /* no more room */
 361: 
 362:     s = (struct symbol *) &Simp[Nsimp++];
 363: 
 364:     ((struct simp *)s)->att = attno;
 365:     ((struct simp *)s)->const = const;
 366:     ((struct simp *)s)->relop = rel;
 367: 
 368: #	ifdef xOTR1
 369:     if (tTf(21, 3))
 370:         prsimp(s);
 371: #	endif
 372: 
 373:     return (FALSE);
 374: }
 375: 
 376: 
 377: prsimp(ss)
 378: struct simp *ss;
 379: {
 380: #	ifdef xOTR1
 381:     struct simp *s;
 382: 
 383:     s = ss;
 384:     printf("simp:relop=%d,att=%d,val=", s->relop, s->att);
 385:     prsym(s->const);
 386: #	endif
 387: }

Defined functions

add_simp defined in line 344; used 2 times
check defined in line 207; used 1 times
cpsym defined in line 269; used 4 times
findsimps defined in line 35; used 1 times
prsimp defined in line 377; used 1 times
relop defined in line 154; used 4 times
Last modified: 1995-03-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3453
Valid CSS Valid XHTML 1.0 Strict