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: }