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
ovqpnod defined in line 273; used 3 times
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
Qvect defined in line 31; used 5 times
Qvptr defined in line 30; used 5 times
Retcode defined in line 219; used 2 times
Last modified: 1995-05-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2525
Valid CSS Valid XHTML 1.0 Strict