예제 #1
0
//---------------------------------------------------------------------------
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();

}
예제 #2
0
파일: exercise01.cpp 프로젝트: hofst/tinydb
//---------------------------------------------------------------------------
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();
}
예제 #3
0
//---------------------------------------------------------------------------
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;
   }
}
예제 #4
0
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;
}
예제 #5
0
/**
 * 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 "";
			}
		}
}
예제 #6
0
//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(&registers, *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();
	}	
}