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