|
|
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.