1: # include "../pipes.h" 2: # include "../ingres.h" 3: # include "../tree.h" 4: # include "../symbol.h" 5: # include "decomp.h" 6: 7: /* 8: ** DECOMP2 -- Routines for executing detached sub-queries appearing 9: ** in sqlist. These routines include: 10: ** 11: ** exec_sq -- execute sub-queries and update range table. 12: ** 13: ** undo_sq -- restore range table and destroy temp rels. 14: ** 15: ** reset_sq - restore range table and reset temp rels. 16: ** 17: ** execsq1 -- call ovqp with subquery. 18: */ 19: 20: 21: exec_sq(sqlist, sqrange, disj) 22: struct querytree *sqlist[]; 23: int sqrange[]; 24: int *disj; 25: 26: /* 27: ** Exec_sq -- execute the subqueries in sqlist. Associated with 28: ** each sub-query is a relation number stored in sqrange. 29: ** If the sub-query has a non-null target list, the range 30: ** table is updated to reflect the new range of the relation. 31: ** 32: ** If any sub-query is false, all subsequent ones are ignored 33: ** by ovqp and exec_sq returns the var number of the false subquery. 34: ** 35: ** As a side effect, "disj" is incremented for each disjoint sub-query 36: */ 37: 38: { 39: register struct querytree *sq; 40: register int i, qualfound; 41: 42: # ifdef xDTR1 43: if (tTf(11, 0)) 44: printf("EXEC_SQ--\n"); 45: # endif 46: 47: *disj = 0; 48: 49: for (i = 0; i < MAXRANGE; i++) 50: { 51: if (sq = sqlist[i]) 52: { 53: # ifdef xDTR1 54: if (tTf(11, 1)) 55: printf("sq[%d]=%l\n", i, sq); 56: # endif 57: qualfound = execsq1(sq, i, sqrange[i]); 58: 59: # ifdef xDTR1 60: if (tTf(11, 2)) 61: printf("qualfound=%d\n", qualfound); 62: # endif 63: if (!qualfound) 64: { 65: return(i); 66: } 67: if (sq->left->sym.type != TREE) 68: { 69: /* 70: ** Update the range table and open 71: ** the relation's restricted replacement. 72: */ 73: new_range(i, sqrange[i]); 74: openr1(i); 75: } 76: else 77: { 78: (*disj)++; 79: } 80: } 81: } 82: return (-1); 83: } 84: 85: 86: undo_sq(sqlist, locrang, sqrange, limit, maxlimit, reopen) 87: char *sqlist[]; 88: int locrang[]; 89: int sqrange[]; 90: int limit; 91: int maxlimit; 92: int reopen; 93: 94: /* 95: ** Undo the effects of one variable detachment on 96: ** the range table. The two parameters "limit" and 97: ** "maxlimit" describe how far down the list of 98: ** subqueries were processed. Maxlimit represents 99: ** the furthest every attained and limit represents 100: ** the last variable processed the last time. 101: */ 102: 103: { 104: 105: register struct querytree *sq; 106: register int i, lim; 107: 108: # ifdef xDTR1 109: if (tTf(11, 0)) 110: printf("UNDO_SQ--\n"); 111: # endif 112: 113: 114: initp(); /* setup parm vector for destroys */ 115: lim = limit == -1 ? MAXRANGE : limit; 116: if (maxlimit == -1) 117: maxlimit = MAXRANGE; 118: 119: for (i = 0; i < MAXRANGE; i++) 120: if (sq = (struct querytree *) sqlist[i]) 121: { 122: if (sq->left->sym.type != TREE) 123: { 124: if (i < lim) 125: { 126: /* The query was run. Close the temp rel */ 127: closer1(i); 128: } 129: 130: /* mark the temporary to be destroyed */ 131: dstr_mark(sqrange[i]); 132: 133: /* reopen the original relation. If maxlimit 134: ** never reached the variable "i" then the 135: ** original relation was never closed and thus 136: ** doesn't need to be reopened. 137: */ 138: rstrang(locrang, i); 139: if (reopen && i < maxlimit) 140: openr1(i); 141: } 142: } 143: dstr_flush(0); /* call destroy */ 144: } 145: 146: 147: execsq1(sq, var, relnum) 148: struct querytree *sq; 149: int var; 150: int relnum; 151: 152: /* 153: ** Execsq1 -- call ovqp with mdRETR on temp relation 154: */ 155: 156: { 157: register int qualfound; 158: 159: Sourcevar = var; 160: Newq = 1; 161: qualfound = call_ovqp(sq, mdRETR, relnum); 162: return (qualfound); 163: } 164: 165: 166: reset_sq(sqlist, locrang, limit) 167: struct querytree *sqlist[]; 168: int locrang[]; 169: int limit; 170: 171: /* 172: ** Reset each relation until limit. 173: ** Reset will remove all tuples from the 174: ** relation but not destroy the relation. 175: ** The descriptor for the relation will be removed 176: ** from the cache. 177: ** 178: ** The original relation is returned to 179: ** the range table. 180: ** 181: ** If limit is -1 then all relations are done. 182: */ 183: 184: { 185: register struct querytree *sq; 186: register int i, lim; 187: int old, reset; 188: 189: lim = limit == -1 ? MAXRANGE : limit; 190: reset = FALSE; 191: initp(); 192: 193: for (i = 0; i < lim; i++) 194: if ((sq = sqlist[i]) && sq->left->sym.type != TREE) 195: { 196: old = new_range(i, locrang[i]); 197: setp(rnum_convert(old)); 198: specclose(old); 199: reset = TRUE; 200: } 201: 202: if (reset) 203: { 204: /* 205: ** Guarantee that OVQP will not reuse old 206: ** page of relation being reset 207: */ 208: Newr = TRUE; 209: call_dbu(mdRESETREL, FALSE); 210: } 211: }