1: # include "../ingres.h" 2: # include "../symbol.h" 3: # include "../tree.h" 4: # include "../pipes.h" 5: # include "ovqp.h" 6: 7: 8: /* 9: ** SCAN 10: ** 11: ** performs tuple by tuple scan of source reln or index reln 12: ** within limits found by strategy routine. 13: ** When the source reln tuple is obtained the interpreter is invoked 14: ** to continue further processing 15: ** 16: */ 17: 18: 19: scan() 20: { 21: register j, mode, domno; 22: char *rlist; /* "result" list of query */ 23: long count; 24: long tid, temptid; 25: char agtup[MAXTUP], outtup1[MAXTUP]; 26: int qualfound, ok; 27: struct symbol *interpret(); 28: 29: # ifdef xOTR1 30: if (tTf(30, -1)) 31: { 32: printf("SCAN\tScanr=%.12s\n", Scanr ? Scanr->relid : "(none)"); 33: if (tTf(30, 4)) 34: printf(" Alist=%l, Bylist=%l, Tlist=%l, Qlist=%l\n", Alist, Bylist, Tlist, Qlist); 35: } 36: # endif 37: 38: if (Result || Alist) 39: { 40: if (Result) 41: clr_tuple(Result, Outtup); 42: else 43: { 44: j = MAXTUP; 45: while (j--) 46: Outtup[j] = 0; 47: } 48: } 49: 50: count = 0; 51: qualfound = EMPTY; 52: mode = Ov_qmode; 53: 54: /* 55: ** Check for identical source and result relations. 56: ** For modes mdREPL and mdDEL, Origtup must point 57: ** to the original (unmodified result tuple). 58: ** 59: ** If there is no Source or Result relations then 60: ** the code has no effect. 61: */ 62: if (!bequal(Source->relid, Result->relid, MAXNAME)) 63: { 64: Diffrel = TRUE; 65: Origtup = outtup1; 66: } 67: else 68: { 69: Diffrel = FALSE; 70: Origtup = Intup; 71: } 72: 73: /* determine type of result list */ 74: /* the only valid combinations are: 75: ** 76: ** Tlist=no Alist=no Bylist=no 77: ** Tlist=yes Alist=no Bylist=no 78: ** Tlist=no Alist=yes Bylist=no 79: ** Tlist=no Alist=yes Bylist=yes 80: */ 81: rlist = (char *) (Tlist? Tlist: Alist); 82: if (Bylist) 83: rlist = 0; 84: 85: Counter= &count; 86: if (Bylist) 87: { 88: /* 89: ** For aggregate functions the result relation 90: ** is in the format: 91: ** domain 1 = I4 (used as a counter) 92: ** domain 2 through relatts - Agcount (by-domains) 93: ** remaining domains (the actual aggregate values) 94: */ 95: 96: /* set up keys for the getequal */ 97: /* domno must end with the domain number of the first aggregate */ 98: for (domno = 2; domno <= Result->relatts - Agcount; domno++) 99: Result->relgiven[domno] = 1; 100: 101: Counter = (long *) Outtup; /* first four bytes of Outtup is counter for Bylist */ 102: } 103: 104: /* 105: ** check for constant qualification. 106: ** If the constant qual is true then remove 107: ** the qual to save reprocessing it. 108: ** If it is false then block further processing. 109: */ 110: 111: ok = TRUE; 112: if (Qlist && Qualvc == 0) 113: if (*interpret(Qlist)->value) 114: Qlist = 0; /* qual always true */ 115: else 116: ok = FALSE; /* qual always false */ 117: 118: 119: /* if no source relation, interpret target list */ 120: if (!Scanr && ok) 121: { 122: /* there is no source relation and the qual is true */ 123: qualfound = NONEMPTY; 124: Tend = Outtup; 125: /* if there is a rlist then process it. (There should always be one) */ 126: if (rlist) 127: { 128: (*Counter)++; 129: interpret(rlist); 130: } 131: if (Tlist) 132: dispose(mode); 133: else 134: if (Userqry) 135: Tupsfound++; 136: } 137: 138: if (Scanr && ok) 139: { 140: /* There is a source relation. Iterate through each tuple */ 141: while (!(j = get(Scanr, &Lotid, &Hitid, Intup, NXTTUP))) 142: { 143: # ifdef xOTR1 144: if (tTf(30, 5)) 145: { 146: if (Scanr != Source) 147: printf("Sec Index:"); 148: else 149: printf("Intup:"); 150: printup(Scanr, Intup); 151: } 152: # endif 153: Intid = Lotid; 154: if (Scanr != Source) 155: { 156: /* make sure index tuple is part of the solution */ 157: if (!indexcheck()) 158: /* index keys don't match what we want */ 159: continue; 160: bmove(Intup + Scanr->relwid - TIDLEN, &tid, TIDLEN); 161: if (j = get(Source, &tid, &temptid, &Intup, CURTUP)) 162: syserr("scan:indx get %d %.12s", j, Scanr->relid); 163: # ifdef xOTR1 164: if (tTf(30, 6)) 165: { 166: printf("Intup:"); 167: printup(Source, Intup); 168: } 169: # endif 170: Intid = tid; 171: } 172: 173: if ( !Qlist || *interpret(Qlist)->value) 174: { 175: qualfound = NONEMPTY; 176: Tend = Outtup; 177: if (rlist) 178: { 179: (*Counter)++; 180: interpret(rlist); 181: } 182: if (Tlist) 183: dispose(mode); 184: else 185: if (Userqry) 186: Tupsfound++; 187: 188: if (!Targvc) /* constant Target list */ 189: break; 190: 191: /* process Bylist if any */ 192: if (Bylist) 193: { 194: interpret(Bylist); 195: if ((j = getequal(Result, Outtup, agtup, &Uptid)) < 0) 196: syserr("scan:getequal %d,%.12s", j, Result->relid); 197: 198: if (!j) 199: { 200: /* match on bylist */ 201: bmove(agtup, Outtup, Result->relwid); 202: mode = mdREPL; 203: (*Counter)++; 204: } 205: else 206: { 207: /* first of this bylist */ 208: mode = mdAPP; 209: *Counter = 1; 210: } 211: 212: Tend = Outtup + Result->reloff[domno]; 213: interpret(Alist); 214: dispose(mode); 215: } 216: } 217: } 218: 219: if (j < 0) 220: syserr("scan:get prim %d %.12s", j, Source->relid); 221: } 222: if (Result) 223: { 224: if (j = noclose(Result)) 225: syserr("scan:noclose %d %.12s", j, Result->relid); 226: } 227: return (qualfound); 228: } 229: 230: dispose(mode) 231: { 232: register int i; 233: 234: i = 0; 235: 236: if (!Result) 237: { 238: if (Equel) 239: equeleol(EOTUP); 240: else 241: printeol(); 242: } 243: else 244: { 245: # ifdef xOTR1 246: if (tTf(30, -1)) 247: { 248: if (tTf(30, 1)) 249: printf("mode=%d,",mode); 250: if (tTf(30, 2) && (mode == mdREPL || mode == mdDEL)) 251: printf("Uptid:%s, ",locv(Uptid)); 252: if (tTf(30, 3)) 253: if (mode == mdDEL) 254: printup(Source, Intup); 255: else 256: printup(Result, Outtup); 257: } 258: # endif 259: 260: /* SPOOL UPDATES OF EXISTING USER RELNS TO BATCH PROCESSOR */ 261: if (Buflag) 262: { 263: addbatch(&Uptid, Outtup, Origtup); 264: return; 265: } 266: 267: /* PERFORM ALL OTHER OPERATIONS DIRECTLY */ 268: switch (mode) 269: { 270: case mdRETR: 271: case mdAPP: 272: if ((i = insert(Result, &Uptid, Outtup, NODUPS)) < 0) 273: syserr("dispose:insert %d %.12s", i, Result->relid); 274: break; 275: 276: case mdREPL: 277: if ((i = replace(Result, &Uptid, Outtup, NODUPS)) < 0) 278: syserr("dispose:replace %d %.12s", i, Result->relid); 279: break; 280: 281: case mdDEL: 282: if ((i = delete(Result, &Uptid)) < 0) 283: syserr("dispose:delete %d %.12s", i, Result->relid); 284: break; 285: 286: default: 287: syserr("dispose:bad mode %d", mode); 288: } 289: } 290: 291: if (Userqry && i == 0) 292: Tupsfound++; 293: }