# 2.11BSD#431 - /usr/ingres/source/decomp/call_ovqp70.c

##### Functions

    call_ovqp         X
    endovqp           X
    files_avail       X
    init_decomp       X
    openindex         X
    ov_err            X
    ovqpnod           X
    readagg_result    X
    startdecomp       X

##### Variables

    D_ovqp70          X
    Ovqpbuf           X
    Qvect             X
    Qvptr             X
    Retcode           X

       1: # include   "../ingres.h"
       2: # include   "../aux.h"
       3: # include   "../unix.h"
       4: # include   "../access.h"
       5: # include   "../tree.h"
       6: # include   "../symbol.h"
       7: # include   "decomp.h"
       8: # include   "../ovqp/ovqp.h"
       9:
      10:
      11: /*
      12: ** CALL_OVQP -- Routines which interface to the One Variable Query Processor.
      13: **
      14: **	This file contains the routines associated with sending queries
      15: **	and receiving results from OVQP. The interface to these routines is
      16: **	still messy. Call_ovqp is given the query, mode, and result relation
      17: **	as parameters and gets the source relation, and two flags
      18: **	(Newq, Newr) as globals. The routines include:
      19: **
      20: **	Call_ovqp -- Sends a One-var query to ovqp and flushes the pipe.
      21: **
      22: **	Readresult -- Reads the result from a one-var query.
      23: **
      24: **	Endovqp    -- Informs ovqp that the query is over. Helps to synchronize
      25: **			the batch file (if any).
      26: **
      27: */
      28:
      29:
      30: int     Qvptr;      /* index into available Qvect space in ovqpnod() */
      31: struct symbol   *Qvect[MAXNODES];
      32: char        *Ovqpbuf;
      33:
      34: char        D_ovqp70 = 1;   /* used for loading only. forces call_ovqp70 to be
      35: 			** loaded instead of call_ovqp
      36: 			*/
      37:
      38:
      39:
      40: call_ovqp(qtree, mode, resultnum)
      41: struct querytree    *qtree;
      42: int         mode;
      43: int         resultnum;
      44:
      45: /*
      46: ** Call_ovqp -- send query down pipe to ovqp and flush pipe.
      47: **	Inputs are:
      48: **		mode		retrieve, append, etc.
      49: **		resultnum	result relation id
      50: **		qtree		the query
      51: **		Sourcevar	(global) if >= 0 then source var
      52: **		Newq		send NEWQ symbol
      53: **		Newr		send NEWR symbol
      54: */
      55:
      56: {
      57:     register struct querytree   *tree;
      58:     register int            i;
      59:     char                *rangename();
      60:     struct symbol           s;
      61:     extern int          derror();
      62:     extern int          Batchupd;
      63:     extern struct descriptor    Inddes;
      64:     char                ovqpbuf[LBUFSIZE];
      65:     struct descriptor       *readopen(), *specopen();
      66:
      67: #	ifdef xOTM
      68:     if (tTf(76, 1))
      69:         timtrace(7, 0);
      70: #	endif
      71:
      72:     tree = qtree;
      73: #	ifdef xDTR1
      74:     if (tTf(8, -1))
      75:     {
      76:         if (tTf(8, 0))
      77:             printf("CALL_OVQP-\n");
      78:         if (tTf(8, 1))
      79:         {
      80:             if (Newq)
      81:                 printree(tree, "new query to ovqp");
      82:             else
      83:                 printf("query same as previous\n");
      84:         }
      85:         if (tTf(8, 2))
      86:         {
      87:             printf("Sourcevar=%d\t", Sourcevar);
      88:             if (Sourcevar >= 0)
      89:                 printf("relid=%s\t", rangename(Sourcevar));
      90:             if (resultnum >= 0)
      91:                 printf("Resultname=%s", rnum_convert(resultnum));
      92:             if (((struct qt_root *)tree)->rootuser)
      93:                 printf(", userqry");
      94:             printf("\n");
      95:         }
      96:     }
      97: #	endif
      98:
      99:
     100:
     101:     /* assign mode of this query */
     102:     Ov_qmode = mode;
     103:
     104:     if (Newr)
     105:     {
     106:         Newr = FALSE;
     107:     }
     108:
     109:     if (resultnum >= 0)
     110:         Result = specopen(resultnum);
     111:     else
     112:         Result = NULL;
     113:
     114:     if (Sourcevar >= 0)
     115:         Source = readopen(Sourcevar);
     116:     else
     117:         Source = NULL;
     118:
     119:     /* assume this will be direct update */
     120:     Userqry = Buflag = FALSE;
     121:
     122:     if (((struct qt_root *)tree)->rootuser)
     123:     {
     124:         Userqry = TRUE;
     125:         /* handle batch file */
     126:         if (Result && Ov_qmode != mdRETR)
     127:         {
     128:             if (Batchupd || Result->relindxd > 0)
     129:             {
     130:                 if (Bopen == 0)
     131:                 {
     132:                     if (Result->relindxd > 0)
     133:                         opencatalog("indexes", 0);
     134:                     if (i = openbatch(Result, &Inddes, Ov_qmode))
     135:                         syserr("call_ovqp:opn batch %d", i);
     136:                     Bopen = TRUE;
     137:                 }
     138:                 Buflag = TRUE;
     139:             }
     140:         }
     141:     }
     142:
     143:     /*  now write the query list itself  */
     144:     if (Newq)
     145:     {
     146:         Ovqpbuf = ovqpbuf;
     147:         initbuf(Ovqpbuf, LBUFSIZE, LISTFULL, &derror);
     148:         Qvptr = 0;
     149:         Alist = Bylist = Qlist = Tlist = NULL;
     150:         Targvc = ((struct qt_root *)tree)->lvarc;
     151:         Qualvc = bitcnt(((struct qt_root *)tree)->rvarm);
     152:         Agcount = 0;
     153:
     154:         if (tree->sym.type == AGHEAD)
     155:         {
     156:             Alist = &Qvect[0];
     157:             if (tree->left->sym.type == BYHEAD)
     158:             {
     159:                 mklist(tree->left->right);
     160:                 ovqpnod(tree->left);    /* BYHEAD node */
     161:                 Bylist = &Qvect[Qvptr];
     162:                 mklist(tree->left->left);
     163:             }
     164:             else
     165:                 mklist(tree->left);
     166:         }
     167:         else
     168:         {
     169:             if (tree->left->sym.type != TREE)
     170:             {
     171:                 Tlist = &Qvect[0];
     172:                 mklist(tree->left);
     173:             }
     174:         }
     175:
     176:         /* now for the qualification */
     177:         ovqpnod(tree);  /* ROOT node */
     178:
     179:         if (tree->right->sym.type != QLEND)
     180:         {
     181:             Qlist = &Qvect[Qvptr];
     182:             mklist(tree->right);
     183:         }
     184:         ovqpnod(Qle);   /* QLEND node */
     185:     }
     186:
     187:     /* Now call ovqp */
     188:     if (strategy())
     189:     {
     190:
     191: #		ifdef xOTM
     192:         if (tTf(76, 2))
     193:             timtrace(9, 0);
     194: #		endif
     195:
     196:         i = scan(); /* scan the relation */
     197:
     198: #		ifdef xOTM
     199:         if (tTf(76, 2))
     200:             timtrace(10, 0);
     201: #		endif
     202:
     203:     }
     204:     else
     205:         i = EMPTY;
     206:
     207: #	ifdef xOTM
     208:     if (tTf(76, 1))
     209:         timtrace(8, 0);
     210: #	endif
     211:
     212:
     213:     /* return result of query */
     214:     return (i == NONEMPTY); /* TRUE if tuple satisfied */
     215: }
     216:
     217:
     218:
     219: struct retcode  Retcode;    /* return code structure */
     220:
     221: endovqp(ack)
     222: int ack;
     223:
     224: /*
     225: ** Endovqp -- Inform ovqp that processing is complete. "Ack" indicates
     226: **	whether to wait for an acknowledgement from ovqp. The overall
     227: **	mode of the query is sent followed by an EXIT command.
     228: **
     229: **	Ovqp decides whether to use batch update or not. If ack == ACK
     230: **	then endovqp will read a RETVAL symbol from ovqp and return
     231: **	a token which specifies whether to call the update processor or not.
     232: */
     233:
     234: {
     235:     register int        i, j;
     236:     extern int      Qry_mode;
     237:
     238:     if (ack != RUBACK)
     239:     {
     240:         if (Equel && Qry_mode == mdRETTERM)
     241:             equeleol(EXIT); /* signal end of retrieve to equel process */
     242:     }
     243:
     244:     i = NOUPDATE;
     245:
     246:     if (ack == ACK)
     247:     {
     248:         if (Bopen)
     249:         {
     250:             closebatch();
     251:             Bopen = FALSE;
     252:             i = UPDATE;
     253:         }
     254:     }
     255:     else
     256:     {
     257:         if (Bopen)
     258:         {
     259:             rmbatch();
     260:             Bopen = FALSE;
     261:         }
     262:     }
     263:
     264:     Retcode.rc_tupcount = Tupsfound;
     265:
     266:     closecatalog(FALSE);
     267:
     268:     return (i);
     269: }
     270:
     271:
     272:
     273: ovqpnod(n)
     274: struct querytree    *n;
     275:
     276: /*
     277: **	Add node n to ovqp's list
     278: */
     279:
     280: {
     281:     register struct symbol      *s;
     282:     register struct querytree   *q;
     283:     register int            i;
     284:     extern struct querytree     *ckvar(), *need();
     285:
     286:     q = n;
     287:     s = &q->sym;
     288:
     289:     /* VAR nodes must be specially processed */
     290:     if (s->type == VAR)
     291:     {
     292:         /* locate currently active VAR */
     293:         q = ckvar(q);
     294:
     295:         /* Allocate an ovqp var node for the VAR */
     296:         s = (struct symbol *) need(Ovqpbuf, 8);
     297:         s->len = 6;
     298:         s->value[0] = ((struct qt_var *)q)->attno;
     299:         ((struct qt_v *)s)->vtype = ((struct qt_var *)q)->frmt;
     300:         ((struct qt_v *)s)->vlen = ((struct qt_var *)q)->frml;
     301:
     302:         /* If VAR has been substituted for, get value */
     303:         if (((struct qt_var *)q)->valptr)
     304:         {
     305:
     306:             /* This is a substituted variable */
     307:             if (((struct qt_var *)q)->varno == Sourcevar)
     308:                 syserr("ovqpnod:bd sub %d,%d", ((struct qt_var *)q)->varno, Sourcevar);
     309:
     310:             s->type = S_VAR;
     311:             ((struct qt_v *)s)->vpoint = (int *) ((struct qt_var *)q)->valptr;
     312:         }
     313:         else
     314:         {
     315:             /* Var for one variable query */
     316:             if (((struct qt_var *)q)->varno != Sourcevar)
     317:                 syserr("ovqpnod:src var %d,%d", ((struct qt_var *)q)->varno, Sourcevar);
     318:             s->type = VAR;
     319:             if (((struct qt_var *)q)->attno)
     320:                 ((struct qt_v *)s)->vpoint = (int *) (Intup + Source->reloff[((struct qt_var *)q)->attno]);
     321:             else
     322:                 ((struct qt_v *)s)->vpoint = (int *) &Intid;
     323:         }
     324:
     325:     }
     326:     if (s->type == AOP)
     327:         Agcount++;
     328:
     329:     /* add symbol to list */
     330:     if (Qvptr > MAXNODES - 1)
     331:         ov_err(NODOVFLOW);
     332:     Qvect[Qvptr++] = s;
     333: }
     334:
     335:
     336: readagg_result(result)
     337: struct querytree    *result[];
     338:
     339: /*
     340: **
     341: */
     342:
     343: {
     344:     register struct querytree   **r, *aop;
     345:     register int            i;
     346:
     347:
     348:     Tend = Outtup;
     349:     r = result;
     350:
     351:     while (aop = *r++)
     352:     {
     353:         i = aop->sym.len & I1MASK;
     354:
     355:         if (aop->sym.type == CHAR)
     356:             pad(Tend, i);
     357:
     358:         bmove(Tend, aop->sym.value, i);
     359:
     360:         Tend += i;
     361: #		ifdef xDTR1
     362:         if (tTf(8, 3))
     363:             writenod(aop);
     364: #		endif
     365:     }
     366: }
     367:
     368:
     369: ov_err(code)
     370: int code;
     371: {
     372:     derror(code);
     373: }
     374:
     375:
     376: struct descriptor *openindex(name)
     377: char    *name;
     378: {
     379:     register struct descriptor  *d;
     380:     register int            varno;
     381:     struct descriptor       *readopen();
     382:
     383:     varno = SECINDVAR;
     384:     Rangev[varno].relnum = rnum_assign(name);
     385:     d = readopen(varno);
     386:     return (d);
     387: }
     388:
     389:
     390: /*
     391: **	Use "closer()" for closing relations. See
     392: **	desc_close in openrs.c for details.
     393: */
     394: extern int  closer();
     395: int     (*Des_closefunc)()  = closer;
     396:
     397: init_decomp()
     398: {
     399:     static struct accbuf    xtrabufs[12];
     400:
     401:     acc_addbuf(xtrabufs, 12);
     402: }
     403:
     404:
     405: startdecomp()
     406: {
     407:     /* called at the start of each user query */
     408:     Retcode.rc_tupcount = 0;
     409:     initrange();
     410:     rnum_init();
     411:     startovqp();
     412: }
     413:
     414:
     415:
     416: /*
     417: ** Files_avail -- returns how many file descriptors are available
     418: **	for decomposition. For decomp combined with ovqp, the fixed
     419: **	overhead for files is:
     420: **
     421: **		4 -- pipes
     422: **		1 -- relation relation
     423: **		1 -- attribute relation
     424: **		1 -- standard output
     425: **		1 -- concurrency
     426: **		1 -- indexes relation
     427: **
     428: **	Optional overhead is:
     429: **
     430: **		1 -- for Equel data pipe
     431: **		1 -- for batch file on updates
     432: */
     433:
     434: files_avail(mode)
     435: int mode;
     436: {
     437:     register int    i;
     438:
     439:     i = MAXFILES - 9;
     440:     if (Equel)
     441:         i--;
     442:     if (mode != mdRETR)
     443:         i--;
     444:     return (i);
     445: }

#### Defined functions

call_ovqp defined in line 40; never used
endovqp defined in line 221; never used
files_avail defined in line 434; never used
init_decomp defined in line 397; never used
openindex defined in line 376; never used
ov_err defined in line 369; used 1 times

- in line 331

ovqpnod defined in line 273; used 3 times

- in line 160, 177, 184

readagg_result defined in line 336; never used
startdecomp defined in line 405; never used

#### Defined variables

D_ovqp70 defined in line 34; never used
Ovqpbuf defined in line 32; used 3 times

- in line 146-147(2), 296

Qvect defined in line 31; used 5 times

- in line 156-161(2), 171, 181, 332

Qvptr defined in line 30; used 5 times

- in line 148, 161, 181, 330-332(2)

Retcode defined in line 219; used 2 times

- in line 264, 408

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