1: # include   <errors.h>
   2: # include   <ingres.h>
   3: # include   <aux.h>
   4: # include   <opsys.h>
   5: # include   <access.h>
   6: # include   <tree.h>
   7: # include   <symbol.h>
   8: # include   "globs.h"
   9: # include   <sccs.h>
  10: 
  11: SCCSID(@(#)call_ovqp.c	8.6	12/18/85)
  12: 
  13: 
  14: /*
  15: ** CALL_OVQP -- Routines which interface to the One Variable Query Processor.
  16: **
  17: **	This file contains the routines associated with sending queries
  18: **	and receiving results from OVQP. The interface to these routines is
  19: **	still messy. Call_ovqp is given the query, mode, and result relation
  20: **	as parameters and gets the source relation, and two flags
  21: **	(De.de_newq, De.de_newr) as globals. The routines include:
  22: **
  23: **	Call_ovqp -- Sends a One-var query to ovqp and flushes the pipe.
  24: **
  25: **	Readresult -- Reads the result from a one-var query.
  26: **
  27: **	Endovqp    -- Informs ovqp that the query is over. Helps to synchronize
  28: **			the batch file (if any).
  29: **
  30: **	Trace Flags:
  31: **		61
  32: */
  33: /*
  34: ** Call_ovqp -- send query down pipe to ovqp and flush pipe.
  35: **	Inputs are:
  36: **		mode		retrieve, append, etc.
  37: **		resultnum	result relation id
  38: **		tree		the query
  39: **		De.de_sourcevar	(global) if >= 0 then source var
  40: **		De.de_newq		send NEWQ symbol
  41: **		De.de_newr		send NEWR symbol
  42: */
  43: 
  44: call_ovqp(tree, mode, resultnum)
  45: register QTREE  *tree;
  46: int     mode;
  47: int     resultnum;
  48: {
  49:     register int    i;
  50:     char        *rangename();
  51:     extern int  derror();
  52:     extern bool Batchupd;
  53:     extern DESC Inddes;
  54:     int     ovqpbuf[1+LBUFSIZE/sizeof(int)];
  55:     DESC        *readopen();
  56:     extern DESC *specopen();
  57:     extern char *rnum_convert();
  58: 
  59: 
  60: #	ifdef xDTR1
  61:     if (tTf(61, -1))
  62:     {
  63:         if (tTf(61, 0))
  64:             printf("CALL_OVQP-\n");
  65:         if (tTf(61, 1))
  66:         {
  67:             if (De.de_newq)
  68:             {
  69:                 printf("new query to ovqp\n");
  70:                 treepr(tree);
  71:             }
  72:             else
  73:                 printf("query same as previous\n");
  74:         }
  75:         if (tTf(61, 2))
  76:         {
  77:             printf("De.de_sourcevar=%d\t", De.de_sourcevar);
  78:             if (De.de_sourcevar >= 0)
  79:                 printf("relid=%s\t", rangename(De.de_sourcevar));
  80:             if (resultnum >= 0)
  81:                 printf("De.ov_resultname=%s", rnum_convert(resultnum));
  82:             if (tree->sym.value.sym_root.rootuser)
  83:                 printf(", userqry");
  84:             printf("\n");
  85:         }
  86:     }
  87: #	endif
  88: 
  89: 
  90: 
  91:     /* assign mode of this query */
  92:     De.de_qmode = mode;
  93: 
  94:     if (De.de_newr)
  95:     {
  96:         De.de_newr = FALSE;
  97:     }
  98: 
  99:     if (resultnum >= 0)
 100:     {
 101:         De.ov_result = specopen(resultnum);
 102:     }
 103:     else
 104:         De.ov_result = NULL;
 105: 
 106:     if (De.de_sourcevar >= 0)
 107:         De.ov_source = readopen(De.de_sourcevar);
 108:     else
 109:         De.ov_source = NULL;
 110: 
 111:     /* assume this will be direct update */
 112:     De.ov_userqry = De.de_buflag = FALSE;
 113: 
 114:     if (tree->sym.value.sym_root.rootuser)
 115:     {
 116:         De.ov_userqry = TRUE;
 117:         /* handle batch file */
 118:         if (De.ov_result && De.de_qmode != mdRETR)
 119:         {
 120:             if (Batchupd || De.ov_result->reldum.relindxd > 0)
 121:             {
 122:                 if (De.ov_bopen == 0)
 123:                 {
 124:                     if (De.ov_result->reldum.relindxd > 0)
 125:                         opencatalog("indexes", OR_READ);
 126:                     if (i = openbatch(De.ov_result, &Inddes, De.de_qmode))
 127:                         syserr("call_ovqp:opn batch %d", i);
 128:                     De.ov_bopen = TRUE;
 129:                 }
 130:                 De.de_buflag = TRUE;
 131:             }
 132:         }
 133:     }
 134: 
 135:     /*  now write the query list itself  */
 136:     if (De.de_newq)
 137:     {
 138:         De.ov_ovqpbuf = (char *)ovqpbuf;
 139:         initbuf(De.ov_ovqpbuf, LBUFSIZE, LISTFULL, derror);
 140:         De.de_qvptr = 0;
 141:         De.ov_alist = De.ov_bylist = De.ov_qlist = De.ov_tlist = NULL;
 142:         De.ov_targvc = tree->sym.value.sym_root.lvarc;
 143:         De.ov_qualvc = bitcnt(tree->sym.value.sym_root.rvarm);
 144:         De.ov_agcount = 0;
 145: 
 146:         if (tree->sym.type == AGHEAD)
 147:         {
 148:             De.ov_alist = &De.de_qvect[0];
 149:             if (tree->left->sym.type == BYHEAD)
 150:             {
 151:                 mklist(tree->left->right);
 152:                 ovqpnod(tree->left);    /* BYHEAD node */
 153:                 De.ov_bylist = &De.de_qvect[De.de_qvptr];
 154:                 mklist(tree->left->left);
 155:             }
 156:             else
 157:                 mklist(tree->left);
 158:         }
 159:         else
 160:         {
 161:             if (tree->left->sym.type != TREE)
 162:             {
 163:                 De.ov_tlist = &De.de_qvect[0];
 164:                 mklist(tree->left);
 165:             }
 166:         }
 167: 
 168:         /* now for the qualification */
 169:         ovqpnod(tree);  /* ROOT node */
 170: 
 171:         if (tree->right->sym.type != QLEND)
 172:         {
 173:             De.ov_qlist = &De.de_qvect[De.de_qvptr];
 174:             mklist(tree->right);
 175:         }
 176:         ovqpnod(De.de_qle); /* QLEND node */
 177:     }
 178: 
 179:     /* Now call ovqp */
 180:     if (strategy())
 181:     {
 182:         i = scan(); /* scan the relation */
 183:     }
 184:     else
 185:         i = EMPTY;
 186: 
 187:     /* return result of query */
 188:     return (i == NONEMPTY); /* TRUE if tuple satisfied */
 189: }
 190: /*
 191: ** Endovqp -- Inform ovqp that processing is complete. "Ack" indicates
 192: **	whether to wait for an acknowledgement from ovqp. The overall
 193: **	mode of the query is sent followed by an EXIT command.
 194: **
 195: **	Ovqp decides whether to use batch update or not. If ack == ACK
 196: **	then endovqp will read a RETVAL symbol from ovqp and return
 197: **	a token which specifies whether to call the update processor or not.
 198: */
 199: 
 200: endovqp(ack)
 201: int ack;
 202: {
 203:     register int    i;
 204: 
 205:     if (ack != RUBACK)
 206:     {
 207:         if (Equel && De.de_qry_mode == mdRETTERM)
 208:             equeleol(EXIT); /* signal end of retrieve to equel process */
 209:     }
 210: 
 211:     i = NOUPDATE;
 212: 
 213:     if (ack == ACK)
 214:     {
 215:         if (De.ov_bopen)
 216:         {
 217:             closebatch();
 218:             De.ov_bopen = FALSE;
 219:             i = UPDATE;
 220:         }
 221:     }
 222:     else
 223:     {
 224:         if (De.ov_bopen)
 225:         {
 226:             rmbatch();
 227:             De.ov_bopen = FALSE;
 228:         }
 229:     }
 230: 
 231:     closecatalog(FALSE);
 232: 
 233:     return (i);
 234: }
 235: /*
 236: **	Add node q to ovqp's list
 237: */
 238: 
 239: ovqpnod(q)
 240: register QTREE  *q;
 241: {
 242:     register SYMBOL *s;
 243:     extern QTREE    *ckvar();
 244:     extern char *need();
 245:     register int    i;
 246: 
 247:     s = &q->sym;
 248: 
 249:     /* VAR nodes must be specially processed */
 250:     if (s->type == VAR)
 251:     {
 252:         /* locate currently active VAR */
 253:         q = ckvar(q);
 254: 
 255:         /* Allocate an ovqp var node for the VAR */
 256:         s = (SYMBOL *) need(De.ov_ovqpbuf, SYM_HDR_SIZ + sizeof s->value.sym_var);
 257:         s->len = sizeof s->value.sym_var;
 258:         s->value.sym_var.attno = q->sym.value.sym_var.attno;
 259:         s->value.sym_var.varfrmt = q->sym.value.sym_var.varfrmt;
 260:         s->value.sym_var.varfrml = q->sym.value.sym_var.varfrml;
 261:         s->value.sym_var.varstr = q->sym.value.sym_var.varstr;
 262: 
 263:         /* If VAR has been substituted for, get value */
 264:         if (q->sym.value.sym_var.valptr)
 265:         {
 266:             /* This is a substituted variable */
 267:             if (q->sym.value.sym_var.varno == De.de_sourcevar)
 268:                 syserr("ovqpnod:bd sub %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
 269: 
 270:             s->type = S_VAR;
 271:             s->value.sym_var.valptr = q->sym.value.sym_var.valptr;
 272:         }
 273:         else
 274:         {
 275:             /* Var for one variable query */
 276:             if (q->sym.value.sym_var.varno != De.de_sourcevar)
 277:                 syserr("ovqpnod:src var %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
 278:             s->type = VAR;
 279:             i = q->sym.value.sym_var.attno;
 280:             if (i != 0)
 281:                 s->value.sym_var.valptr = (ANYTYPE *) (De.ov_intup + De.ov_source->reloff[i]);
 282:             else
 283:                 s->value.sym_var.valptr = (ANYTYPE *) &De.ov_intid;
 284:         }
 285:     }
 286:     if (s->type == AOP)
 287:         De.ov_agcount++;
 288: 
 289:     /* add symbol to list */
 290:     if (De.de_qvptr > MAXNODES - 1)
 291:         ov_err(NODOVFLOW);
 292:     De.de_qvect[De.de_qvptr++] = s;
 293: }
 294: /*
 295: **  READAGG_RESULT
 296: */
 297: 
 298: readagg_result(result)
 299: QTREE   *result[];
 300: {
 301:     register QTREE  **r, *aop;
 302:     register int    i;
 303: 
 304:     De.ov_tend = De.ov_outtup;
 305:     r = result;
 306: 
 307:     while (aop = *r++)
 308:     {
 309:         i = aop->sym.len & I1MASK;
 310: 
 311:         if (aop->sym.type == CHAR)
 312:             pad(De.ov_tend, i);
 313: 
 314:         bmove(De.ov_tend, (char *)&aop->sym.value, i);
 315: 
 316:         De.ov_tend += i;
 317: #		ifdef xDTR1
 318:         if (tTf(61, 3))
 319:             nodepr(aop);
 320: #		endif
 321:     }
 322: }
 323: 
 324: 
 325: ov_err(code)
 326: int code;
 327: {
 328:     derror(code);
 329: }
 330: 
 331: 
 332: DESC *
 333: openindex(name)
 334: char    *name;
 335: {
 336:     register DESC   *d;
 337:     register int    varno;
 338:     DESC        *readopen();
 339: 
 340:     varno = SECINDVAR;
 341:     De.de_rangev[varno].relnum = rnum_findadd(name);
 342:     d = readopen(varno);
 343:     return (d);
 344: }
 345: /*
 346: **	Use "closer()" for closing relations. See
 347: **	desc_close in openrs.c for details.
 348: */
 349: extern int  closer();
 350: int     (*Des_closefunc)()  = closer;
 351: 
 352: init_decomp()
 353: {
 354:     static struct accbuf    xtrabufs[12];
 355: 
 356:     set_so_buf();
 357:     acc_addbuf(xtrabufs, 12);
 358: }
 359: 
 360: 
 361: startdecomp()
 362: {
 363:     /* called at the start of each user query */
 364:     initrange();
 365:     rnum_init();
 366:     startovqp();
 367: }

Defined functions

init_decomp defined in line 352; used 1 times
openindex defined in line 332; never used
ov_err defined in line 325; used 1 times
ovqpnod defined in line 239; used 5 times
readagg_result defined in line 298; used 1 times
startdecomp defined in line 361; used 1 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1170
Valid CSS Valid XHTML 1.0 Strict