Relation* Delete(vector<string> &words, SchemaManager &schema_manager, MainMemory &mem){

	Relation* relation_ptr = schema_manager.getRelation(words[2]);
	vector<string>::iterator it = find(words.begin(), words.end(), "WHERE");
	// no WHERE, delete everything
	if (it == words.end()){
		relation_ptr->deleteBlocks(0);	
	}
	// with WHERE clause
	else{
		vector<string> where_list(it, words.end());
		preProcess(vector<string> (1, words[2]), where_list, schema_manager);
		Relation * new_relation = generateDLQP(where_list, words[2], schema_manager, mem);
		// very ....
		schema_manager.deleteRelation(words[2]);
		Relation* newRR = schema_manager.createRelation(words[2], new_relation->getSchema());		
		assert(!free_blocks.empty());
		int memory_block_index = free_blocks.front();
		free_blocks.pop();

		int dBlocks = new_relation->getNumOfBlocks();

		int size =  0;
		Block * block_ptr = NULL;
		while(size < dBlocks){
			// read the relatioin block by block
			new_relation->getBlock(size, memory_block_index);
			block_ptr = mem.getBlock(memory_block_index);

			vector<Tuple> tuples = block_ptr->getTuples();
			if(tuples.empty()){
				cerr<<"Warning In Delete: No tuples in the current mem block!"<<endl;
			}
			for(int i = 0; i < tuples.size(); ++i){
				Tuple t = tuples[i];
				appendTupleToRelation(newRR, mem, t);
			}
			size++;
		}
		free_blocks.push(memory_block_index);

		//	cout<<newRR->getRelationName()<<endl;
		//	cout<<*newRR<<endl;
	}
	relation_ptr = schema_manager.getRelation(words[2]);
	cout<<relation_ptr<<endl;
	return relation_ptr;
}
Relation* Insert(vector<string> &words, string &line, SchemaManager &schema_manager, MainMemory &mem){
	Relation* relation_ptr = schema_manager.getRelation(words[2]);

	vector<string>::iterator it = find(words.begin(), words.end(), "SELECT");
	// no select
	if (it == words.end()){
		// get insert vals
		vector<string> content = splitBy(line, "()");
		vector<string> fields = splitBy(content[1], ", ");
		vector<string> vals = splitBy(content[3], ",");
		//preProcess(vector<string>(1, words[2]), fields, schema_manager);
		preProcess(vector<string>(1, words[2]), vals, schema_manager);

		assert(fields.size() == vals.size());

		Tuple tuple = relation_ptr->createTuple();

		// standard insert doesn't have table names
		vector<string> col_names = nakedFieldNames(relation_ptr);

		// comparing 
		for (int i = 0; i < fields.size(); i++){
			for (int j = 0; j < col_names.size(); j++){
				// this is a match
				if (fields[i] == col_names[j]){
					if (tuple.getSchema().getFieldType(j) == INT){
						tuple.setField(j, atoi(vals[i].c_str()));
					}
					else{
						tuple.setField(j, vals[i]);
					}
					break;
				}
			}
		}
		appendTupleToRelation(relation_ptr, mem, tuple);
	}
	// with SELECT
	else{
		vector<string> SFW(it, words.end());	
		Relation* new_relation = Select(SFW, schema_manager, mem);
		assert(new_relation);

		vector<string> new_field_names = nakedFieldNames(new_relation);
		vector<string> field_names = nakedFieldNames(relation_ptr);

		// mapping: index of new_field_names to field_names 
		vector<int> mapping(new_field_names.size(), -1);
		for (int i = 0; i < new_field_names.size(); i++){
			for (int j = 0; j < field_names.size(); j++){
				if (new_field_names[i] == field_names[j]){
					mapping[i] = j;
					break;
				}
			}
		}

		int new_field_size = new_relation->getSchema().getNumOfFields();

		// warning: new_relation and relation_ptr might be the same!
		// get all tuples from the new_relation in one run
		vector<Tuple> new_tuples;
		for (int i = 0; i < new_relation->getNumOfBlocks(); i++){

			assert(!free_blocks.empty());
			int memory_block_index = free_blocks.front();
			free_blocks.pop();

			// read the relation block by block
			new_relation->getBlock(i, memory_block_index);
			Block* block_ptr = mem.getBlock(memory_block_index);
			assert(block_ptr);
			vector<Tuple> block_tuples = block_ptr->getTuples();
			new_tuples.insert(new_tuples.end(), block_tuples.begin(), block_tuples.end());
			if(new_tuples.empty()){
				cerr<<"Warning: Insert from SFW, No tuples in the current mem block!"<<endl;
			}
			free_blocks.push(memory_block_index);
		}

		for (int j = 0; j < new_tuples.size(); j++){
			Tuple tuple = relation_ptr->createTuple();
			for (int k = 0; k < new_field_size; k++){
				if (mapping[k] != -1){
					int idx = mapping[k];
					assert(idx < relation_ptr->getSchema().getNumOfFields() && idx >= 0);
					if (tuple.getSchema().getFieldType(idx) == INT){
						int val = new_tuples[j].getField(k).integer;
						tuple.setField(field_names[idx], val);
					}
					else{
						string *str = new_tuples[j].getField(k).str;
						tuple.setField(field_names[idx], *str);
					}
				}
			}
			appendTupleToRelation(relation_ptr, mem, tuple);
		}
		cout<<*relation_ptr<<endl;
	}
	return relation_ptr;
}
Example #3
0
Relation * orderByRelationTwoPass(Relation *relation_ptr, vector<string> &field_name, vector<enum FIELD_TYPE> &field_type,
                            bool returnRelation) {
  Block *block_ptr;

  // Every 9 blocks of the relation are sorted
  int sorted_blocks = 9;
  int num_relation_blocks = relation_ptr->getNumOfBlocks();
  int num_groups = (num_relation_blocks - 1) / 9 + 1;
  int first_min_index;
  vector<int> blocks_used;
  Relation *ordered_relation_ptr = NULL;
  Schema schema;

  if (returnRelation) {
    schema = relation_ptr->getSchema();
    ordered_relation_ptr = schema_manager.createRelation(relation_ptr->getRelationName() + "_ordered",
						         Schema(schema.getFieldNames(), schema.getFieldTypes()));
  }

  // Bring first block of each group in memory
  for (int i = 0; i < num_groups; i++) {
    block_ptr = mem.getBlock(i);
    block_ptr->clear();
    relation_ptr->getBlock(i * sorted_blocks, i);
    blocks_used.push_back(1);
  }

  while(1) {
    Block *min_tuple_block_ptr = NULL;
    int min_tuple_index = -1;

    for(int i = 0; i < num_groups; i++) {

      block_ptr = mem.getBlock(i);
      vector<Tuple> tuples = block_ptr->getTuples();
      
      // Try to get the first unconsidered tuple from this sublist
      while ( (first_min_index = getFirstMinTuple(tuples)) == -1) {
        // Use 1 more block
        blocks_used[i] += 1;
        if ( (i == num_groups - 1) && (blocks_used[i] > ((num_relation_blocks - 1) % 9 + 1)))
          break;
        if (blocks_used[i] > sorted_blocks)
          break;
        // Bring another block from the sublist into the memory
        relation_ptr->getBlock(i * sorted_blocks + blocks_used[i] - 1, i);
        tuples = block_ptr->getTuples();
      }

      // This sublist has been exhausted
      if (first_min_index == -1)
        continue;

      if (isSmaller(field_name, field_type, block_ptr->getTuple(first_min_index),
                    min_tuple_block_ptr, min_tuple_index)) {
          min_tuple_block_ptr = block_ptr;
          min_tuple_index = first_min_index;
      }
    }

    // If no min tuple found, break
    if (!min_tuple_block_ptr)
      break;

    Tuple min_tuple = min_tuple_block_ptr->getTuple(min_tuple_index);
    if (!returnRelation)
      min_tuple.printTuple();
    else
      appendTupleToRelation(ordered_relation_ptr, 9, min_tuple);
    min_tuple_block_ptr->nullTuple(min_tuple_index);
  }
  return ordered_relation_ptr;
}