|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.