# 2.11BSD#431 - /usr/ingres/source/ovqp/interp.c

##### Functions

    aop_interp        X
    interpret         X
    relop_interp      X

       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

- in line 456

interpret defined in line 38; used 7 times

- in /usr/ingres/source/ovqp/scan.c line 27, 113, 129, 173, 180, 194, 213

relop_interp defined in line 464; used 4 times

- in line 251, 295, 334, 347

Last modified: 1995-03-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1608 |