//--------------------------------------------------------------------------- int main() { Database db; db.open("data/uni"); Table& studenten=db.getTable("studenten"); Table& hoeren=db.getTable("hoeren"); //from Studenten s1, Studenten s2, hoeren h1, hoeren h2 unique_ptr<Tablescan> scanStudenten1(new Tablescan(studenten)); unique_ptr<Tablescan> scanStudenten2(new Tablescan(studenten)); unique_ptr<Tablescan> scanHoeren1(new Tablescan(hoeren)); unique_ptr<Tablescan> scanHoeren2(new Tablescan(hoeren)); const Register* name1=scanStudenten1->getOutput("name"); const Register* name2=scanStudenten2->getOutput("name"); const Register* matrNr1=scanStudenten1->getOutput("matrnr"); const Register* matrNr2=scanStudenten2->getOutput("matrnr"); const Register* matrNrHoeren1=scanHoeren1->getOutput("matrnr"); const Register* matrNrHoeren2=scanHoeren2->getOutput("matrnr"); const Register* vorlNrHoeren1=scanHoeren1->getOutput("vorlnr"); const Register* vorlNrHoeren2=scanHoeren2->getOutput("vorlnr"); //where s1.Name='Schopenhauer' std::string name = "Schopenhauer"; Register* n = new Register(); n->setString(name); unique_ptr<Selection> select(new Selection(move(scanStudenten1),name1,n)); //and s1.MatrNr=h1.MatrNr unique_ptr<CrossProduct> cp(new CrossProduct(move(select),move(scanHoeren1))); unique_ptr<Selection> select2(new Selection(move(cp),matrNr1,matrNrHoeren1)); //and h1.VorlNr=h2.VorlNr unique_ptr<CrossProduct> cp2(new CrossProduct(move(select2),move(scanHoeren2))); unique_ptr<Selection> select3(new Selection(move(cp2),vorlNrHoeren1,vorlNrHoeren2)); // and h1.MatrNr!=h2.MatrNr unique_ptr<Chi> chi(new Chi(move(select3),Chi::NotEqual,matrNrHoeren1,matrNrHoeren2)); const Register* chiResult=chi->getResult(); unique_ptr<Selection> select4(new Selection(move(chi),chiResult)); //and h2.MatrNr = s2.MatrNr unique_ptr<CrossProduct> cp3(new CrossProduct(move(select4),move(scanStudenten2))); unique_ptr<Selection> select5(new Selection(move(cp3),matrNrHoeren2,matrNr2)); //select s2.Name unique_ptr<Projection> project(new Projection(move(select5),{name2})); Printer out(move(project)); out.open(); while (out.next()); out.close(); }
//--------------------------------------------------------------------------- void task1() { cout << endl << "***** Find all students that attended the lectures together with Schopenhauer, excluding Schopenhauer himself. *****" << endl; // open database Database db; db.open("data/uni"); // FROM Table& s1=db.getTable("studenten"); Table& h1=db.getTable("hoeren"); Table& s2=db.getTable("studenten"); Table& h2=db.getTable("hoeren"); unique_ptr<Tablescan> scan_s1(new Tablescan(s1)); unique_ptr<Tablescan> scan_h1(new Tablescan(h1)); unique_ptr<Tablescan> scan_s2(new Tablescan(s2)); unique_ptr<Tablescan> scan_h2(new Tablescan(h2)); // columns const Register* s1_name=scan_s1->getOutput("name"); const Register* s2_name=scan_s2->getOutput("name"); const Register* s1_matrnr=scan_s1->getOutput("matrnr"); const Register* h1_matrnr=scan_h1->getOutput("matrnr"); const Register* s2_matrnr=scan_s2->getOutput("matrnr"); const Register* h2_matrnr=scan_h2->getOutput("matrnr"); // filter s1 and s2 for (in)equality to "Schopenhauer" Register schopenhauer; schopenhauer.setString("Schopenhauer"); unique_ptr<Chi> s1_filter(new Chi(move(scan_s1),Chi::Equal,s1_name,&schopenhauer)); const Register* s1_filtered_result=s1_filter->getResult(); unique_ptr<Selection> s1_filtered(new Selection(move(s1_filter),s1_filtered_result)); unique_ptr<Chi> s2_filter(new Chi(move(scan_s2),Chi::NotEqual,s2_name,&schopenhauer)); const Register* s2_filtered_result=s2_filter->getResult(); unique_ptr<Selection> s2_filtered(new Selection(move(s2_filter),s2_filtered_result)); // join s1, h1 unique_ptr<HashJoin> hjoin1(new HashJoin(move(s1_filtered),move(scan_h1), s1_matrnr, h1_matrnr)); // join s2, h2 unique_ptr<HashJoin> hjoin2(new HashJoin(move(s2_filtered),move(scan_h2), s2_matrnr, h2_matrnr)); // cross product of both joins unique_ptr<CrossProduct> cp(new CrossProduct(move(hjoin1),move(hjoin2))); // Project to s2.name unique_ptr<Projection> project(new Projection(move(cp),{s2_name})); // distinct s2.name unique_ptr<Distinct> dist(new Distinct(move(project),{s2_name})); // print result Printer out(move(dist)); out.open(); while (out.next()); out.close(); }
//--------------------------------------------------------------------------- static void readIndex(istream& in,map<Register,unsigned>& index,Attribute::Type type,unsigned cardinality) // Read an index { unsigned count; in.read(reinterpret_cast<char*>(&count),sizeof(count)); if (count!=cardinality) { cerr << "index corruption encountered, reload the database" << endl; throw; } index.clear(); switch (type) { case Attribute::Type::Int: for (unsigned index2=0;index2<count;++index2) { int val; unsigned pos; in.read(reinterpret_cast<char*>(&val),sizeof(val)); in.read(reinterpret_cast<char*>(&pos),sizeof(pos)); Register r; r.setInt(val); index[r]=pos; } break; case Attribute::Type::Double: for (unsigned index2=0;index2<count;++index2) { double val; unsigned pos; in.read(reinterpret_cast<char*>(&val),sizeof(val)); in.read(reinterpret_cast<char*>(&pos),sizeof(pos)); Register r; r.setDouble(val); index[r]=pos; } break; case Attribute::Type::Bool: for (unsigned index2=0;index2<count;++index2) { bool val; unsigned pos; in.read(reinterpret_cast<char*>(&val),sizeof(val)); in.read(reinterpret_cast<char*>(&pos),sizeof(pos)); Register r; r.setBool(val); index[r]=pos; } break; case Attribute::Type::String: for (unsigned index2=0;index2<count;++index2) { unsigned valLen,pos; string val; in.read(reinterpret_cast<char*>(&valLen),sizeof(valLen)); val.resize(valLen); in.read(const_cast<char*>(val.data()),valLen); in.read(reinterpret_cast<char*>(&pos),sizeof(pos)); Register r; r.setString(val); index[r]=pos; } break; } }
std::vector<Register*> SPSegment::toRegisterVector(const char* data) { Schema::Relation relation = this->relation(); unsigned nextVarLength = 0; unsigned offset = 0; vector<Register*> result = vector<Register*>(); for (auto attr = relation.attributes.begin(); attr != relation.attributes.end(); attr++) { switch ((*attr).type) { case Types::Tag::Integer: nextVarLength += sizeof(int); break; case Types::Tag::Char: nextVarLength += sizeof(unsigned); break; } } for (auto attr = relation.attributes.begin(); attr != relation.attributes.end(); attr++) { Register* reg = new Register(); switch ((*attr).type) { case Types::Tag::Integer: reg->setInteger(*(reinterpret_cast<const int*>(data + offset))); offset += sizeof(int); break; case Types::Tag::Char: const char* str = data + nextVarLength; const unsigned endOffset = *(reinterpret_cast<const unsigned*>(data + offset)); reg->setString(string(str, offset + endOffset - nextVarLength)); offset += sizeof(unsigned); break; } result.push_back(reg); } return result; }
/** * Apply all Selections of the form <attribute>='<constant>' to the joinPlan */ void ExecutionPlan::applySelections(){ //replace base relations by resulting tables after selection if there is a selection <attribute>='<constant>' cout<<"---Selections:---"<<endl; for (unsigned int i = 0; i < r.selections.size(); i++) { //find tablescan using the binding unsigned int index = 0; for (; index < r.relations.size(); index++) { if (r.selections.at(i).first.relation.compare( r.relations.at(index).binding) == 0) { break; } } //apply selections const Register* attributeRegister = getRegister( r.selections.at(i).first); Register* constantRegister = new Register(); constantRegister->setString(r.selections.at(i).second.value); cout<<"Register: "<<r.selections.at(i).first.getName()<<"="<<r.selections.at(i).second.value<<endl; unique_ptr<Selection> select( new Selection(move(joinPlan.at(index).second), attributeRegister, constantRegister)); //replace base relation with relations after selection joinPlan.at(index).second = move(select); if(joinPlan.at(index).second==NULL){ throw ""; } } }
//executes query canonically void Executor::execute(query q){ Database db; db.open("data/uni"); if(q.from.size() >= 1){ unordered_map<string, unordered_map<string, const Register*>> registers; unique_ptr<Operator> crossproduct(nullptr); //Make crossproducts int counter = 0; for(auto it = q.from.begin(); it != q.from.end(); ++it) { unique_ptr<Tablescan> tablescan(new Tablescan(db.getTable(it->first))); //Used for constants push down //Get names of all attributes an populate tables vector<string> names = db.getTable(it->first).getAttributeNames(); populateRegisterTable(®isters, *tablescan, &names, it->second); unique_ptr<Operator> selection(move(tablescan)); //Find pushdowns and execute them for(auto it2 = q.where.begin(); it2 != q.where.end(); it2++){ if((*it2).r_attr.first == "" && (*it2).l_attr.first == it->second){ //See if bindings are the same Register* registertmp = new Register(); //tmpp int attrIndex = db.getTable(it->first).findAttribute((*it2).l_attr.second); if(attrIndex < 0){ throw "NO EXISTENT ATTRIBUTE"; } const Attribute& attr = db.getTable(it->first).getAttribute(attrIndex); Attribute::Type attr_type = attr.getType(); string name = attr.getName(); //Check type for attribute if(attr_type == Attribute::Type::Int) { int tmp; size_t end; tmp = stoi((*it2).r_attr.second, &end); registertmp->setInt(tmp); } else if(attr_type == Attribute::Type::Double) { int tmp; size_t end; tmp = stod((*it2).r_attr.second, &end); registertmp->setInt(tmp); } else if(attr_type == Attribute::Type::Bool) { //TODO } else { registertmp->setString((*it2).r_attr.second); } unique_ptr<Operator> seltmp(new Selection(move(selection), registers[it->second][(*it2).l_attr.second] ,registertmp )); //tmp selection.swap(seltmp); } } if(crossproduct == nullptr){ crossproduct.swap(selection); } else{ unique_ptr<Operator> dummy(new CrossProduct(move(selection), move(crossproduct))); crossproduct.swap(dummy); } } //Find join conditions and execute them for(auto it2 = q.where.begin(); it2 != q.where.end(); it2++){ if((*it2).r_attr.first != ""){ //See if bindings are the string rightTable; string leftTable; for(auto it3 = q.from.begin(); it3 != q.from.end(); ++it3 ){ if(it3->second == (*it2).r_attr.first) { rightTable = it3->second; } else if(it3->second == (*it2).l_attr.first) { leftTable = it3->second; } } unique_ptr<Operator> seltmp(new Selection(move(crossproduct), registers[leftTable][(*it2).l_attr.second] ,registers[rightTable][(*it2).r_attr.second] )); //tmp crossproduct.swap(seltmp); } } //Print the names of the students Printer out(move(crossproduct)); out.open(); while (out.next()); out.close(); } }