コード例 #1
0
void OptimizerTest::setupExpressions() {
  literal_0_ = E::ScalarLiteral::Create(TypedValue(0),
                                        TypeFactory::GetType(kInt, false /* nullable */));
  literal_1_ = E::ScalarLiteral::Create(TypedValue(1),
                                        TypeFactory::GetType(kInt, false /* nullable */));
  alias_0_ = createAlias(literal_0_,
                         "literal_0" /* attribute_name */,
                         "dummy_table" /* relation_name */);
  alias_1_ = createAlias(literal_1_,
                         "literal_1" /* attribute_name */,
                         "dummy_table" /* relation_name */);
  attribute_reference_0_ = E::ToRef(alias_0_);
  attribute_reference_1_ = E::ToRef(alias_1_);

  filter_predicate_0_ = E::ComparisonExpression::Create(
      ComparisonFactory::GetComparison(ComparisonID::kNotEqual),
      relation_attribute_reference_0_0_,
      relation_attribute_reference_0_2_);
  filter_predicate_1_ = E::ComparisonExpression::Create(
      ComparisonFactory::GetComparison(ComparisonID::kGreater),
      relation_attribute_reference_1_0_,
      literal_0_);
  hash_join_predicate_0_1_ = E::ComparisonExpression::Create(
      ComparisonFactory::GetComparison(ComparisonID::kEqual),
      relation_attribute_reference_0_0_,
      relation_attribute_reference_1_0_);
  non_hash_join_predicate_0_1_ = E::ComparisonExpression::Create(
      ComparisonFactory::GetComparison(ComparisonID::kGreater),
      relation_attribute_reference_0_0_,
      relation_attribute_reference_1_0_);
  add_literal_0_ = E::BinaryExpression::Create(
      BinaryOperationFactory::GetBinaryOperation(BinaryOperationID::kAdd),
      relation_attribute_reference_0_0_,
      literal_0_);
  alias_add_literal_0_ = E::Alias::Create(
      optimizer_context()->nextExprId(),
      add_literal_0_,
      "add_literal_0" /* attribute_name */,
      "add_literal_0" /* attribute_alias */,
      "" /* relation_name */);
}
コード例 #2
0
TEST_F(JoinTest, NestedLoopsJoinOnSelection) {
  // We pull a any Selection to a NestedLoopsJoin only if it does not have a
  // filter predicate.
  // Project -- NestedLoopsJoin -- Project
  //                            -- Project -- Filter
  const E::PredicatePtr join_predicate = E::ComparisonExpression::Create(
      ComparisonFactory::GetComparison(ComparisonID::kNotEqual),
      E::ToRef(alias_add_literal_0_),
      E::ToRef(alias_1_));
  const L::NestedLoopsJoinPtr nested_loops_join = L::NestedLoopsJoin::Create(
      logical_project_0_, logical_project_on_filter_1_, join_predicate);

  const E::AliasPtr alias_on_alias_reference = E::Alias::Create(
      optimizer_context()->nextExprId(),
      E::ToRef(alias_add_literal_0_),
      "alias_on_alias_reference" /* attribute_name */,
      "alias_on_alias_reference" /* attribute_alias */,
      "join_test_relation" /* relation_name */);
  input_logical_ = L::Project::Create(
      nested_loops_join, {alias_on_alias_reference} /* project_expressions */);

  // The top-level project references an attribute created by the left
  // underlying project of the nested loops join.
  // The project expression will be rewritten when the left project is merged to
  // the join.
  const E::AliasPtr alias_on_alias_reference_after_pullup =
      std::static_pointer_cast<const E::Alias>(alias_on_alias_reference->copyWithNewChildren(
          {alias_add_literal_0_->expression()} /* new_children */));
  const E::PredicatePtr join_predicate_after_pullup =
      E::ComparisonExpression::Create(
          ComparisonFactory::GetComparison(ComparisonID::kNotEqual),
          std::static_pointer_cast<const E::NamedExpression>(alias_add_literal_0_->expression()),
          E::ToRef(alias_1_));
  expected_physical_ = P::NestedLoopsJoin::Create(
      physical_table_reference_0_,
      physical_project_on_filter_1_,
      join_predicate_after_pullup,
      {alias_on_alias_reference_after_pullup} /* project_expressions */);
  EXPECT_CORRECT_PHYSICAL();
}
コード例 #3
0
void OptimizerTextTestRunner::runTestCase(const std::string &input,
                                          const std::set<std::string> &options,
                                          std::string *output) {
  CHECK(!options.empty()) << "No options specified";
  VLOG(4) << "Test SQL: " << input;

  sql_parser_.feedNextBuffer(new std::string(input));
  ParseResult result = sql_parser_.getNextStatement();

  OptimizerContext optimizer_context(tmb::kClientIdNone /* foreman_client_id */,
                                     0 /* query_id */,
                                     test_database_loader_.catalog_database(),
                                     nullptr /* storage_manager */,
                                     nullptr /* TMB */);
  if (result.condition != ParseResult::kSuccess) {
    *output = result.error_message;
  } else {
    // Number of options specified.
    int num_options = 0;
    std::ostringstream out_ss;
    try {
      logical::LogicalPtr initial_logical_plan;
      logical::LogicalPtr optimized_logical_plan;
      physical::PhysicalPtr physical_plan;

      const bool output_initial_logical_plan =
          (options.find(kTestOptions[0]) != options.end());
      const bool output_optimized_logical_plan =
          (options.find(kTestOptions[1]) != options.end());
      const bool output_physical_plan =
          (options.find(kTestOptions[2]) != options.end());
      if (output_initial_logical_plan) {
        initial_logical_plan =
            resolveParseTree(*result.parsed_statement, &optimizer_context);
        ++num_options;
      }
      if (output_optimized_logical_plan || output_physical_plan) {
        optimized_logical_plan =
            generateLogicalPlan(*result.parsed_statement, &optimizer_context);
        if (output_optimized_logical_plan) {
          ++num_options;
        }
      }
      if (output_physical_plan) {
        physical_plan =
            generatePhysicalPlan(optimized_logical_plan);
        ++num_options;
      }

      if (output_initial_logical_plan) {
        if (num_options > 1) {
          out_ss << "[Initial Logical Plan]\n";
        }
        out_ss << initial_logical_plan->toString();
      }
      if (output_optimized_logical_plan) {
        if (num_options > 1) {
          out_ss << "[Optimized Logical Plan]\n";
        }
        out_ss << optimized_logical_plan->toString();
      }
      if (output_physical_plan) {
        if (num_options > 1) {
          out_ss << "[Physical Plan]\n";
        }
        out_ss << physical_plan->toString();
      }
      *output = out_ss.str();
      CHECK(!output->empty());
    } catch (const SqlError &error) {
      *output = error.formatMessage(input);
    }
  }
}
コード例 #4
0
void CommandExecutorTestRunner::runTestCase(
    const std::string &input, const std::set<std::string> &options,
    std::string *output) {
  // TODO(qzeng): Test multi-threaded query execution when we have a Sort operator.

  VLOG(4) << "Test SQL(s): " << input;

  if (options.find(kResetOption) != options.end()) {
    test_database_loader_.clear();
    test_database_loader_.createTestRelation(false /* allow_vchar */);
    test_database_loader_.loadTestRelation();
  }

  MemStream output_stream;
  sql_parser_.feedNextBuffer(new std::string(input));

  while (true) {
    ParseResult result = sql_parser_.getNextStatement();

    O::OptimizerContext optimizer_context(0 /* query_id */,
                                          test_database_loader_.catalog_database(),
                                          test_database_loader_.storage_manager());

    if (result.condition != ParseResult::kSuccess) {
      if (result.condition == ParseResult::kError) {
        *output = result.error_message;
      }
      break;
    } else {
      std::printf("%s\n", result.parsed_statement->toString().c_str());
      try {
        if (result.parsed_statement->getStatementType() == ParseStatement::kCommand) {
          quickstep::cli::executeCommand(
              *result.parsed_statement,
              *(test_database_loader_.catalog_database()),
              main_thread_client_id_,
              foreman_->getBusClientID(),
              &bus_,
              test_database_loader_.storage_manager(),
              nullptr,
              output_stream.file());
        } else  {
          QueryHandle query_handle(optimizer_context.query_id());
          O::LogicalGenerator logical_generator(&optimizer_context);
          O::PhysicalGenerator physical_generator;
          O::ExecutionGenerator execution_generator(&optimizer_context, &query_handle);
          const P::PhysicalPtr physical_plan =
              physical_generator.generatePlan(
                  logical_generator.generatePlan(*result.parsed_statement));
          execution_generator.generatePlan(physical_plan);

          AdmitRequestMessage request_message(&query_handle);
          TaggedMessage admit_tagged_message(
              &request_message, sizeof(request_message), kAdmitRequestMessage);
          QueryExecutionUtil::SendTMBMessage(&bus_,
                                             main_thread_client_id_,
                                             foreman_->getBusClientID(),
                                             std::move(admit_tagged_message));

          // Receive workload completion message from Foreman.
          const AnnotatedMessage annotated_msg =
              bus_.Receive(main_thread_client_id_, 0, true);
          const TaggedMessage &tagged_message = annotated_msg.tagged_message;
          DCHECK_EQ(kWorkloadCompletionMessage, tagged_message.message_type());
          const CatalogRelation *query_result_relation = query_handle.getQueryResultRelation();
          if (query_result_relation) {
            PrintToScreen::PrintRelation(*query_result_relation,
                                         test_database_loader_.storage_manager(),
                                         output_stream.file());
            DropRelation::Drop(*query_result_relation,
                               test_database_loader_.catalog_database(),
                               test_database_loader_.storage_manager());
          }
        }
      } catch (const SqlError &error) {
        *output = error.formatMessage(input);
        break;
      }
    }
  }

  if (output->empty()) {
    *output = output_stream.str();
  }
}
コード例 #5
0
void ExecutionGeneratorTestRunner::runTestCase(
    const std::string &input, const std::set<std::string> &options,
    std::string *output) {
  // TODO(qzeng): Test multi-threaded query execution when we have a Sort operator.

  VLOG(4) << "Test SQL(s): " << input;

  if (options.find(kResetOption) != options.end()) {
    test_database_loader_.clear();
    test_database_loader_.createTestRelation(false /* allow_vchar */);
    test_database_loader_.loadTestRelation();
  }

  MemStream output_stream;
  sql_parser_.feedNextBuffer(new std::string(input));

  while (true) {
    ParseResult result = sql_parser_.getNextStatement();

    OptimizerContext optimizer_context(0 /* query_id */,
                                       test_database_loader_.catalog_database(),
                                       test_database_loader_.storage_manager());

    if (result.condition != ParseResult::kSuccess) {
      if (result.condition == ParseResult::kError) {
        *output = result.error_message;
      }
      break;
    } else {
      std::printf("%s\n", result.parsed_statement->toString().c_str());
      try {
        QueryHandle query_handle(optimizer_context.query_id());
        LogicalGenerator logical_generator(&optimizer_context);
        PhysicalGenerator physical_generator;
        ExecutionGenerator execution_generator(&optimizer_context,
                                               &query_handle);

        const physical::PhysicalPtr physical_plan =
            physical_generator.generatePlan(
                logical_generator.generatePlan(*result.parsed_statement));
        execution_generator.generatePlan(physical_plan);
        foreman_->setQueryPlan(
            query_handle.getQueryPlanMutable()->getQueryPlanDAGMutable());

        foreman_->reconstructQueryContextFromProto(query_handle.getQueryContextProto());

        foreman_->start();
        foreman_->join();

        const CatalogRelation *query_result_relation = query_handle.getQueryResultRelation();
        if (query_result_relation) {
            PrintToScreen::PrintRelation(*query_result_relation,
                                         test_database_loader_.storage_manager(),
                                         output_stream.file());
            DropRelation::Drop(*query_result_relation,
                               test_database_loader_.catalog_database(),
                               test_database_loader_.storage_manager());
        }
      } catch (const SqlError &error) {
        *output = error.formatMessage(input);
        break;
      }
    }
  }

  if (output->empty()) {
    *output = output_stream.str();
  }
}
コード例 #6
0
TEST_F(JoinTest, HashJoinOnSelection) {
  // Project -- HashJoin -- Project
  //                     -- Project -- Filter
  const L::HashJoinPtr hash_join =
      L::HashJoin::Create(logical_project_0_,
                          logical_project_on_filter_1_,
                          {relation_attribute_reference_0_0_},
                          {relation_attribute_reference_1_0_},
                          nullptr /* residual_predicate */,
                          L::HashJoin::JoinType::kInnerJoin);
  // References an attribute created by the left underlying project of the hash
  // join.
  const E::AliasPtr alias_on_alias_reference = E::Alias::Create(
      optimizer_context()->nextExprId(),
      E::ToRef(alias_add_literal_0_),
      "alias_on_alias_reference", /* attribute_name */
      "alias_on_alias_reference", /* attribute_alias */
      "join_test_relation" /* relation_name */);
  const E::AliasPtr alias_on_alias_reference_after_pullup =
      std::static_pointer_cast<const E::Alias>(alias_on_alias_reference->copyWithNewChildren(
          {alias_add_literal_0_->expression()} /* new_children */));
  input_logical_ = L::Project::Create(
      hash_join, {alias_on_alias_reference} /* project_expressions */);
  // Since the right Selection for the join have a filter, it will not be pulled
  // up.
  expected_physical_ = P::HashJoin::Create(
      physical_table_reference_0_,
      physical_project_on_filter_1_,
      {relation_attribute_reference_0_0_},
      {relation_attribute_reference_1_0_},
      E::PredicatePtr(),
      E::PredicatePtr(),
      {alias_on_alias_reference_after_pullup} /* project_expressions */,
      P::HashJoin::JoinType::kInnerJoin);
  EXPECT_CORRECT_PHYSICAL();

  // HashJoin -- Project
  //          -- Project
  const E::AliasPtr alias_on_attribute_reference =
      createAlias(relation_attribute_reference_1_0_, "alias_on_reference",
                  "join_test_relation");
  const L::ProjectPtr logical_project_on_attribute_reference =
      L::Project::Create(
          logical_table_reference_1_,
          {alias_on_attribute_reference} /* project_expressions */);
  const P::PhysicalPtr physical_project_on_attribute_reference =
      P::Selection::Create(
          physical_table_reference_1_,
          logical_project_on_attribute_reference->project_expressions(),
          E::PredicatePtr());
  physical_generator()->setBestPhysicalForLogical(
      logical_project_on_attribute_reference,
      physical_project_on_attribute_reference);

  // The left Project cannot be pulled up, while the right can be.
  input_logical_ = L::HashJoin::Create(logical_project_0_,
                                       logical_project_on_attribute_reference,
                                       {E::ToRef(alias_add_literal_0_)},
                                       {relation_attribute_reference_1_0_},
                                       nullptr /* residual_predicate */,
                                       L::HashJoin::JoinType::kInnerJoin);
  std::vector<E::NamedExpressionPtr> project_expressions(
      E::ToNamedExpressions(physical_project_0_->getOutputAttributes()));
  project_expressions.push_back(alias_on_attribute_reference);
  expected_physical_ =
      P::HashJoin::Create(physical_project_0_,
                          physical_table_reference_1_,
                          {E::ToRef(alias_add_literal_0_)},
                          {relation_attribute_reference_1_0_},
                          E::PredicatePtr(),
                          E::PredicatePtr(),
                          project_expressions,
                          P::HashJoin::JoinType::kInnerJoin);
  EXPECT_CORRECT_PHYSICAL();
}