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