1: # include   <ingres.h>
   2: # include   <symbol.h>
   3: # include   <tree.h>
   4: # include   "../decomp/globs.h"
   5: # include   "strategy.h"
   6: # include   <sccs.h>
   7: 
   8: SCCSID(@(#)findsimps.c	8.4	4/13/85)
   9: 
  10: /*
  11: **	Findsimps searches the qualification for
  12: **	occurances of simple clauses. In its
  13: **	current crude implementation it only finds
  14: **	cluases of the form:
  15: **
  16: **	var relop constant  or  constant relop var
  17: **
  18: **	it does not use simple clauses with 'OR's
  19: **	nor does it accept clauses of the form
  20: **
  21: **	var relop constant + constant    etc.
  22: **
  23: **	Findsimps knows about pattern matching characters
  24: **	and treats char constants containing pm chars
  25: **	specially. For example
  26: **		var >= "xx*"  --> var >= "xx"
  27: **		var <= "xx*"  --> var <= "xx\0177"
  28: **		var =  "xx*"  --> var >= "xx" and var <= "xx\0177"
  29: **	If the first char is a pm char then the clause is not
  30: **	considered as a simple clause. Also notice that the conversion
  31: **	is done only once. If the next time De.ov_newq = FALSE, then findsimps()
  32: **	isn't called. This works because a pm char can only come from
  33: **	the user and not from a relation. Thus during tuple substition
  34: **	a constant with a pm will never change.
  35: */
  36: 
  37: findsimps()
  38: {
  39:     register struct symbol  *c;
  40:     register int        t;
  41:     int         length;
  42:     register struct symbol  **q;
  43:     int         attno, rel, found;
  44:     struct symbol       *cpsym(), *xc;
  45: 
  46: #	ifdef xOTR1
  47:     if (tTf(81, 0))
  48:         printf("FINDSIMPS\n");
  49: #	endif
  50:     De.ov_nsimp = 0;
  51:     found = FALSE;
  52:     q = De.ov_qlist;    /* q holds pointer to qualification */
  53: 
  54:     if (!q)
  55:         return (0);
  56: 
  57: 
  58:     for (t = (*q)->type; t != QLEND; t = (*++q)->type)
  59:     {
  60:         switch (t)
  61:         {
  62:           case VAR:
  63:             attno = (*q)->value.sym_var.attno;  /* save att number */
  64:             t = (*++q)->type;
  65:             if (t == INT || t == FLOAT || t == CHAR || t == S_VAR)
  66:             {
  67:                 c = *q; /* save pointer to value symbol */
  68:                 t = (*++q)->type;
  69:                 if ((rel = relop(*q, FALSE)) >= 0
  70:                    && (t = (*++q)->type) == AND)
  71:                 {
  72:                     /* found a simple clause */
  73:                     found = TRUE;
  74:                 }
  75:             }
  76:             break;
  77: 
  78:           case S_VAR:
  79:           case INT:
  80:           case FLOAT:
  81:           case CHAR:
  82:             c = *q++;
  83:             if ((t = (*q)->type) == VAR)
  84:             {
  85:                 attno = (*q)->value.sym_var.attno;
  86:                 t = (*++q)->type;
  87:                 if ((rel = relop(*q, TRUE)) >= 0 && (t = (*++q)->type) == AND)
  88:                 {
  89:                     /* found a simple clause */
  90:                     found = TRUE;
  91:                 }
  92:             }
  93:         }
  94:         if (found)
  95:         {
  96:             /* a simple clause has been found.
  97: 			** Check that the constant contains
  98: 			** at least one char before any pattern
  99: 			** matching char. If there is a pattern
 100: 			** matching char then special processing
 101: 			** must be done.
 102: 			*/
 103: 
 104:             found = FALSE;
 105:             if (length = check(c))
 106:             {
 107: 
 108:                 /*
 109: 				** If length is zero then the first char was
 110: 				** a pattern matching char. If length < 0 then
 111: 				** no pattern matching char, and finally
 112: 				** if length > 0 then length is the number of
 113: 				** chars before the first pattern matching char
 114: 				*/
 115:                 if (length > 0)
 116:                 {
 117:                     switch (rel)
 118:                     {
 119: 
 120:                       case opEQ:
 121:                         /*
 122: 						** Create two simple clauses:
 123: 						** One below the value and the
 124: 						** other above the value.
 125: 						*/
 126:                         xc = cpsym(c, length, opLTLE);
 127:                         add_simp(xc, opLTLE, attno);
 128:                         rel = opGTGE;
 129:                         /* fall through to GTGE case */
 130: 
 131:                       case opGTGE:
 132:                         c = cpsym(c, length, opGTGE);
 133:                         break;
 134: 
 135:                       case opLTLE:
 136:                         c = cpsym(c, length, opLTLE);
 137:                         break;
 138:                     }
 139:                 }
 140: 
 141:                 if (add_simp(c, rel, attno))
 142:                     break;  /* no more room in simps */
 143:             }
 144:         }
 145:         while (t != AND)    /* skip to next AND */
 146:             t = (*++q)->type & I1MASK;
 147:     }
 148: #	ifdef xOTR1
 149:     if (tTf(81, 2))
 150:         printf("findsimps returning %d\n", De.ov_nsimp);
 151: #	endif
 152:     return (De.ov_nsimp);
 153: }
 154: 
 155: 
 156: /*
 157: **	relop determines whether a symbol is a
 158: **	usable relational operator ie. =,>,>=,<,<=
 159: **
 160: **	returns the type of the relational
 161: **	operator if found, else it returns
 162: **	-1
 163: **
 164: **	Items are normalized to be in the form:
 165: **	var relop constant. If reverse is TRUE then
 166: **	complement the sense of the relop. Reverse will
 167: **	be TRUE is the simple clause was found in the
 168: **	form constant relop var.
 169: */
 170: relop(s, reverse)
 171: struct symbol   *s;
 172: int     reverse;
 173: {
 174:     register int    v;
 175: 
 176:     v = -1; /* assume failure */
 177:     if (s->type == BOP)
 178:     {
 179:         switch (s->value.sym_op.opno)
 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: /*
 208: **	check checks the symbol for
 209: **	pattern matching characters.
 210: **	If any are found then check returns
 211: **	the number of characters before the
 212: **	first pattern matching character.
 213: **
 214: **	If no pattern matching chars are found
 215: **	then check returns -1.
 216: **
 217: **	note that PAT_RBRAC need not be checked for
 218: **	since it is not a pattern matching char unless
 219: **	PAT_LBRAC appears before it.
 220: **
 221: **	PAT_LBRAC is treated specially in cpsym().
 222: **	If any are detected, then length until the
 223: **	first PAT_ANY or PAT_ONE or PAT_SPEC is returned.
 224: */
 225: check(sym)
 226: struct symbol   *sym;
 227: {
 228:     register struct symbol  *s;
 229:     register char       *cp;
 230:     register int        len;
 231:     int         flag;
 232: 
 233:     s = sym;
 234: #	ifdef xOTR1
 235:     if (tTf(81, 4))
 236:     {
 237:         printf("Checksym:");
 238:         prsym(s);
 239:     }
 240: #	endif
 241:     if (s->type == CHAR)
 242:     {
 243:         flag = FALSE;
 244:         cp = s->value.sym_data.c0type;  /* the string is a literal */
 245:         len = s->len & I1MASK;
 246:         while (len--)
 247:         {
 248:             switch(*cp++)
 249:             {
 250: 
 251:               case PAT_ANY:
 252:               case PAT_ONE:
 253:               case PAT_SPEC:
 254:                 return ((s->len & I1MASK) - len - 1);
 255: 
 256:               case PAT_LBRAC:
 257:                 flag = TRUE;
 258: 
 259:             }
 260:         }
 261:         if (flag)
 262:             return (s->len & I1MASK);   /* constant had PAT_LBRAC char */
 263:     }
 264:     return (-1);    /* ok */
 265: }
 266: 
 267: 
 268: /*
 269: ** Cpsym -- copy a symbol to a new buffer area.
 270: **	If op is opLTLE then add a pad character
 271: **	whose value is the largest possible char
 272: **	value.
 273: **
 274: **	If any ranges of characters are found,
 275: **	then the lowest/highest char is taken from
 276: **	range.
 277: */
 278: 
 279: struct symbol
 280: *cpsym(const, len, op)
 281: struct symbol   *const;
 282: int     len;
 283: int     op;
 284: {
 285:     register struct symbol  *s;
 286:     register char       *cp;
 287:     register int        i;
 288:     char            *sp, c, nc;
 289:     extern char     *ov_ovqpbuf;
 290:     char            *need();
 291: 
 292:     i = len;
 293:     s = (struct symbol *)
 294:         need(De.ov_ovqpbuf, op == opLTLE ? i + SYMOFF+1 : i + SYMOFF);
 295:     s->type = CHAR;
 296:     sp = s->value.sym_data.c0type;
 297:     cp = const->value.sym_data.c0type;
 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.sym_data.c0type;
 339: 
 340:     return (s);
 341: }
 342: 
 343: 
 344: 
 345: /*
 346: ** Add_simp -- add a simple clause to the list of
 347: **	simple clauses. As a side effect the De.ov_nsimp
 348: **	is incremented. If there is no room return
 349: **	TRUE else return FALSE
 350: */
 351: 
 352: add_simp(const, rel, attno)
 353: struct symbol   *const;
 354: int     rel;
 355: int     attno;
 356: {
 357:     register struct simp    *s;
 358: 
 359:     if (De.ov_nsimp == NSIMP)
 360:         return (TRUE);  /* no more room */
 361: 
 362:     s = &De.ov_simp[De.ov_nsimp++];
 363: 
 364:     s->att = attno;
 365:     s->const = const;
 366:     s->relop = rel;
 367: 
 368: #	ifdef xOTR1
 369:     if (tTf(81, 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 352; used 2 times
check defined in line 225; used 1 times
cpsym defined in line 279; used 4 times
findsimps defined in line 8; used 1 times
prsimp defined in line 377; used 1 times
relop defined in line 170; used 6 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1157
Valid CSS Valid XHTML 1.0 Strict