|
|
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 7.1 2/5/81) ! 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 & 0377; ! 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: relop(s, reverse) ! 157: struct symbol *s; ! 158: int reverse; ! 159: ! 160: /* ! 161: ** relop determines whether a symbol is a ! 162: ** usable relational operator ie. =,>,>=,<,<= ! 163: ** ! 164: ** returns the type of the relational ! 165: ** operator if found, else it returns ! 166: ** -1 ! 167: ** ! 168: ** Items are normalized to be in the form: ! 169: ** var relop constant. If reverse is TRUE then ! 170: ** complement the sense of the relop. Reverse will ! 171: ** be TRUE is the simple clause was found in the ! 172: ** form constant relop var. ! 173: */ ! 174: ! 175: { ! 176: register int v; ! 177: ! 178: v = -1; /* assume failure */ ! 179: if (s->type == BOP) ! 180: { ! 181: switch (s->value.sym_op.opno) ! 182: { ! 183: ! 184: case opEQ: ! 185: v = opEQ; ! 186: break; ! 187: ! 188: case opLT: ! 189: case opLE: ! 190: v = opLTLE; ! 191: if (reverse) ! 192: v = opGTGE; ! 193: break; ! 194: ! 195: case opGT: ! 196: case opGE: ! 197: v = opGTGE; ! 198: if (reverse) ! 199: v = opLTLE; ! 200: break; ! 201: ! 202: } ! 203: } ! 204: return (v); ! 205: } ! 206: ! 207: ! 208: ! 209: check(sym) ! 210: struct symbol *sym; ! 211: ! 212: /* ! 213: ** check checks the symbol for ! 214: ** pattern matching characters. ! 215: ** If any are found then check returns ! 216: ** the number of characters before the ! 217: ** first pattern matching character. ! 218: ** ! 219: ** If no pattern matching chars are found ! 220: ** then check returns -1. ! 221: ** ! 222: ** note that PAT_RBRAC need not be checked for ! 223: ** since it is not a pattern matching char unless ! 224: ** PAT_LBRAC appears before it. ! 225: ** ! 226: ** PAT_LBRAC is treated specially in cpsym(). ! 227: ** If any are detected, then length until the ! 228: ** first PAT_ANY or PAT_ONE is returned. ! 229: */ ! 230: ! 231: { ! 232: register struct symbol *s; ! 233: register char *cp; ! 234: register int len; ! 235: int flag; ! 236: ! 237: s = sym; ! 238: # ifdef xOTR1 ! 239: if (tTf(81, 4)) ! 240: { ! 241: printf("Checksym:"); ! 242: prsym(s); ! 243: } ! 244: # endif ! 245: if (s->type == CHAR) ! 246: { ! 247: flag = FALSE; ! 248: cp = s->value.sym_data.c0type; /* the string is a literal */ ! 249: len = s->len & 0377; ! 250: while (len--) ! 251: { ! 252: switch(*cp++) ! 253: { ! 254: ! 255: case PAT_ANY: ! 256: case PAT_ONE: ! 257: return ((s->len & 0377) - len - 1); ! 258: ! 259: case PAT_LBRAC: ! 260: flag = TRUE; ! 261: ! 262: } ! 263: } ! 264: if (flag) ! 265: return (s->len & 0377); /* constant had PAT_LBRAC char */ ! 266: } ! 267: return (-1); /* ok */ ! 268: } ! 269: ! 270: ! 271: struct symbol ! 272: *cpsym(const, len, op) ! 273: struct symbol *const; ! 274: int len; ! 275: int op; ! 276: ! 277: /* ! 278: ** Cpsym -- copy a symbol to a new buffer area. ! 279: ** If op is opLTLE then add a pad character ! 280: ** whose value is the largest possible char ! 281: ** value. ! 282: ** ! 283: ** If any ranges of characters are found, ! 284: ** then the lowest/highest char is taken from ! 285: ** range. ! 286: */ ! 287: ! 288: { ! 289: register struct symbol *s; ! 290: register char *cp; ! 291: register int i; ! 292: char *sp, c, nc; ! 293: extern char *ov_ovqpbuf; ! 294: char *need(); ! 295: ! 296: i = len; ! 297: s = (struct symbol *)need(De.ov_ovqpbuf, op == opLTLE ? i + 3 : i + 2); ! 298: s->type = CHAR; ! 299: sp = s->value.sym_data.c0type; ! 300: cp = const->value.sym_data.c0type; ! 301: ! 302: while (i--) ! 303: { ! 304: /* copy chars processing LBRAC chars if any */ ! 305: if ((c = *cp++) == PAT_LBRAC) ! 306: { ! 307: /* if string is empty, ignore it */ ! 308: if (i == 0) ! 309: break; ! 310: ! 311: c = *cp++; ! 312: i--; ! 313: ! 314: if (c == PAT_RBRAC) ! 315: continue; /* empty [] */ ! 316: ! 317: while (i-- && ((nc = *cp++) != PAT_RBRAC)) ! 318: { ! 319: /* ignore '-' */ ! 320: if (nc == '-') ! 321: continue; ! 322: ! 323: /* check for char larger/smaller than 'c' */ ! 324: if (op == opLTLE) ! 325: { ! 326: if (nc > c) ! 327: c = nc; ! 328: } ! 329: else ! 330: { ! 331: if (nc < c) ! 332: c = nc; ! 333: } ! 334: } ! 335: } ! 336: ! 337: *sp++ = c; /* copy next char */ ! 338: } ! 339: if (op == opLTLE) ! 340: *sp++ = 0177; ! 341: s->len = sp - s->value.sym_data.c0type; ! 342: ! 343: return (s); ! 344: } ! 345: ! 346: ! 347: add_simp(const, rel, attno) ! 348: struct symbol *const; ! 349: int rel; ! 350: int attno; ! 351: ! 352: /* ! 353: ** Add_simp -- add a simple clause to the list of ! 354: ** simple clauses. As a side effect the De.ov_nsimp ! 355: ** is incremented. If there is no room return ! 356: ** TRUE else return FALSE ! 357: */ ! 358: ! 359: { ! 360: register struct simp *s; ! 361: ! 362: if (De.ov_nsimp == NSIMP) ! 363: return (TRUE); /* no more room */ ! 364: ! 365: s = &De.ov_simp[De.ov_nsimp++]; ! 366: ! 367: s->att = attno; ! 368: s->const = const; ! 369: s->relop = rel; ! 370: ! 371: # ifdef xOTR1 ! 372: if (tTf(81, 3)) ! 373: prsimp(s); ! 374: # endif ! 375: ! 376: return (FALSE); ! 377: } ! 378: ! 379: ! 380: prsimp(ss) ! 381: struct simp *ss; ! 382: { ! 383: # ifdef xOTR1 ! 384: struct simp *s; ! 385: ! 386: s = ss; ! 387: printf("simp:relop=%d,att=%d,val=", s->relop, s->att); ! 388: prsym(s->const); ! 389: # endif ! 390: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.