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

Defined functions

aop_interp defined in line 507; used 1 times
interpret defined in line 38; used 7 times
relop_interp defined in line 464; used 4 times
Last modified: 1995-03-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3877
Valid CSS Valid XHTML 1.0 Strict