Status Operators::SNL(const string& result, // Output relation name const int projCnt, // Number of attributes in the projection const AttrDesc attrDescArray[], // Projection list (as AttrDesc) const AttrDesc& attrDesc1, // The left attribute in the join predicate const Operator op, // Predicate operator const AttrDesc& attrDesc2, // The left attribute in the join predicate const int reclen) // The length of a tuple in the result relation { cout << "Algorithm: Simple NL Join" << endl; //************ //************ //DECLARATIONS //************ //************ string r1 = attrDesc1.relName; string r2 = attrDesc2.relName; RID ro; int nb; char *src; Record rr; char *end; RID ri; Record rro; Record rri; char *rd; Status s; int ros; char *v; //Main Part HeapFileScan file_scan_outer(r2, s); if (s != OK) { return s; } HeapFile result_heap_file (result, s); if (s != OK) { return s; } while (file_scan_outer.scanNext(ro, rro) == OK) { v = new char[attrDesc2.attrLen]; src = ((char*)rro.data) + attrDesc2.attrOffset; memcpy(v, src, attrDesc2.attrLen); HeapFileScan file_scan_inner(r1, attrDesc1.attrOffset, attrDesc1.attrLen, static_cast<Datatype>(attrDesc1.attrType), v, op, s); if (s != OK) { delete [] v; return s; } while (file_scan_inner.scanNext(ri, rri) == OK) { rd = new char[reclen]; rr.data = rd; rr.length = reclen; ros = 0; int pcn = 0; while (pcn < projCnt) { src = NULL; if (attrDescArray[pcn].relName == r1) { src = ((char*)rri.data) + attrDescArray[pcn].attrOffset; } else { src = ((char*)rro.data) + attrDescArray[pcn].attrOffset; } end = rd + ros; nb = attrDescArray[pcn].attrLen; memcpy(end, src, nb); ros = ros + nb; pcn++; } RID rrd; s = result_heap_file.insertRecord(rr, rrd); delete [] rd; if (s != OK) { return s; } } } return OK; }
Status Operators::INL(const string& result, // Name of the output relation const int projCnt, // Number of attributes in the projection const AttrDesc attrDescArray[], // The projection list (as AttrDesc) const AttrDesc& attrDesc1, // The left attribute in the join predicate const Operator op, // Predicate operator const AttrDesc& attrDesc2, // The left attribute in the join predicate const int reclen) // Length of a tuple in the output relation { cout << "Algorithm: Indexed NL Join" << endl; Status status; string relName1 = attrDesc1.relName; string relName2 = attrDesc2.relName; /* Open the FileScan for the Outer Atribute. This must be the one without an index in the case * that only one has an index. join.cpp ensures that that is attr1 in this case. */ HeapFileScan file_scan_outer(relName1, status); if(status != OK) return status; /* Open the HeapFile for the Result Table */ HeapFile result_heap_file(result, status); if(status != OK) return status; /* Scan Through the Outer Relation */ RID rid_outer, rid_inner; Record record_outer, record_inner; while(file_scan_outer.scanNext(rid_outer, record_outer) == OK) { /* Open the Index on the Inner Attribute (attr2) */ Datatype type = static_cast<Datatype>(attrDesc2.attrType); Index index_inner(relName2, attrDesc2.attrOffset, attrDesc2.attrLen, type, 0, status); if(status != OK) return status; /* Open a HeapFileScan object for the inner relation which we will need to get * Records from their RIDs using getRandomRecord */ HeapFileScan file_scan_inner(relName2, status); if(status != OK) return status; /* Start the Scan through the Matching Records Using the Index */ char *value = new char[attrDesc1.attrLen]; char *source = ((char*)record_outer.data) + attrDesc1.attrOffset; memcpy(value, source, attrDesc1.attrLen); index_inner.startScan(value); while(index_inner.scanNext(rid_inner) == OK) { file_scan_inner.getRandomRecord(rid_inner, record_inner); char *result_rec_data = new char[reclen]; Record result_rec = {result_rec_data, reclen}; int result_offset = 0; /* Do the Projection On The Fly */ for(int i=0; i<projCnt; i++) { char *source = NULL; if(attrDescArray[i].relName == relName1) source = ((char*)record_outer.data) + attrDescArray[i].attrOffset; else source = ((char*)record_inner.data) + attrDescArray[i].attrOffset; char *destination = result_rec_data + result_offset; int num_bytes = attrDescArray[i].attrLen; memcpy(destination, source, num_bytes); result_offset += num_bytes; } /* Insert the Result Record into the Result HeapFile */ RID result_rec_rid; status = result_heap_file.insertRecord(result_rec, result_rec_rid); delete [] result_rec_data; if(status != OK) return status; } index_inner.endScan(); } return OK; }