|
|
1.1 root 1: # include <ingres.h>
2: # include <aux.h>
3: # include <symbol.h>
4: # include <tree.h>
5: # include <access.h>
6: # include "../decomp/globs.h"
7: # include <sccs.h>
8:
9: SCCSID(@(#)interp.c 7.3 3/6/81)
10:
11:
12:
13: /*
14: **
15: ** INTERPRET
16: **
17: ** Processes the retrieved tuple from the De.ov_source relation
18: ** according to the symbols in the list. Recognition
19: ** of characteristic delimiters and separators initiates
20: ** action appropriate to a target list or qualification list
21: ** as the case may be.
22: **
23: ** Between delimiters, the symbol list is expected to be in
24: ** Polish postfix form. A qualification list is further
25: ** expected to be in conjunctive normal form, with Boolean
26: ** operators infixed.
27: **
28: */
29:
30:
31: double pow();
32: double sqrt();
33: double log();
34: double exp();
35: double sin();
36: double cos();
37: double atan();
38:
39: # define SPUSH(v) (++((struct stacksym *) v))
40: # define SPOP(v) (((struct stacksym *) v)--)
41:
42: SYMBOL *
43: interpret(list)
44: SYMBOL **list; /* ptr to list of sym pointers */
45: {
46: register SYMBOL *tos;
47: SYMBOL *op1,*op2; /*operands popped off stack*/
48: register ANYTYPE *val1,*val2; /*ptrs to values of operands*/
49: int opval, optype, l1;
50: char *s1;
51: int byflag;
52: long hitid;
53: extern char *Usercode;
54: extern ov_err();
55: int cb_mark;
56: extern char *ov_ovqpbuf;
57: extern char *locv();
58:
59: # ifdef xOTR1
60: if (tTf(72, 0))
61: printf("INTERP: list=%x\n",list);
62: # endif
63:
64: # ifdef xOTM
65: if (tTf(90, 2))
66: timtrace(11, 0);
67: # endif
68:
69: byflag = (list == De.ov_bylist); /* set byflag if aggregate function */
70: tos = (SYMBOL *)(De.ov_stack-1);
71: /* reset the concat and ascii operator buffer */
72: seterr(De.ov_ovqpbuf, CBUFULL, ov_err);
73: cb_mark = markbuf(De.ov_ovqpbuf);
74:
75: loop:
76: # ifdef xOTR1
77: if (tTf(72, 1) && tos >= (SYMBOL *) De.ov_stack)
78: {
79: printf("\ttops of stack=");
80: prstack(tos); /* print top of stack element */
81: }
82: # endif
83: /* check for stack overflow */
84: l1 = getsymbol(SPUSH(tos), &list);
85:
86: if (l1)
87: {
88: # ifdef xOTM
89: if (tTf(90, 2))
90: timtrace(12, 0);
91: # endif
92:
93: freebuf(De.ov_ovqpbuf, cb_mark);
94: return (tos);
95: }
96: optype = tos->type;
97: opval = tos->value.sym_data.i2type;
98: SPOP(tos); /* assume that stack will be popped */
99:
100: switch(optype)
101: {
102: case INT:
103: case FLOAT:
104: case CHAR:
105: SPUSH(tos); /* just leave symbol on stack */
106: goto loop;
107:
108: case COP:
109: SPUSH(tos); /* new symbol goes on stack */
110: tos->type = CHAR;
111: switch (opval)
112: {
113:
114: case opDBA:
115: tos->value.sym_data.cptype = Admin.adhdr.adowner;
116: tos->len = 2;
117: goto loop;
118:
119: case opUSERCODE:
120: tos->value.sym_data.cptype = Usercode;
121: tos->len = 2;
122: goto loop;
123: }
124:
125: case AND: /* if top value false return immediately */
126: if (!tos->value.sym_data.i2type)
127: {
128: # ifdef xOTM
129: if (tTf(90, 2))
130: timtrace(12, 0);
131: # endif
132: freebuf(De.ov_ovqpbuf, cb_mark);
133: return(tos);
134: }
135: else
136: SPOP(tos);
137: freebuf(De.ov_ovqpbuf, cb_mark);
138: goto loop;
139:
140: case OR: /* if top value is true then skip to
141: ** end of disjunction. */
142: if (tos->value.sym_data.i2type)
143: {
144: SPUSH(tos);
145: do
146: {
147: getsymbol(tos, &list);
148: } while (tos->type != AND);
149: optype = AND;
150: SPOP(tos);
151: }
152: SPOP(tos);
153: goto loop;
154:
155: case RESDOM:
156: freebuf(De.ov_ovqpbuf, cb_mark); /* init the concat and ascii buffer */
157: if (De.ov_result)
158: {
159: if (opval) /* if gt zero then opval represents a real domain */
160: {
161: if (byflag)
162: opval++; /* skip over count field for ag functs */
163: rcvt(tos, De.ov_result->relfrmt[opval], De.ov_result->relfrml[opval]);
164: tout(tos, De.ov_outtup+De.ov_result->reloff[opval], De.ov_result->relfrml[opval]);
165: }
166: else /* opval refers to the tid and this is an update */
167: {
168: De.ov_uptid = tos->value.sym_data.i4type; /* copy tid */
169: if (De.de_qmode == mdREPL || (De.ov_diffrel && De.de_qmode == mdDEL && De.ov_result->reldum.relindxd > 0 ))
170: {
171: /* De.ov_origtup must be left with the orig
172: ** unaltered tuple, and De.ov_outtup must
173: ** be initialized with the orig tuple.
174: **
175: ** De.ov_outtup only matters with REPL.
176: ** Scan() sets up De.ov_origtup so when
177: ** De.ov_source == De.ov_result, origtup is already
178: ** correct.
179: */
180:
181: if (De.ov_diffrel)
182: {
183: if (l1 = get(De.ov_result, &De.ov_uptid, &hitid, De.ov_origtup, CURTUP))
184: syserr("interp:get on resdom %s, %d", locv(De.ov_uptid), l1);
185: bmove(De.ov_origtup, De.ov_outtup, De.ov_result->reldum.relwid);
186: }
187: else
188: {
189: bmove(De.ov_intup, De.ov_outtup, De.ov_result->reldum.relwid);
190: }
191: }
192: }
193: }
194: else
195: {
196: if (Equel)
197: equelatt(tos); /* send attribute to equel */
198: else
199: {
200: if (tos->type == CHAR)
201: s1 = tos->value.sym_data.cptype;
202: else
203: s1 = tos->value.sym_data.c0type;
204: printatt(tos->type, tos->len & 0377, s1); /* print attribute */
205: }
206: }
207: SPOP(tos);
208: goto loop;
209:
210:
211: case BOP:
212: op2 = (SYMBOL *)SPOP(tos);
213: op1 = (SYMBOL *)tos;
214: typecheck(op1, op2, opval);
215: val1 = &op1->value.sym_data;
216: val2 = &op2->value.sym_data;
217:
218: switch (tos->type)
219: {
220: case INT:
221: switch (tos->len)
222: {
223: case 1:
224: case 2:
225: switch (opval)
226: {
227: case opADD:
228: val1->i2type += val2->i2type;
229: goto loop;
230:
231: case opSUB:
232: val1->i2type -= val2->i2type;
233: goto loop;
234:
235: case opMUL:
236: val1->i2type *= val2->i2type;
237: goto loop;
238:
239: case opDIV:
240: val1->i2type /= val2->i2type;
241: goto loop;
242:
243: case opMOD:
244: val1->i2type %= val2->i2type;
245: goto loop;
246:
247: case opPOW:
248: itof(op1);
249: itof(op2);
250: val1->f8type = pow(val1->f8type, val2->f8type);
251: goto loop;
252:
253: /* relational operator */
254: default:
255: l1 = val1->i2type - val2->i2type;
256: val1->i2type = relop_interp(opval, l1);
257: goto loop;
258: }
259:
260: case 4:
261: switch(opval)
262: {
263: case opADD:
264: val1->i4type += val2->i4type;
265: goto loop;
266:
267: case opSUB:
268: val1->i4type -= val2->i4type;
269: goto loop;
270:
271: case opMUL:
272: val1->i4type *= val2->i4type;
273: goto loop;
274:
275: case opDIV:
276: val1->i4type /= val2->i4type;
277: goto loop;
278:
279: case opMOD:
280: val1->i4type %= val2->i4type;
281: goto loop;
282:
283: case opPOW:
284: itof(op1);
285: itof(op2);
286: val1->f8type = pow(val1->f8type, val2->f8type);
287: goto loop;
288:
289: /* relational operator */
290: default:
291: tos->len = 2;
292: if (val1->i4type > val2->i4type)
293: l1 = 1;
294: else
295: if (val1->i4type == val2->i4type)
296: l1 = 0;
297: else
298: l1 = -1;
299:
300: val1->i2type = relop_interp(opval, l1);
301: goto loop;
302:
303: }
304: }
305:
306: case FLOAT:
307: switch (opval)
308: {
309: case opADD:
310: val1->f8type += val2->f8type;
311: goto loop;
312:
313: case opSUB:
314: val1->f8type -= val2->f8type;
315: goto loop;
316:
317: case opMUL:
318: val1->f8type *= val2->f8type;
319: goto loop;
320:
321: case opDIV:
322: val1->f8type /= val2->f8type;
323: goto loop;
324:
325: case opPOW:
326: val1->f8type = pow(val1->f8type, val2->f8type);
327: goto loop;
328:
329: default:
330: tos->type = INT;
331: tos->len = 2;
332: if (val1->f8type > val2->f8type)
333: l1 = 1;
334: else
335: if (val1->f8type == val2->f8type)
336: l1 = 0;
337: else
338: l1 = -1;
339: val1->i2type = relop_interp(opval, l1);
340: goto loop;
341: }
342:
343: case CHAR:
344: if (opval == opCONCAT)
345: {
346: concatsym(op1, op2); /* concatenate the two symbols */
347: goto loop;
348: }
349: l1 = lexcomp(val1->cptype, op1->len & 0377, val2->cptype, op2->len & 0377);
350: tos->type = INT;
351: tos->len = 2;
352: val1->i2type = relop_interp(opval, l1);
353: goto loop;
354: } /* end of BOP */
355:
356: case UOP:
357: val1 = &tos->value.sym_data;
358: switch (opval)
359: {
360: case opMINUS:
361: case opABS:
362: if (tos->type == CHAR)
363: ov_err(BADUOPC);
364: l1 = opval == opMINUS;
365: switch (tos->type)
366: {
367: case INT:
368: switch (tos->len)
369: {
370: case 1:
371: case 2:
372: if (l1 || val1->i2type < 0)
373: val1->i2type = -val1->i2type;
374: goto loop;
375:
376: case 4:
377: if (l1 || val1->i4type < 0)
378: val1->i4type = -val1->i4type;
379: goto loop;
380: }
381:
382: case FLOAT:
383: if (l1 || val1->f8type < 0.0)
384: val1->f8type = -val1->f8type;
385: goto loop;
386: }
387:
388: case opNOT:
389: val1->i2type = !val1->i2type;
390: case opPLUS:
391: if (tos->type == CHAR)
392: ov_err(BADUOPC);
393: goto loop;
394:
395: case opASCII:
396: ascii(tos);
397: goto loop;
398:
399: case opINT1:
400: typecoerce(tos, INT, 1);
401: goto loop;
402:
403: case opINT2:
404: typecoerce(tos, INT, 2);
405: goto loop;
406:
407: case opINT4:
408: typecoerce(tos, INT, 4);
409: goto loop;
410:
411: case opFLOAT4:
412: typecoerce(tos, FLOAT, 4);
413: goto loop;
414:
415: case opFLOAT8:
416: typecoerce(tos, FLOAT, 8);
417: goto loop;
418:
419: default:
420: if (tos->type == CHAR)
421: ov_err(BADUOPC);
422: if (tos->type == INT)
423: itof(tos);
424: switch (opval)
425: {
426: case opATAN:
427: val1->f8type = atan(val1->f8type);
428: goto loop;
429:
430: case opLOG:
431: val1->f8type = log(val1->f8type);
432: goto loop;
433:
434: case opSIN:
435: val1->f8type = sin(val1->f8type);
436: goto loop;
437:
438: case opCOS:
439: val1->f8type = cos(val1->f8type);
440: goto loop;
441:
442: case opSQRT:
443: val1->f8type = sqrt(val1->f8type);
444: goto loop;
445:
446: case opEXP:
447: val1->f8type = exp(val1->f8type);
448: goto loop;
449:
450: default:
451: syserr("interp:bad uop %d",opval);
452: }
453: }
454:
455:
456: case AOP:
457: aop_interp(opval, tos);
458: SPOP(tos); /* pop this symbol */
459: goto loop;
460:
461: }
462: syserr("interp: fell out");
463: /*NOTREACHED*/
464: }
465: /*
466: ** relop_interp interprets the relational operators
467: ** (ie. EQ, NE etc.) and returns true or false
468: ** by evaluating l1.
469: **
470: ** l1 should be greater than, equal or less than zero.
471: */
472:
473: relop_interp(opval, l1)
474: int opval;
475: int l1;
476: {
477: register int i;
478:
479: i = l1;
480:
481: switch (opval)
482: {
483:
484: case opEQ:
485: return (i == 0);
486:
487: case opNE:
488: return (i != 0);
489:
490: case opLT:
491: return (i < 0);
492:
493: case opLE:
494: return (i <= 0);
495:
496: case opGT:
497: return (i > 0);
498:
499: case opGE:
500: return (i >= 0);
501:
502: default:
503: syserr("relop:bad relop or bop %d", opval);
504: }
505: /*NOTREACHED*/
506: }
507: /*
508: ** Aggregate values are stored in De.ov_outtup. De.ov_tend points
509: ** to the spot for the next aggregate. Aop_interp()
510: ** computes the value for the aggregate and leaves
511: ** the result in the position pointed to by De.ov_tend.
512: */
513:
514: aop_interp(opval, tos)
515: int opval;
516: register SYMBOL *tos;
517: {
518: register int i;
519: int l1;
520: ANYTYPE numb; /* used for type conversion */
521:
522: bmove(De.ov_tend, (char *) &numb, 8); /* note: this assumes that there are always 8 bytes which can be moved.
523: ** if it moves beyond De.ov_tend, it's ok */
524: switch (opval)
525: {
526:
527: case opSUMU:
528: case opSUM:
529: if (*De.ov_counter <= 1)
530: goto puta;
531: switch (tos->type)
532: {
533: case INT:
534: switch(tos->len)
535: {
536: case 1:
537: tos->value.sym_data.i2type += numb.i1type;
538: goto puta;
539:
540: case 2:
541: tos->value.sym_data.i2type += numb.i2type;
542: goto puta;
543:
544: case 4:
545: tos->value.sym_data.i4type += numb.i4type;
546: goto puta;
547: }
548:
549: case FLOAT:
550: if (tos->len == 4)
551: numb.f8type = numb.f4type;
552: tos->value.sym_data.f8type += numb.f8type;
553: goto puta;
554:
555: default:
556: ov_err(BADSUMC); /* cant sum char fields */
557: }
558:
559: case opCOUNTU:
560: case opCOUNT:
561: tos->type = CNTTYPE;
562: tos->len = CNTLEN;
563: tos->value.sym_data.i4type = *De.ov_counter;
564: goto puta;
565:
566: case opANY:
567: tos->type = OANYTYPE;
568: tos->len = OANYLEN;
569: if (*De.ov_counter)
570: {
571: tos->value.sym_data.i2type = 1;
572: if (!De.ov_bylist && (De.ov_agcount == 1))
573: De.ov_targvc = 0; /* if simple agg. stop scan */
574: }
575: else
576: tos->value.sym_data.i2type = 0;
577: goto puta;
578:
579: case opMIN:
580: case opMAX:
581: if (*De.ov_counter<=1)
582: goto puta;
583: switch (tos->type)
584: {
585: case INT:
586: switch (tos->len)
587: {
588: case 1:
589: i = (tos->value.sym_data.i1type < numb.i1type);
590: break;
591:
592: case 2:
593: i = (tos->value.sym_data.i2type < numb.i2type);
594: break;
595:
596: case 4:
597: i = (tos->value.sym_data.i4type < numb.i4type);
598: break;
599: }
600: break;
601:
602: case FLOAT:
603: if (tos->len == 4)
604: numb.f8type = numb.f4type;
605: i = (tos->value.sym_data.f8type < numb.f8type);
606: break;
607:
608: case CHAR:
609: l1 = tos->len & 0377;
610: i = (lexcomp(tos->value.sym_data.cptype, l1, De.ov_tend, l1) < 0);
611: break;
612:
613: default:
614: syserr("interp:bad op type for opMIN/MAX %d", tos->type);
615: }
616:
617: /* check result of comparison */
618: if (opval == opMAX)
619: i = !i; /* complement test for opMAX */
620: if (i)
621: goto puta; /* condition true. new value */
622:
623: /* condition false. Keep old value */
624: goto done;
625:
626:
627: case opAVGU:
628: case opAVG:
629: if (tos->type == INT)
630: itof(tos);
631: else
632: if (tos->type == CHAR)
633: ov_err(BADAVG);
634: if (*De.ov_counter > 1)
635: {
636: tos->value.sym_data.f8type = numb.f8type + (tos->value.sym_data.f8type - numb.f8type) / *De.ov_counter;
637: }
638: tos->len = 8;
639: goto puta;
640:
641: default:
642: syserr("interp:bad agg op %d", tos->type);
643: }
644:
645: puta:
646: tout(tos, De.ov_tend, tos->len);
647: done:
648: De.ov_tend += tos->len & 0377;
649: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.