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