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