Added unit tests for the distributed version.
Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/cdc1e053 Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/cdc1e053 Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/cdc1e053 Branch: refs/heads/quickstep-28-29 Commit: cdc1e053b34aff46104397405642cd9c64b7d5f1 Parents: 59f4dab Author: Zuyu Zhang <zu...@twitter.com> Authored: Sun Aug 14 00:02:20 2016 -0700 Committer: Zuyu Zhang <zu...@twitter.com> Committed: Tue Aug 16 13:33:54 2016 -0700 ---------------------------------------------------------------------- query_optimizer/tests/CMakeLists.txt | 35 ++++ .../tests/DistributedExecutionGeneratorTest.cpp | 62 +++++++ .../DistributedExecutionGeneratorTestRunner.cpp | 162 +++++++++++++++++++ .../DistributedExecutionGeneratorTestRunner.hpp | 118 ++++++++++++++ .../tests/execution_generator/CMakeLists.txt | 70 ++++++++ 5 files changed, 447 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/cdc1e053/query_optimizer/tests/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/CMakeLists.txt b/query_optimizer/tests/CMakeLists.txt index 4969ada..597dbe0 100644 --- a/query_optimizer/tests/CMakeLists.txt +++ b/query_optimizer/tests/CMakeLists.txt @@ -80,6 +80,14 @@ target_link_libraries(quickstep_queryoptimizer_tests_TestDatabaseLoader quickstep_utility_Macros tmb) +if (ENABLE_DISTRIBUTED) + add_executable(quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest + DistributedExecutionGeneratorTest.cpp + DistributedExecutionGeneratorTestRunner.cpp + DistributedExecutionGeneratorTestRunner.hpp + "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.cpp" + "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.hpp") +endif(ENABLE_DISTRIBUTED) add_executable(quickstep_queryoptimizer_tests_ExecutionGeneratorTest ExecutionGeneratorTest.cpp ExecutionGeneratorTestRunner.cpp @@ -109,6 +117,33 @@ add_executable(quickstep_queryoptimizer_tests_OptimizerTextTest "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.cpp" "${PROJECT_SOURCE_DIR}/utility/textbased_test/TextBasedTest.hpp") +if (ENABLE_DISTRIBUTED) + target_link_libraries(quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest + glog + gtest + quickstep_catalog_CatalogTypedefs + quickstep_cli_DropRelation + quickstep_cli_PrintToScreen + quickstep_parser_ParseStatement + quickstep_parser_SqlParserWrapper + quickstep_queryexecution_ForemanDistributed + quickstep_queryexecution_QueryExecutionTypedefs + quickstep_queryexecution_QueryExecutionUtil + quickstep_queryexecution_Shiftboss + quickstep_queryexecution_Worker + quickstep_queryexecution_WorkerDirectory + quickstep_queryoptimizer_Optimizer + quickstep_queryoptimizer_OptimizerContext + quickstep_queryoptimizer_QueryHandle + quickstep_queryoptimizer_tests_TestDatabaseLoader + quickstep_utility_Macros + quickstep_utility_MemStream + quickstep_utility_SqlError + quickstep_utility_TextBasedTestDriver + tmb + ${GFLAGS_LIB_NAME} + ${LIBS}) +endif(ENABLE_DISTRIBUTED) target_link_libraries(quickstep_queryoptimizer_tests_ExecutionGeneratorTest glog gtest http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/cdc1e053/query_optimizer/tests/DistributedExecutionGeneratorTest.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/DistributedExecutionGeneratorTest.cpp b/query_optimizer/tests/DistributedExecutionGeneratorTest.cpp new file mode 100644 index 0000000..af310bc --- /dev/null +++ b/query_optimizer/tests/DistributedExecutionGeneratorTest.cpp @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#include <fstream> +#include <memory> + +#include "query_optimizer/tests/DistributedExecutionGeneratorTestRunner.hpp" +#include "utility/textbased_test/TextBasedTestDriver.hpp" +#include "utility/textbased_test/TextBasedTest.hpp" + +#include "gflags/gflags.h" +#include "glog/logging.h" +#include "gtest/gtest.h" + +using quickstep::TextBasedTest; + +QUICKSTEP_GENERATE_TEXT_TEST(DISTRIBUTED_EXECUTION_GENERATOR_TEST); + +int main(int argc, char** argv) { + google::InitGoogleLogging(argv[0]); + // Honor FLAGS_buffer_pool_slots in StorageManager. + gflags::ParseCommandLineFlags(&argc, &argv, true); + + if (argc < 4) { + LOG(ERROR) << "Must have at least 3 arguments, but " << argc - 1 + << " are provided"; + } + + std::ifstream input_file(argv[1]); + CHECK(input_file.is_open()) << argv[1]; + std::unique_ptr<quickstep::optimizer::DistributedExecutionGeneratorTestRunner> + test_runner( + new quickstep::optimizer::DistributedExecutionGeneratorTestRunner(argv[3])); + test_driver.reset( + new quickstep::TextBasedTestDriver(&input_file, test_runner.get())); + test_driver->registerOption( + quickstep::optimizer::DistributedExecutionGeneratorTestRunner::kResetOption); + + ::testing::InitGoogleTest(&argc, argv); + const int success = RUN_ALL_TESTS(); + if (success != 0) { + test_driver->writeActualOutputToFile(argv[2]); + } + + return success; +} http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/cdc1e053/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.cpp ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.cpp b/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.cpp new file mode 100644 index 0000000..5cccc21 --- /dev/null +++ b/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.cpp @@ -0,0 +1,162 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#include "query_optimizer/tests/DistributedExecutionGeneratorTestRunner.hpp" + +#include <cstdio> +#include <set> +#include <string> +#include <vector> + +#include "catalog/CatalogTypedefs.hpp" +#include "cli/DropRelation.hpp" +#include "cli/PrintToScreen.hpp" +#include "parser/ParseStatement.hpp" +#include "query_execution/ForemanDistributed.hpp" +#include "query_execution/QueryExecutionTypedefs.hpp" +#include "query_optimizer/OptimizerContext.hpp" +#include "query_optimizer/QueryHandle.hpp" +#include "utility/MemStream.hpp" +#include "utility/SqlError.hpp" + +#include "glog/logging.h" + +#include "tmb/id_typedefs.h" +#include "tmb/message_bus.h" +#include "tmb/tagged_message.h" + +using std::string; +using std::make_unique; +using std::vector; + +namespace quickstep { + +class CatalogRelation; + +namespace optimizer { + +const char *DistributedExecutionGeneratorTestRunner::kResetOption = + "reset_before_execution"; + +DistributedExecutionGeneratorTestRunner::DistributedExecutionGeneratorTestRunner(const string &storage_path) + : query_id_(0), + test_database_loader_(storage_path) { + test_database_loader_.createTestRelation(false /* allow_vchar */); + test_database_loader_.loadTestRelation(); + + bus_.Initialize(); + + cli_id_ = bus_.Connect(); + bus_.RegisterClientAsSender(cli_id_, kAdmitRequestMessage); + bus_.RegisterClientAsSender(cli_id_, kPoisonMessage); + bus_.RegisterClientAsReceiver(cli_id_, kQueryExecutionSuccessMessage); + + // NOTE(zuyu): Foreman should initialize before Shiftboss so that the former + // could receive a registration message from the latter. + foreman_ = make_unique<ForemanDistributed>(&bus_, test_database_loader_.catalog_database()); + + // We don't use the NUMA aware version of worker code. + const vector<numa_node_id> numa_nodes(1 /* Number of worker threads per instance */, + kAnyNUMANodeID); + + for (int i = 0; i < kNumInstances; ++i) { + workers_.push_back(make_unique<Worker>(0 /* worker_thread_index */, &bus_)); + + const vector<tmb::client_id> worker_client_ids(1, workers_[i]->getBusClientID()); + worker_directories_.push_back( + make_unique<WorkerDirectory>(worker_client_ids.size(), worker_client_ids, numa_nodes)); + + shiftbosses_.push_back( + make_unique<Shiftboss>(&bus_, test_database_loader_.storage_manager(), worker_directories_[i].get())); + } + + foreman_->start(); + + for (int i = 0; i < kNumInstances; ++i) { + shiftbosses_[i]->start(); + workers_[i]->start(); + } +} + +void DistributedExecutionGeneratorTestRunner::runTestCase( + const string &input, const std::set<string> &options, 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 string(input)); + + while (true) { + ParseResult result = sql_parser_.getNextStatement(); + if (result.condition != ParseResult::kSuccess) { + if (result.condition == ParseResult::kError) { + *output = result.error_message; + } + break; + } + + const ParseStatement &parse_statement = *result.parsed_statement; + std::printf("%s\n", parse_statement.toString().c_str()); + try { + OptimizerContext optimizer_context; + QueryHandle query_handle(query_id_++, cli_id_); + + optimizer_.generateQueryHandle(parse_statement, + test_database_loader_.catalog_database(), + &optimizer_context, + &query_handle); + + QueryExecutionUtil::ConstructAndSendAdmitRequestMessage( + cli_id_, + foreman_->getBusClientID(), + &query_handle, + &bus_); + + const tmb::AnnotatedMessage annotated_message = bus_.Receive(cli_id_, 0, true); + DCHECK_EQ(kQueryExecutionSuccessMessage, annotated_message.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(); + } +} + +} // namespace optimizer +} // namespace quickstep http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/cdc1e053/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.hpp ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.hpp b/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.hpp new file mode 100644 index 0000000..e4d0765 --- /dev/null +++ b/query_optimizer/tests/DistributedExecutionGeneratorTestRunner.hpp @@ -0,0 +1,118 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + **/ + +#ifndef QUICKSTEP_QUERY_OPTIMIZER_TESTS_DISTRIBUTED_EXECUTION_GENERATOR_TEST_RUNNER_HPP_ +#define QUICKSTEP_QUERY_OPTIMIZER_TESTS_DISTRIBUTED_EXECUTION_GENERATOR_TEST_RUNNER_HPP_ + +#include <cstddef> +#include <memory> +#include <set> +#include <string> +#include <utility> +#include <vector> + +#include "parser/SqlParserWrapper.hpp" +#include "query_execution/ForemanDistributed.hpp" +#include "query_execution/QueryExecutionTypedefs.hpp" +#include "query_execution/QueryExecutionUtil.hpp" +#include "query_execution/Shiftboss.hpp" +#include "query_execution/Worker.hpp" +#include "query_execution/WorkerDirectory.hpp" +#include "query_optimizer/Optimizer.hpp" +#include "query_optimizer/tests/TestDatabaseLoader.hpp" +#include "utility/Macros.hpp" +#include "utility/textbased_test/TextBasedTestRunner.hpp" + +#include "glog/logging.h" + +#include "tmb/id_typedefs.h" +#include "tmb/message_bus.h" +#include "tmb/tagged_message.h" + +namespace quickstep { +namespace optimizer { + +namespace { +constexpr int kNumInstances = 1; +} // namespace + +/** + * @brief TextBasedTestRunner for testing the ExecutionGenerator in the + * distributed version. + */ +class DistributedExecutionGeneratorTestRunner : public TextBasedTestRunner { + public: + /** + * @brief If this option is enabled, recreate the entire database and + * repopulate the data before every test. + */ + static const char *kResetOption; + + /** + * @brief Constructor. + */ + explicit DistributedExecutionGeneratorTestRunner(const std::string &storage_path); + + ~DistributedExecutionGeneratorTestRunner() { + tmb::TaggedMessage poison_tagged_message(quickstep::kPoisonMessage); + + const tmb::MessageBus::SendStatus send_status = + QueryExecutionUtil::SendTMBMessage( + &bus_, + cli_id_, + foreman_->getBusClientID(), + std::move(poison_tagged_message)); + CHECK(send_status == tmb::MessageBus::SendStatus::kOK); + + for (int i = 0; i < kNumInstances; ++i) { + workers_[i]->join(); + shiftbosses_[i]->join(); + } + + foreman_->join(); + } + + void runTestCase(const std::string &input, + const std::set<std::string> &options, + std::string *output) override; + + private: + std::size_t query_id_; + + SqlParserWrapper sql_parser_; + TestDatabaseLoader test_database_loader_; + Optimizer optimizer_; + + MessageBusImpl bus_; + + tmb::client_id cli_id_; + + std::unique_ptr<ForemanDistributed> foreman_; + + std::vector<std::unique_ptr<Worker>> workers_; + std::vector<std::unique_ptr<WorkerDirectory>> worker_directories_; + std::vector<std::unique_ptr<Shiftboss>> shiftbosses_; + + DISALLOW_COPY_AND_ASSIGN(DistributedExecutionGeneratorTestRunner); +}; + +} // namespace optimizer +} // namespace quickstep + +#endif // QUICKSTEP_QUERY_OPTIMIZER_TESTS_DISTRIBUTED_EXECUTION_GENERATOR_TEST_RUNNER_HPP_ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/cdc1e053/query_optimizer/tests/execution_generator/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/query_optimizer/tests/execution_generator/CMakeLists.txt b/query_optimizer/tests/execution_generator/CMakeLists.txt index 0c00ff6..1ea6a17 100644 --- a/query_optimizer/tests/execution_generator/CMakeLists.txt +++ b/query_optimizer/tests/execution_generator/CMakeLists.txt @@ -15,6 +15,63 @@ # specific language governing permissions and limitations # under the License. +if (ENABLE_DISTRIBUTED) + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_create + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Create.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedCreate.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedCreate/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_delete + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Delete.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedDelete.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedDelete/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_distinct + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Distinct.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedDistinct.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedDistinct/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_drop + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Drop.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedDrop.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedDrop/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_index + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Index.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedIndex.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedIndex/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_insert + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Insert.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedInsert.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedInsert/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_join + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Join.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedJoin.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedJoin/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_select + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Select.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedSelect.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedSelect/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_stringpatternmatching + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/StringPatternMatching.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedStringPatternMatching.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedStringPatternMatching/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_tablegenerator + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/TableGenerator.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedTableGenerator.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedTableGenerator/") + add_test(quickstep_queryoptimizer_tests_distributed_executiongenerator_update + "../quickstep_queryoptimizer_tests_DistributedExecutionGeneratorTest" + "${CMAKE_CURRENT_SOURCE_DIR}/Update.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedUpdate.test" + "${CMAKE_CURRENT_BINARY_DIR}/DistributedUpdate/") +endif(ENABLE_DISTRIBUTED) add_test(quickstep_queryoptimizer_tests_executiongenerator_create "../quickstep_queryoptimizer_tests_ExecutionGeneratorTest" "${CMAKE_CURRENT_SOURCE_DIR}/Create.test" @@ -76,6 +133,19 @@ add_test(quickstep_queryoptimizer_tests_executiongenerator_update file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Create) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Delete) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Distinct) +if (ENABLE_DISTRIBUTED) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedCreate) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedDelete) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedDistinct) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedDrop) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedIndex) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedInsert) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedJoin) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedSelect) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedStringPatternMatching) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedTableGenerator) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DistributedUpdate) +endif(ENABLE_DISTRIBUTED) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Drop) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Index) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Insert)