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