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