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: }