|
|
1.1 ! root 1: # include <ingres.h> ! 2: # include <aux.h> ! 3: # include <tree.h> ! 4: # include <symbol.h> ! 5: # include "globs.h" ! 6: # include <sccs.h> ! 7: ! 8: SCCSID(@(#)decomp.c 7.2 2/9/83) ! 9: ! 10: /* ! 11: ** DECOMP -- Process a query given a query tree and range table. ! 12: ** ! 13: ** Decomp processes any arbitrary query by converting it into ! 14: ** a sequence of "one variable queries"; eg. queries involving ! 15: ** at most one source relation. This file and decision.c contain ! 16: ** the principle decision making routines. ! 17: ** ! 18: ** Decomp() is called with a pointer to a query tree, the mode ! 19: ** of the query (retrieve, append, etc.), and the internal name ! 20: ** of the result relation (if any). The routines included are: ! 21: ** ! 22: ** Decomp -- Opens the source relations and decides whether the ! 23: ** query is multi-variable or single/zero variable. ! 24: ** ! 25: ** Decompx -- Takes a multivariable query, removes and executes any ! 26: ** one-var restrictions and passes the remaining query ! 27: ** to decompz (if one/zero variable) or decision(). ! 28: ** ! 29: ** Decompy -- Performs "tuple substitution" on a multi-var query, ! 30: ** does any new one-var restrictions and passes the ! 31: ** remaining query to decompz (if one/zero variable) ! 32: ** or decision(). ! 33: ** ! 34: ** Decompz -- Executes a one/zero variable query by calling call_ovqp(). ! 35: */ ! 36: /* ! 37: ** Process query by calling either decompx for multivar ! 38: ** or decompz for 0 or 1 var query. Decomp() must guarantee ! 39: ** that the range table is the same upon exiting as it was ! 40: ** when entered. Newquery() and endquery() perform that function. ! 41: ** ! 42: ** Trace Flags: ! 43: ** 30 ! 44: */ ! 45: ! 46: decomp(q, qmode, result_num) ! 47: QTREE *q; ! 48: int qmode; ! 49: int result_num; ! 50: { ! 51: register QTREE *root; ! 52: register int vc, i; ! 53: int locrange[MAXRANGE]; ! 54: ! 55: root = q; ! 56: vc = root->sym.value.sym_root.tvarc; ! 57: # ifdef xDTR1 ! 58: if (tTf(30, 0)) ! 59: printf("DECOMP: %d-var query, result_num=%d\n", vc, result_num); ! 60: if (tTf(30, 1)) ! 61: { ! 62: printf("DECOMP\n"); ! 63: treepr(root); ! 64: } ! 65: # endif ! 66: ! 67: openrs(root); ! 68: ! 69: if (vc > 1) ! 70: { ! 71: newquery(locrange); ! 72: i = decompx(root, qmode, result_num); ! 73: endquery(locrange, FALSE); /* don't reopen previous range */ ! 74: } ! 75: else ! 76: { ! 77: De.de_newq = 1; ! 78: De.de_sourcevar = -1; ! 79: i = decompz(root, qmode, result_num); ! 80: } ! 81: ! 82: /* ! 83: ** remove the range variables that the view subsystem ! 84: ** might have placed in. ! 85: */ ! 86: clrrange(); ! 87: ! 88: return (i); ! 89: } ! 90: /* ! 91: ** Decompx -- Initialize for multi-variable query. ! 92: ** All one-variable subqueries are run. ! 93: ** If the remaining query is still multi-var ! 94: ** then decision() is called; else decompz() ! 95: ** is called. The range table is restored ! 96: ** after the query is complete. ! 97: ** The tempvars from the exec_sq() are left on the ! 98: ** tree since it is presumed that the tree will be discarded ! 99: ** anyway. ! 100: ** ! 101: ** Trace Flags: ! 102: ** 31 ! 103: */ ! 104: ! 105: decompx(root, qmode, result_num) ! 106: QTREE *root; ! 107: int qmode; ! 108: int result_num; ! 109: { ! 110: register int i, vc; ! 111: int disj; ! 112: char sqbuf[SQSIZ]; ! 113: QTREE *sqlist[MAXRANGE]; ! 114: int locrang[MAXRANGE], sqrange[MAXRANGE]; ! 115: extern int derror(); ! 116: ! 117: vc = root->sym.value.sym_root.tvarc; ! 118: initbuf(sqbuf, SQSIZ, SQBUFFULL, derror); ! 119: pull_sq(root, sqlist, locrang, sqrange, sqbuf); ! 120: if ((i = exec_sq(sqlist, sqrange, &disj)) != -1) ! 121: { ! 122: undo_sq(sqlist, locrang, sqrange, i, i, FALSE); ! 123: return (FALSE); ! 124: } ! 125: vc -= disj; ! 126: tempvar(root, sqlist, sqbuf); ! 127: if (pull_const(root, sqbuf) == 0) ! 128: return (FALSE); ! 129: if (vc <= 1) ! 130: { ! 131: De.de_sourcevar = -1; ! 132: De.de_newq = 1; ! 133: return (decompz(root, qmode, result_num)); ! 134: } ! 135: i = decision(root, qmode, result_num, sqbuf); ! 136: undo_sq(sqlist, locrang, sqrange, MAXRANGE, MAXRANGE, FALSE); ! 137: return (i); ! 138: } ! 139: /* ! 140: ** Decompy -- decompose a multi-variable query by tuple substitution. ! 141: ** First a variable is selected ! 142: ** for substitution. Then for each tuple in the ! 143: ** selected variable, all one variable restrictions ! 144: ** are done (exec_sq) and the remaining query is ! 145: ** solved by calling either decompz() or recursively ! 146: ** decision(). ! 147: ** ! 148: ** The original tree and range table are guaranteed to ! 149: ** be the same on entry and exit (modulo the effects of ! 150: ** reformat()). ! 151: ** ! 152: ** Trace Flags: ! 153: ** 32 ! 154: */ ! 155: ! 156: decompy(q, qmode, result_num, sqbuf) ! 157: QTREE *q; ! 158: int qmode; ! 159: int result_num; ! 160: char *sqbuf; ! 161: { ! 162: register QTREE *root; ! 163: register int j, vc; ! 164: DESC *d; ! 165: QTREE *newroot; ! 166: int constl, sqcnt, var, srcvar, maxsqcnt; ! 167: int disj, tc, qtrue; ! 168: TID tid, hitid; ! 169: char *tuple; ! 170: QTREE *sqlist[MAXRANGE]; ! 171: int sqmark, sqmark1; ! 172: int locrang[MAXRANGE], sqrange[MAXRANGE]; ! 173: extern DESC *readopen(); ! 174: extern char *need(), *rangename(); ! 175: extern QTREE *copy_ands(); ! 176: ! 177: root = q; ! 178: vc = root->sym.value.sym_root.tvarc; ! 179: ! 180: # ifdef xDTR1 ! 181: if (tTf(32, -1)) ! 182: printf("DECOMPY:%x,vc=%d\n", root, vc); ! 183: # endif ! 184: ! 185: sqmark = markbuf(sqbuf); ! 186: constl = !root->sym.value.sym_root.lvarc; ! 187: qtrue = FALSE; ! 188: ! 189: if ((var = selectv(root)) < 0) ! 190: return (qtrue); ! 191: d = readopen(var); /* gets full descriptor for setvar & get */ ! 192: tuple = need(sqbuf, d->reldum.relwid); ! 193: setvar(root, var, &tid, tuple); ! 194: pull_sq(root, sqlist, locrang, sqrange, sqbuf); ! 195: tempvar(root, sqlist, sqbuf); ! 196: reformat(var, sqlist, locrang, sqbuf, root); ! 197: vc--; ! 198: # ifdef xDTR2 ! 199: if (tTf(32, 0)) ! 200: { ! 201: printf("DECOMPY: &tup=%x, ", tuple); ! 202: printdesc(d); ! 203: } ! 204: # endif xDTR2 ! 205: ! 206: /* HERE FOR MULTI-VAR SUBSTITUTION */ ! 207: sqmark1 = markbuf(sqbuf); ! 208: De.de_newq = 1; ! 209: tc = 0; ! 210: sqcnt = maxsqcnt = 0; ! 211: srcvar = -1; ! 212: De.de_sourcevar = -1; ! 213: find(readopen(var), NOKEY, &tid, &hitid); ! 214: while (!(j=get(readopen(var), &tid, &hitid, tuple, NXTTUP))) ! 215: { ! 216: # ifdef xDTR1 ! 217: if (tTf(32, 2)) ! 218: { ! 219: printf("Subst:"); ! 220: printup(readopen(var), tuple); ! 221: } ! 222: # endif ! 223: tc++; ! 224: if (vc > 1) ! 225: { ! 226: reset_sq(sqlist, locrang, sqcnt); ! 227: if ((sqcnt = exec_sq(sqlist, sqrange, &disj)) != -1) ! 228: continue; ! 229: ! 230: maxsqcnt = sqcnt; ! 231: vc -= disj; ! 232: if (vc <= 1) ! 233: { ! 234: De.de_sourcevar = srcvar; ! 235: qtrue |= decompz(root, qmode, result_num); ! 236: srcvar = De.de_sourcevar; ! 237: } ! 238: else ! 239: { ! 240: freebuf(sqbuf, sqmark1); ! 241: newroot = copy_ands(root, sqbuf); ! 242: qtrue |= decision(newroot, qmode, result_num, sqbuf); ! 243: } ! 244: vc += disj; ! 245: } ! 246: else ! 247: qtrue |= decompz(root, qmode, result_num); ! 248: ! 249: /* check for early termination on constant Target list */ ! 250: if (constl && qtrue) ! 251: break; ! 252: } ! 253: if (j < 0) ! 254: syserr("decompy: bad get %d on %.12s", j, readopen(var)->reldum.relid); ! 255: ! 256: /* undo the effect of pulling the sub queries */ ! 257: origvar(root, sqlist); ! 258: undo_sq(sqlist, locrang, sqrange, sqcnt, maxsqcnt, TRUE); ! 259: ! 260: /* undo the setvar on the main tree and all subtrees */ ! 261: clearvar(root, var); ! 262: for (j = 0; j < MAXRANGE; j++) ! 263: clearvar(sqlist[j], var); ! 264: ! 265: /* return any used buffer space */ ! 266: freebuf(sqbuf, sqmark); ! 267: ! 268: # ifdef xDTR1 ! 269: if (tTf(32, 2)) ! 270: printf("tc[%.12s]=%d,qtrue=%d\n", rangename(var), tc, qtrue); ! 271: # endif ! 272: ! 273: return (qtrue); ! 274: } ! 275: /* ! 276: ** Decompz processes a one variable query ! 277: ** by calling call_ovqp(). ! 278: ** ! 279: ** Trace Flags: ! 280: ** 33 ! 281: */ ! 282: ! 283: decompz(q, qmode, result_num) ! 284: QTREE *q; ! 285: int qmode; ! 286: int result_num; ! 287: { ! 288: register QTREE *root; ! 289: register int qualfound; ! 290: ! 291: root = q; ! 292: if (root->sym.value.sym_root.tvarc) ! 293: { ! 294: if (De.de_sourcevar < 0) ! 295: { ! 296: if ((De.de_sourcevar = selectv(root)) < 0) ! 297: return (FALSE); ! 298: } ! 299: } ! 300: else ! 301: { ! 302: De.de_sourcevar = -1; ! 303: } ! 304: ! 305: qualfound = call_ovqp(root, qmode, result_num); ! 306: De.de_newq = 0; ! 307: return (qualfound); ! 308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.