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