TEST(JoinTests, JoinPredicateTest) { oid_t join_test_types = 1; // Go over all join test types for(oid_t join_test_type = 0 ; join_test_type < join_test_types ; join_test_type++) { std::cout << "JOIN TEST ------------------------ :: " << std::to_string(join_test_type) << "\n"; // Go over all join algorithms for (auto join_algorithm : join_algorithms) { std::cout << "JOIN ALGORITHM :: " << PlanNodeTypeToString(join_algorithm) << "\n"; // Go over all join types for (auto join_type : join_types) { std::cout << "JOIN TYPE :: " << join_type << "\n"; // Execute the join test ExecuteJoinTest(join_algorithm, join_type, join_test_type); } } } }
/** * @brief Pretty print the plan tree. * @param The plan tree * @return none. */ void PlanExecutor::PrintPlan(const planner::AbstractPlan *plan, std::string prefix) { if (plan == nullptr) { LOG_TRACE("Plan is null"); return; } prefix += " "; LOG_TRACE("Plan Type: %s", PlanNodeTypeToString(plan->GetPlanNodeType()).c_str()); LOG_TRACE("%s->Plan Info :: %s ", prefix.c_str(), plan->GetInfo().c_str()); auto &children = plan->GetChildren(); LOG_TRACE("Number of children in plan: %d ", (int)children.size()); for (auto &child : children) { PrintPlan(child.get(), prefix); } }
// Get a string representation of this plan std::ostream &operator<<(std::ostream &os, const AbstractPlan &plan) { os << PlanNodeTypeToString(plan.GetPlanNodeType()); return os; }
/* * This a QueryPlan Processing function. It is a framework right now. Different * query type can be added. */ void PelotonService::QueryPlan(::google::protobuf::RpcController *controller, const QueryPlanExecRequest *request, QueryPlanExecResponse *response, ::google::protobuf::Closure *done) { // TODO: controller should be set, we probably use it in the future if (controller->Failed()) { std::string error = controller->ErrorText(); LOG_TRACE("PelotonService with controller failed:%s ", error.c_str()); } // If request is not null, this is a rpc call, server should handle the // reqeust if (request != NULL) { LOG_TRACE("Received a queryplan"); if (!request->has_plan_type()) { LOG_ERROR("Queryplan recived desen't have type"); return; } // construct parameter list // int param_num = request->param_num(); std::string param_list = request->param_list(); ReferenceSerializeInput param_input(param_list.c_str(), param_list.size()); std::vector<type::Value> params; // for (int it = 0; it < param_num; it++) { // // TODO: Make sure why varlen_pool is used as parameter // std::shared_ptr<type::VarlenPool> pool(new // type::VarlenPool(BackendType::MM)); // Value value_item; // value_item.DeserializeFromAllocateForStorage(param_input, pool.get()); // params.push_back(value_item); //} // construct TupleDesc // std::unique_ptr<tupleDesc> tuple_desc = // ParseTupleDescMsg(request->tuple_dec()); PlanNodeType plan_type = static_cast<PlanNodeType>(request->plan_type()); // TODO: We can add more plan type in this switch to process switch (plan_type) { case PlanNodeType::INVALID: { LOG_ERROR("Queryplan recived desen't have type"); break; } case PlanNodeType::SEQSCAN: { LOG_TRACE("SEQSCAN revieved"); std::string plan = request->plan(); ReferenceSerializeInput input(plan.c_str(), plan.size()); std::shared_ptr<peloton::planner::SeqScanPlan> ss_plan = std::make_shared<peloton::planner::SeqScanPlan>(); ss_plan->DeserializeFrom(input); std::vector<std::unique_ptr<executor::LogicalTile>> logical_tile_list; int tuple_count = peloton::executor::PlanExecutor::ExecutePlan( ss_plan.get(), params, logical_tile_list); // Return result if (tuple_count < 0) { // ExecutePlan fails LOG_ERROR("ExecutePlan fails"); return; } // Set the basic metadata response->set_tuple_count(tuple_count); response->set_tile_count(logical_tile_list.size()); // Loop the logical_tile_list to set the response std::vector<std::unique_ptr<executor::LogicalTile>>::iterator it; for (it = logical_tile_list.begin(); it != logical_tile_list.end(); it++) { // First materialize logicalTile to physical tile std::unique_ptr<storage::Tile> tile = (*it)->Materialize(); // Then serialize physical tile CopySerializeOutput output_tiles; tile->SerializeTo(output_tiles, tile->GetActiveTupleCount()); // Finally set the response, which be automatically sent back response->add_result(output_tiles.Data(), output_tiles.Size()); // Debug LOG_TRACE("Tile content is: %s", tile->GetInfo().c_str()); } break; } default: { LOG_ERROR("Queryplan recived :: Unsupported TYPE: %s", PlanNodeTypeToString(plan_type).c_str()); break; } } // If callback exist, run it if (done) { done->Run(); } } // Here is for the client callback for response else { // Process the response LOG_TRACE("proecess the Query response"); PL_ASSERT(response); UNUSED_ATTRIBUTE int tile_count = response->tile_count(); UNUSED_ATTRIBUTE int result_size = response->result_size(); PL_ASSERT(result_size == tile_count); for (int idx = 0; idx < result_size; idx++) { // Get the tile bytes std::string tile_bytes = response->result(idx); ReferenceSerializeInput tile_input(tile_bytes.c_str(), tile_bytes.size()); // Create a tile or tuple that depends on our protocol. // Tuple is prefered, since it voids copying from tile again // But we should prepare schema before creating tuple/tile. // Can we get the schema from local catalog? // storage::Tile tile; storage::Tuple tuple; // TODO: Make sure why varlen_pool is used as parameter // std::shared_ptr<VarlenPool> var_pool(new VarlenPool(BackendType::MM)); // Tile deserialization. // tile.DeserializeTuplesFrom(tile_input, var_pool); // We should remove tile header or no header when serialize, then use // tuple deserialize tuple.DeserializeWithHeaderFrom(tile_input); // Debug // LOG_TRACE("Recv a tile: %s", tile.GetInfo().c_str()); } } }