OmniSciDB  d2f719934e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QueryRunner.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "QueryRunner.h"
18 
19 #include "Calcite/Calcite.h"
20 #include "Catalog/Catalog.h"
22 #include "DistributedLoader.h"
23 #include "Geospatial/Transforms.h"
25 #include "Logger/Logger.h"
26 #include "Parser/ParserWrapper.h"
27 #include "Parser/parser.h"
36 #include "Shared/StringTransform.h"
38 #include "Shared/import_helpers.h"
40 #include "gen-cpp/CalciteServer.h"
41 #include "include/bcrypt.h"
42 
43 #include <boost/filesystem/operations.hpp>
44 #include <csignal>
45 #include <random>
46 
47 #define CALCITEPORT 3279
48 
49 extern size_t g_leaf_count;
50 extern bool g_enable_filter_push_down;
51 
53 
54 extern bool g_serialize_temp_tables;
56 std::mutex calcite_lock;
57 
58 using namespace Catalog_Namespace;
59 namespace {
60 
61 std::shared_ptr<Calcite> g_calcite = nullptr;
62 
63 void calcite_shutdown_handler() noexcept {
64  if (g_calcite) {
65  g_calcite->close_calcite_server();
66  g_calcite.reset();
67  }
68 }
69 
73 }
74 
75 } // namespace
76 
77 namespace QueryRunner {
78 
79 std::unique_ptr<QueryRunner> QueryRunner::qr_instance_ = nullptr;
80 
81 query_state::QueryStates QueryRunner::query_states_;
82 
83 QueryRunner* QueryRunner::init(const char* db_path,
84  const std::string& udf_filename,
85  const size_t max_gpu_mem,
86  const int reserved_gpu_mem) {
87  return QueryRunner::init(db_path,
88  std::string{OMNISCI_ROOT_USER},
89  "HyperInteractive",
90  std::string{OMNISCI_DEFAULT_DB},
91  {},
92  {},
93  udf_filename,
94  true,
95  max_gpu_mem,
96  reserved_gpu_mem);
97 }
98 
100  const char* db_path,
101  const std::vector<LeafHostInfo>& string_servers,
102  const std::vector<LeafHostInfo>& leaf_servers) {
103  return QueryRunner::init(db_path,
104  std::string{OMNISCI_ROOT_USER},
105  "HyperInteractive",
106  std::string{OMNISCI_DEFAULT_DB},
107  string_servers,
108  leaf_servers,
109  "",
110  true,
111  0,
112  256 << 20,
113  false,
114  false,
115  disk_cache_config);
116 }
117 
118 QueryRunner* QueryRunner::init(const char* db_path,
119  const std::string& user,
120  const std::string& pass,
121  const std::string& db_name,
122  const std::vector<LeafHostInfo>& string_servers,
123  const std::vector<LeafHostInfo>& leaf_servers,
124  const std::string& udf_filename,
125  bool uses_gpus,
126  const size_t max_gpu_mem,
127  const int reserved_gpu_mem,
128  const bool create_user,
129  const bool create_db,
130  const File_Namespace::DiskCacheConfig* disk_cache_config) {
131  // Whitelist root path for tests by default
133  ddl_utils::FilePathWhitelist::initialize(db_path, "[\"/\"]", "[\"/\"]");
134  LOG_IF(FATAL, !leaf_servers.empty()) << "Distributed test runner not supported.";
135  CHECK(leaf_servers.empty());
136  qr_instance_.reset(new QueryRunner(db_path,
137  user,
138  pass,
139  db_name,
140  string_servers,
141  leaf_servers,
142  udf_filename,
143  uses_gpus,
144  max_gpu_mem,
145  reserved_gpu_mem,
146  create_user,
147  create_db,
148  disk_cache_config));
149  return qr_instance_.get();
150 }
151 
152 QueryRunner::QueryRunner(const char* db_path,
153  const std::string& user_name,
154  const std::string& passwd,
155  const std::string& db_name,
156  const std::vector<LeafHostInfo>& string_servers,
157  const std::vector<LeafHostInfo>& leaf_servers,
158  const std::string& udf_filename,
159  bool uses_gpus,
160  const size_t max_gpu_mem,
161  const int reserved_gpu_mem,
162  const bool create_user,
163  const bool create_db,
164  const File_Namespace::DiskCacheConfig* cache_config)
165  : dispatch_queue_(std::make_unique<QueryDispatchQueue>(1)) {
167  boost::filesystem::path base_path{db_path};
168  CHECK(boost::filesystem::exists(base_path));
169  auto system_db_file = base_path / "mapd_catalogs" / OMNISCI_DEFAULT_DB;
170  CHECK(boost::filesystem::exists(system_db_file));
171  auto data_dir = base_path / "mapd_data";
172  File_Namespace::DiskCacheConfig disk_cache_config{
173  (base_path / "omnisci_disk_cache").string(), File_Namespace::DiskCacheLevel::fsi};
174  if (cache_config) {
175  disk_cache_config = *cache_config;
176  }
178 
181  g_calcite =
182  std::make_shared<Calcite>(-1, CALCITEPORT, db_path, 1024, 5000, true, udf_filename);
183  ExtensionFunctionsWhitelist::add(g_calcite->getExtensionFunctionWhitelist());
184  if (!udf_filename.empty()) {
185  ExtensionFunctionsWhitelist::addUdfs(g_calcite->getUserDefinedFunctionWhitelist());
186  }
187 
189  auto udtfs = ThriftSerializers::to_thrift(
191  std::vector<TUserDefinedFunction> udfs = {};
192  g_calcite->setRuntimeExtensionFunctions(udfs, udtfs, /*is_runtime=*/false);
193 
194  std::unique_ptr<CudaMgr_Namespace::CudaMgr> cuda_mgr;
195 #ifdef HAVE_CUDA
196  if (uses_gpus) {
197  cuda_mgr = std::make_unique<CudaMgr_Namespace::CudaMgr>(-1, 0);
198  }
199 #else
200  uses_gpus = false;
201 #endif
202  SystemParameters mapd_params;
203  mapd_params.gpu_buffer_mem_bytes = max_gpu_mem;
204  mapd_params.aggregator = !leaf_servers.empty();
205 
206  data_mgr_.reset(new Data_Namespace::DataMgr(data_dir.string(),
207  mapd_params,
208  std::move(cuda_mgr),
209  uses_gpus,
210  reserved_gpu_mem,
211  0,
212  disk_cache_config));
213 
214  auto& sys_cat = Catalog_Namespace::SysCatalog::instance();
215 
216  g_base_path = base_path.string();
217  sys_cat.init(g_base_path,
218  data_mgr_,
219  {},
220  g_calcite,
221  false,
222  mapd_params.aggregator,
223  string_servers);
224 
225  if (create_user) {
226  if (!sys_cat.getMetadataForUser(user_name, user)) {
227  sys_cat.createUser(user_name, passwd, false, "", true, g_read_only);
228  }
229  }
230  CHECK(sys_cat.getMetadataForUser(user_name, user));
231  CHECK(bcrypt_checkpw(passwd.c_str(), user.passwd_hash.c_str()) == 0);
232 
233  if (create_db) {
234  if (!sys_cat.getMetadataForDB(db_name, db_metadata_)) {
235  sys_cat.createDatabase(db_name, user.userId);
236  }
237  }
238  CHECK(sys_cat.getMetadataForDB(db_name, db_metadata_));
239  CHECK(user.isSuper || (user.userId == db_metadata_.dbOwner));
240  auto cat = sys_cat.getCatalog(db_metadata_, create_db);
241  CHECK(cat);
242  session_info_ = std::make_unique<Catalog_Namespace::SessionInfo>(
243  cat, user, ExecutorDeviceType::GPU, "");
244 }
245 
246 void QueryRunner::resizeDispatchQueue(const size_t num_executors) {
247  dispatch_queue_ = std::make_unique<QueryDispatchQueue>(num_executors);
248 }
249 
250 QueryRunner::QueryRunner(std::unique_ptr<Catalog_Namespace::SessionInfo> session)
251  : session_info_(std::move(session))
252  , dispatch_queue_(std::make_unique<QueryDispatchQueue>(1)) {}
253 
254 std::shared_ptr<Catalog_Namespace::Catalog> QueryRunner::getCatalog() const {
256  return session_info_->get_catalog_ptr();
257 }
258 
259 std::shared_ptr<Calcite> QueryRunner::getCalcite() const {
260  // TODO: Embed Calcite shared_ptr ownership in QueryRunner
261  return g_calcite;
262 }
263 
264 bool QueryRunner::gpusPresent() const {
266  return session_info_->getCatalog().getDataMgr().gpusPresent();
267 }
268 
269 void QueryRunner::clearGpuMemory() const {
272 }
273 
274 void QueryRunner::clearCpuMemory() const {
277 }
278 
279 std::vector<MemoryInfo> QueryRunner::getMemoryInfo(
280  const Data_Namespace::MemoryLevel memory_level) const {
282  return session_info_->getCatalog().getDataMgr().getMemoryInfo(memory_level);
283 }
284 
285 BufferPoolStats QueryRunner::getBufferPoolStats(
286  const Data_Namespace::MemoryLevel memory_level,
287  const bool current_db_only) const {
288  // Only works single-node for now
290  const std::vector<MemoryInfo> memory_infos =
291  session_info_->getCatalog().getDataMgr().getMemoryInfo(memory_level);
292  if (memory_level == Data_Namespace::MemoryLevel::CPU_LEVEL) {
293  CHECK_EQ(memory_infos.size(), static_cast<size_t>(1));
294  }
295  std::set<std::vector<int32_t>> chunk_keys;
296  std::set<std::vector<int32_t>> table_keys;
297  std::set<std::vector<int32_t>> column_keys;
298  std::set<std::vector<int32_t>> fragment_keys;
299  size_t total_num_buffers{
300  0}; // can be greater than chunk keys set size due to table replication
301  size_t total_num_bytes{0};
302  for (auto& pool_memory_info : memory_infos) {
303  const std::vector<MemoryData>& memory_data = pool_memory_info.nodeMemoryData;
304  for (auto& memory_datum : memory_data) {
305  total_num_buffers++;
306  const auto& chunk_key = memory_datum.chunk_key;
307  if (memory_datum.memStatus == Buffer_Namespace::MemStatus::FREE ||
308  chunk_key.size() < 4) {
309  continue;
310  }
311  if (current_db_only) {
312  if (chunk_key[0] != db_metadata_.dbId) {
313  continue;
314  }
315  }
316  total_num_bytes += (memory_datum.numPages * pool_memory_info.pageSize);
317  table_keys.insert({chunk_key[0], chunk_key[1]});
318  column_keys.insert({chunk_key[0], chunk_key[1], chunk_key[2]});
319  fragment_keys.insert({chunk_key[0], chunk_key[1], chunk_key[3]});
320  chunk_keys.insert(chunk_key);
321  }
322  }
323  return {total_num_buffers,
324  total_num_bytes,
325  table_keys.size(),
326  column_keys.size(),
327  fragment_keys.size(),
328  chunk_keys.size()};
329 }
330 
331 RegisteredQueryHint QueryRunner::getParsedQueryHint(const std::string& query_str) {
334  auto query_state = create_query_state(session_info_, query_str);
335  const auto& cat = session_info_->getCatalog();
337  auto calcite_mgr = cat.getCalciteMgr();
338  const auto query_ra = calcite_mgr
339  ->process(query_state->createQueryStateProxy(),
340  pg_shim(query_str),
341  {},
342  true,
343  false,
344  false,
345  true)
346  .plan_result;
347  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra, query_state);
348  auto query_hints =
349  ra_executor.getParsedQueryHint(ra_executor.getRootRelAlgNodeShPtr().get());
350  return query_hints ? *query_hints : RegisteredQueryHint::defaults();
351 }
352 
354  std::unordered_map<size_t, std::unordered_map<unsigned, RegisteredQueryHint>>>
355 QueryRunner::getParsedQueryHints(const std::string& query_str) {
358  auto query_state = create_query_state(session_info_, query_str);
359  const auto& cat = session_info_->getCatalog();
361  auto calcite_mgr = cat.getCalciteMgr();
362  const auto query_ra = calcite_mgr
363  ->process(query_state->createQueryStateProxy(),
364  pg_shim(query_str),
365  {},
366  true,
367  false,
368  false,
369  true)
370  .plan_result;
371  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra, query_state);
372  return ra_executor.getParsedQueryHints();
373 }
374 
375 std::optional<RegisteredQueryHint> QueryRunner::getParsedGlobalQueryHints(
376  const std::string& query_str) {
379  auto query_state = create_query_state(session_info_, query_str);
380  const auto& cat = session_info_->getCatalog();
382  auto calcite_mgr = cat.getCalciteMgr();
383  const auto query_ra = calcite_mgr
384  ->process(query_state->createQueryStateProxy(),
385  pg_shim(query_str),
386  {},
387  true,
388  false,
389  false,
390  true)
391  .plan_result;
392  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra, query_state);
393  return ra_executor.getGlobalQueryHint();
394 }
395 
396 // used to validate calcite ddl statements
397 void QueryRunner::validateDDLStatement(const std::string& stmt_str_in) {
399 
400  std::string stmt_str = stmt_str_in;
401  // First remove special chars
402  boost::algorithm::trim_left_if(stmt_str, boost::algorithm::is_any_of("\n"));
403  // Then remove spaces
404  boost::algorithm::trim_left(stmt_str);
405 
406  auto query_state = create_query_state(session_info_, stmt_str);
407  auto stdlog = STDLOG(query_state);
408 
409  const auto& cat = session_info_->getCatalog();
410  auto calcite_mgr = cat.getCalciteMgr();
411  calcite_mgr->process(query_state->createQueryStateProxy(),
412  pg_shim(stmt_str),
413  {},
414  true,
415  false,
416  false,
417  true);
418 }
419 
420 std::shared_ptr<RelAlgTranslator> QueryRunner::getRelAlgTranslator(
421  const std::string& query_str,
422  Executor* executor) {
425  auto query_state = create_query_state(session_info_, query_str);
426  const auto& cat = session_info_->getCatalog();
427  auto calcite_mgr = cat.getCalciteMgr();
428  const auto query_ra = calcite_mgr
429  ->process(query_state->createQueryStateProxy(),
430  pg_shim(query_str),
431  {},
432  true,
433  false,
434  false,
435  true)
436  .plan_result;
437  executor->setCatalog(&cat);
438  auto ra_executor = RelAlgExecutor(executor, cat, query_ra);
439  auto root_node_shared_ptr = ra_executor.getRootRelAlgNodeShPtr();
440  return ra_executor.getRelAlgTranslator(root_node_shared_ptr.get());
441 }
442 
443 QueryPlanDagInfo QueryRunner::getQueryInfoForDataRecyclerTest(
444  const std::string& query_str) {
447  auto query_state = create_query_state(session_info_, query_str);
448  const auto& cat = session_info_->getCatalog();
450  auto calcite_mgr = cat.getCalciteMgr();
451  const auto query_ra = calcite_mgr
452  ->process(query_state->createQueryStateProxy(),
453  pg_shim(query_str),
454  {},
455  true,
456  false,
457  false,
458  true)
459  .plan_result;
460  executor->setCatalog(&cat);
461  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra);
462  // note that we assume the test for data recycler that needs to have join_info
463  // does not contain any ORDER BY clause; this is necessary to create work_unit
464  // without actually performing the query
465  auto root_node_shared_ptr = ra_executor.getRootRelAlgNodeShPtr();
466  auto join_info = ra_executor.getJoinInfo(root_node_shared_ptr.get());
467  auto relAlgTranslator = ra_executor.getRelAlgTranslator(root_node_shared_ptr.get());
468  return {root_node_shared_ptr, join_info.first, join_info.second, relAlgTranslator};
469 }
470 
471 std::unique_ptr<Parser::DDLStmt> QueryRunner::createDDLStatement(
472  const std::string& stmt_str_in) {
475 
476  std::string stmt_str = stmt_str_in;
477  // First remove special chars
478  boost::algorithm::trim_left_if(stmt_str, boost::algorithm::is_any_of("\n"));
479  // Then remove spaces
480  boost::algorithm::trim_left(stmt_str);
481 
482  ParserWrapper pw{stmt_str};
483 
484  auto query_state = create_query_state(session_info_, stmt_str);
485  auto stdlog = STDLOG(query_state);
486 
487  if (pw.isCalciteDdl()) {
488  const auto& cat = session_info_->getCatalog();
489  auto calcite_mgr = cat.getCalciteMgr();
490  const auto query_json = calcite_mgr
491  ->process(query_state->createQueryStateProxy(),
492  pg_shim(stmt_str),
493  {},
494  true,
495  false,
496  false,
497  true)
498  .plan_result;
499  std::unique_ptr<Parser::DDLStmt> ptr = create_ddl_from_calcite(query_json);
500  return ptr;
501  }
502 
503  // simply fail here as non-Calcite parsing is about to be removed
504  UNREACHABLE();
505  return nullptr;
506 }
507 
508 void QueryRunner::runDDLStatement(const std::string& stmt_str_in) {
511 
512  std::string stmt_str = stmt_str_in;
513  // First remove special chars
514  boost::algorithm::trim_left_if(stmt_str, boost::algorithm::is_any_of("\n"));
515  // Then remove spaces
516  boost::algorithm::trim_left(stmt_str);
517 
518  ParserWrapper pw{stmt_str};
519 
520  auto query_state = create_query_state(session_info_, stmt_str);
521  auto stdlog = STDLOG(query_state);
522 
523  if (pw.isCalciteDdl()) {
524  const auto& cat = session_info_->getCatalog();
525  auto calcite_mgr = cat.getCalciteMgr();
526  const auto query_ra = calcite_mgr
527  ->process(query_state->createQueryStateProxy(),
528  pg_shim(stmt_str),
529  {},
530  true,
531  false,
532  false,
533  true)
534  .plan_result;
536  executor.execute();
537  return;
538  }
539 
540  SQLParser parser;
541  std::list<std::unique_ptr<Parser::Stmt>> parse_trees;
542  std::string last_parsed;
543  CHECK_EQ(parser.parse(stmt_str, parse_trees, last_parsed), 0) << stmt_str_in;
544  CHECK_EQ(parse_trees.size(), size_t(1));
545  auto stmt = parse_trees.front().get();
546  auto ddl = dynamic_cast<Parser::DDLStmt*>(stmt);
547  CHECK(ddl);
548  ddl->execute(*session_info_);
549 }
550 
551 std::shared_ptr<ResultSet> QueryRunner::runSQL(const std::string& query_str,
553  ExecutionOptions eo) {
556 
557  ParserWrapper pw{query_str};
558  if (pw.isCalcitePathPermissable()) {
559  const auto execution_result = runSelectQuery(query_str, std::move(co), std::move(eo));
560  VLOG(1) << session_info_->getCatalog().getDataMgr().getSystemMemoryUsage();
561  return execution_result->getRows();
562  }
563 
564  auto query_state = create_query_state(session_info_, query_str);
565  auto stdlog = STDLOG(query_state);
566 
567  SQLParser parser;
568  std::list<std::unique_ptr<Parser::Stmt>> parse_trees;
569  std::string last_parsed;
570  CHECK_EQ(parser.parse(query_str, parse_trees, last_parsed), 0) << query_str;
571  CHECK_EQ(parse_trees.size(), size_t(1));
572  auto stmt = parse_trees.front().get();
573  auto insert_values_stmt = dynamic_cast<Parser::InsertValuesStmt*>(stmt);
574  if (insert_values_stmt) {
575  insert_values_stmt->execute(*session_info_);
576  return nullptr;
577  }
578  auto ctas_stmt = dynamic_cast<Parser::CreateTableAsSelectStmt*>(stmt);
579  if (ctas_stmt) {
580  ctas_stmt->execute(*session_info_);
581  return nullptr;
582  }
583  auto itas_stmt = dynamic_cast<Parser::InsertIntoTableAsSelectStmt*>(stmt);
584  if (itas_stmt) {
585  itas_stmt->execute(*session_info_);
586  return nullptr;
587  }
588  UNREACHABLE();
589  return nullptr;
590 }
591 
592 std::shared_ptr<ResultSet> QueryRunner::runSQL(const std::string& query_str,
593  const ExecutorDeviceType device_type,
594  const bool hoist_literals,
595  const bool allow_loop_joins) {
596  auto co = CompilationOptions::defaults(device_type);
597  co.hoist_literals = hoist_literals;
598  return runSQL(
599  query_str, std::move(co), defaultExecutionOptionsForRunSQL(allow_loop_joins));
600 }
601 
602 ExecutionOptions QueryRunner::defaultExecutionOptionsForRunSQL(bool allow_loop_joins,
603  bool just_explain) {
604  return {g_enable_columnar_output,
605  true,
606  just_explain,
607  allow_loop_joins,
608  false,
609  false,
610  false,
611  false,
612  10000,
613  false,
614  false,
616  false,
617  1000};
618 }
619 
620 std::shared_ptr<Executor> QueryRunner::getExecutor() const {
623  auto query_state = create_query_state(session_info_, "");
624  auto stdlog = STDLOG(query_state);
626  return executor;
627 }
628 
629 std::shared_ptr<ResultSet> QueryRunner::runSQLWithAllowingInterrupt(
630  const std::string& query_str,
631  const std::string& session_id,
632  const ExecutorDeviceType device_type,
633  const double running_query_check_freq,
634  const unsigned pending_query_check_freq) {
637  auto current_user = session_info_->get_currentUser();
638  auto session_info = std::make_shared<Catalog_Namespace::SessionInfo>(
639  session_info_->get_catalog_ptr(), current_user, device_type, session_id);
640  auto query_state = create_query_state(session_info, query_str);
641  auto stdlog = STDLOG(query_state);
642  const auto& cat = query_state->getConstSessionInfo()->getCatalog();
643  std::string query_ra{""};
644 
645  std::shared_ptr<ExecutionResult> result;
646  auto query_launch_task = std::make_shared<QueryDispatchQueue::Task>(
647  [&cat,
648  &query_ra,
649  &device_type,
650  &query_state,
651  &result,
652  &running_query_check_freq,
653  &pending_query_check_freq](const size_t worker_id) {
654  auto executor = Executor::getExecutor(worker_id);
656 
658  true,
659  false,
660  true,
661  false,
662  false,
663  false,
664  false,
665  10000,
666  false,
667  false,
669  true,
670  running_query_check_freq,
671  pending_query_check_freq};
672  {
673  // async query initiation for interrupt test
674  // incurs data race warning in TSAN since
675  // calcite_mgr is shared across multiple query threads
676  // so here we lock the manager during query parsing
677  std::lock_guard<std::mutex> calcite_lock_guard(calcite_lock);
678  auto calcite_mgr = cat.getCalciteMgr();
679  query_ra = calcite_mgr
680  ->process(query_state->createQueryStateProxy(),
681  pg_shim(query_state->getQueryStr()),
682  {},
683  true,
684  false,
685  false,
686  true)
687  .plan_result;
688  }
689  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra, query_state);
690  result = std::make_shared<ExecutionResult>(
691  ra_executor.executeRelAlgQuery(co, eo, false, nullptr));
692  });
694  executor->enrollQuerySession(session_id,
695  query_str,
696  query_state->getQuerySubmittedTime(),
698  QuerySessionStatus::QueryStatus::PENDING_QUEUE);
700  dispatch_queue_->submit(query_launch_task, /*is_update_delete=*/false);
701  auto result_future = query_launch_task->get_future();
702  result_future.get();
703  CHECK(result);
704  return result->getRows();
705 }
706 
707 std::vector<std::shared_ptr<ResultSet>> QueryRunner::runMultipleStatements(
708  const std::string& sql,
709  const ExecutorDeviceType dt) {
710  std::vector<std::shared_ptr<ResultSet>> results;
711  // TODO: Need to properly handle escaped semicolons instead of doing a naive split().
712  auto fields = split(sql, ";");
713  for (const auto& field : fields) {
714  auto text = strip(field) + ";";
715  if (text == ";") {
716  continue;
717  }
718 
719  ParserWrapper pw{text};
720  if (pw.isCalciteDdl()) {
721  runDDLStatement(text);
722  results.push_back(nullptr);
723  } else {
724  // TODO: Maybe remove this redundant parsing after enhancing Parser::Stmt?
725  SQLParser parser;
726  std::list<std::unique_ptr<Parser::Stmt>> parse_trees;
727  std::string last_parsed;
728  CHECK_EQ(parser.parse(text, parse_trees, last_parsed), 0);
729  CHECK_EQ(parse_trees.size(), size_t(1));
730  auto stmt = parse_trees.front().get();
731  Parser::DDLStmt* ddl = dynamic_cast<Parser::DDLStmt*>(stmt);
732  Parser::DMLStmt* dml = dynamic_cast<Parser::DMLStmt*>(stmt);
733  if (ddl != nullptr && dml == nullptr) {
734  runDDLStatement(text);
735  results.push_back(nullptr);
736  } else if (ddl == nullptr && dml != nullptr) {
737  results.push_back(runSQL(text, dt, true, true));
738  } else {
739  throw std::runtime_error("Unexpected SQL statement type: " + text);
740  }
741  }
742  }
743  return results;
744 }
745 
746 void QueryRunner::runImport(Parser::CopyTableStmt* import_stmt) {
747  CHECK(import_stmt);
748  import_stmt->execute(*session_info_);
749 }
750 
751 std::unique_ptr<import_export::Loader> QueryRunner::getLoader(
752  const TableDescriptor* td) const {
753  auto cat = getCatalog();
754  return std::make_unique<import_export::Loader>(*cat, td);
755 }
756 
757 namespace {
758 
759 std::shared_ptr<ExecutionResult> run_select_query_with_filter_push_down(
760  QueryStateProxy query_state_proxy,
761  const ExecutorDeviceType device_type,
762  const bool hoist_literals,
763  const bool allow_loop_joins,
764  const bool just_explain,
765  const ExecutorExplainType explain_type,
766  const bool with_filter_push_down) {
767  auto const& query_state = query_state_proxy.getQueryState();
768  const auto& cat = query_state.getConstSessionInfo()->getCatalog();
771  co.explain_type = explain_type;
772 
775  eo.just_explain = just_explain;
776  eo.allow_loop_joins = allow_loop_joins;
777  eo.find_push_down_candidates = with_filter_push_down;
779 
780  auto calcite_mgr = cat.getCalciteMgr();
781  const auto query_ra = calcite_mgr
782  ->process(query_state_proxy,
783  pg_shim(query_state.getQueryStr()),
784  {},
785  true,
786  false,
787  false,
788  true)
789  .plan_result;
790  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra);
791  auto result = std::make_shared<ExecutionResult>(
792  ra_executor.executeRelAlgQuery(co, eo, false, nullptr));
793  const auto& filter_push_down_requests = result->getPushedDownFilterInfo();
794  if (!filter_push_down_requests.empty()) {
795  std::vector<TFilterPushDownInfo> filter_push_down_info;
796  for (const auto& req : filter_push_down_requests) {
797  TFilterPushDownInfo filter_push_down_info_for_request;
798  filter_push_down_info_for_request.input_prev = req.input_prev;
799  filter_push_down_info_for_request.input_start = req.input_start;
800  filter_push_down_info_for_request.input_next = req.input_next;
801  filter_push_down_info.push_back(filter_push_down_info_for_request);
802  }
803  const auto new_query_ra = calcite_mgr
804  ->process(query_state_proxy,
805  pg_shim(query_state.getQueryStr()),
806  filter_push_down_info,
807  true,
808  false,
809  false,
810  true)
811  .plan_result;
812  const ExecutionOptions eo_modified{eo.output_columnar_hint,
813  eo.allow_multifrag,
814  eo.just_explain,
815  eo.allow_loop_joins,
816  eo.with_watchdog,
817  eo.jit_debug,
818  eo.just_validate,
821  /*find_push_down_candidates=*/false,
822  /*just_calcite_explain=*/false,
827  auto new_ra_executor = RelAlgExecutor(executor.get(), cat, new_query_ra);
828  return std::make_shared<ExecutionResult>(
829  new_ra_executor.executeRelAlgQuery(co, eo_modified, false, nullptr));
830  } else {
831  return result;
832  }
833 }
834 
835 } // namespace
836 
837 std::shared_ptr<ExecutionResult> QueryRunner::runSelectQuery(const std::string& query_str,
839  ExecutionOptions eo) {
842  auto query_state = create_query_state(session_info_, query_str);
843  auto stdlog = STDLOG(query_state);
845  return run_select_query_with_filter_push_down(query_state->createQueryStateProxy(),
846  co.device_type,
847  co.hoist_literals,
848  eo.allow_loop_joins,
849  eo.just_explain,
852  }
853 
854  const auto& cat = session_info_->getCatalog();
855 
856  std::shared_ptr<ExecutionResult> result;
857  auto query_launch_task =
858  std::make_shared<QueryDispatchQueue::Task>([&cat,
859  &query_str,
860  &co,
861  explain_type = this->explain_type_,
862  &eo,
863  &query_state,
864  &result](const size_t worker_id) {
865  auto executor = Executor::getExecutor(worker_id);
866  // TODO The next line should be deleted since it overwrites co, but then
867  // NycTaxiTest.RunSelectsEncodingDictWhereGreater fails due to co not getting
868  // reset to its default values.
869  co = CompilationOptions::defaults(co.device_type);
870  co.explain_type = explain_type;
871  auto calcite_mgr = cat.getCalciteMgr();
872  const auto query_ra = calcite_mgr
873  ->process(query_state->createQueryStateProxy(),
874  pg_shim(query_str),
875  {},
876  true,
877  false,
879  true)
880  .plan_result;
881  auto ra_executor = RelAlgExecutor(executor.get(), cat, query_ra);
882  result = std::make_shared<ExecutionResult>(
883  ra_executor.executeRelAlgQuery(co, eo, false, nullptr));
884  });
886  dispatch_queue_->submit(query_launch_task, /*is_update_delete=*/false);
887  auto result_future = query_launch_task->get_future();
888  result_future.get();
889  CHECK(result);
890  return result;
891 }
892 
893 std::shared_ptr<ExecutionResult> QueryRunner::runSelectQuery(
894  const std::string& query_str,
895  const ExecutorDeviceType device_type,
896  const bool hoist_literals,
897  const bool allow_loop_joins,
898  const bool just_explain) {
899  auto co = CompilationOptions::defaults(device_type);
900  co.hoist_literals = hoist_literals;
901  return runSelectQuery(query_str,
902  std::move(co),
903  defaultExecutionOptionsForRunSQL(allow_loop_joins, just_explain));
904 }
905 
906 ExtractedPlanDag QueryRunner::extractQueryPlanDag(const std::string& query_str) {
907  auto query_dag_info = getQueryInfoForDataRecyclerTest(query_str);
909  auto extracted_dag_info =
910  QueryPlanDagExtractor::extractQueryPlanDag(query_dag_info.root_node.get(),
911  *getCatalog(),
912  std::nullopt,
913  query_dag_info.left_deep_trees_info,
914  *executor->getTemporaryTables(),
915  executor,
916  *query_dag_info.rel_alg_translator);
917  return extracted_dag_info;
918 }
919 
920 const int32_t* QueryRunner::getCachedPerfectHashTable(QueryPlan plan_dag) {
921  auto hash_table_cache = PerfectJoinHashTable::getHashTableCache();
922  CHECK(hash_table_cache);
923  auto cache_key = boost::hash_value(plan_dag);
924  auto hash_table = hash_table_cache->getItemFromCache(
926  CHECK(hash_table);
927  return reinterpret_cast<int32_t*>(hash_table->getCpuBuffer());
928 }
929 
930 const int8_t* QueryRunner::getCachedBaselineHashTable(QueryPlan plan_dag) {
931  auto hash_table_cache = BaselineJoinHashTable::getHashTableCache();
932  CHECK(hash_table_cache);
933  auto cache_key = boost::hash_value(plan_dag);
934  auto hash_table = hash_table_cache->getItemFromCache(
936  CHECK(hash_table);
937  return hash_table->getCpuBuffer();
938 }
939 
940 size_t QueryRunner::getEntryCntCachedBaselineHashTable(QueryPlan plan_dag) {
941  auto hash_table_cache = BaselineJoinHashTable::getHashTableCache();
942  CHECK(hash_table_cache);
943  auto cache_key = boost::hash_value(plan_dag);
944  auto hash_table = hash_table_cache->getItemFromCache(
946  CHECK(hash_table);
947  return hash_table->getEntryCount();
948 }
949 
950 // this function exists to test data recycler
951 // specifically, it is tricky to get a hashtable cache key when we only know
952 // a target query sql in test code
953 // so this function utilizes an incorrect way to manipulate our hashtable recycler
954 // but provides the cached hashtable for performing the test
955 // a set "visited" contains cached hashtable keys that we have retrieved so far
956 // based on that, this function iterates hashtable cache and return a cached one
957 // when its hashtable cache key has not been visited yet
958 // for instance, if we call this funtion with an empty "visited" key, we return
959 // the first hashtable that its iterator visits
960 std::tuple<QueryPlanHash,
961  std::shared_ptr<HashTable>,
962  std::optional<HashtableCacheMetaInfo>>
963 QueryRunner::getCachedHashtableWithoutCacheKey(std::set<size_t>& visited,
964  CacheItemType hash_table_type,
965  DeviceIdentifier device_identifier) {
966  HashtableRecycler* hash_table_cache{nullptr};
967  switch (hash_table_type) {
969  hash_table_cache = PerfectJoinHashTable::getHashTableCache();
970  break;
971  }
973  hash_table_cache = BaselineJoinHashTable::getHashTableCache();
974  break;
975  }
977  hash_table_cache = OverlapsJoinHashTable::getHashTableCache();
978  break;
979  }
980  default: {
981  UNREACHABLE();
982  break;
983  }
984  }
985  CHECK(hash_table_cache);
986  return hash_table_cache->getCachedHashtableWithoutCacheKey(
987  visited, hash_table_type, device_identifier);
988 }
989 
990 std::shared_ptr<CacheItemMetric> QueryRunner::getCacheItemMetric(
991  QueryPlanHash cache_key,
992  CacheItemType hash_table_type,
993  DeviceIdentifier device_identifier) {
994  HashtableRecycler* hash_table_cache{nullptr};
995  switch (hash_table_type) {
997  hash_table_cache = PerfectJoinHashTable::getHashTableCache();
998  break;
999  }
1001  hash_table_cache = BaselineJoinHashTable::getHashTableCache();
1002  break;
1003  }
1005  hash_table_cache = OverlapsJoinHashTable::getHashTableCache();
1006  break;
1007  }
1008  default: {
1009  UNREACHABLE();
1010  break;
1011  }
1012  }
1013  CHECK(hash_table_cache);
1014  return hash_table_cache->getCachedItemMetric(
1015  hash_table_type, device_identifier, cache_key);
1016 }
1017 
1018 size_t QueryRunner::getNumberOfCachedPerfectHashTables() {
1019  auto hash_table_cache = PerfectJoinHashTable::getHashTableCache();
1020  CHECK(hash_table_cache);
1021  return hash_table_cache->getCurrentNumCachedItems(
1023 };
1024 
1025 size_t QueryRunner::getNumberOfCachedBaselineJoinHashTables() {
1026  auto hash_table_cache = BaselineJoinHashTable::getHashTableCache();
1027  CHECK(hash_table_cache);
1028  return hash_table_cache->getCurrentNumCachedItems(
1030 }
1031 
1032 size_t QueryRunner::getNumberOfCachedOverlapsHashTables() {
1033  auto hash_table_cache = OverlapsJoinHashTable::getHashTableCache();
1034  CHECK(hash_table_cache);
1035  return hash_table_cache->getCurrentNumCachedItems(
1037 }
1038 
1039 size_t QueryRunner::getNumberOfCachedOverlapsHashTableTuringParams() {
1040  auto hash_table_cache = OverlapsJoinHashTable::getOverlapsTuningParamCache();
1041  CHECK(hash_table_cache);
1042  return hash_table_cache->getCurrentNumCachedItems(
1044 }
1045 
1046 size_t QueryRunner::getNumberOfCachedOverlapsHashTablesAndTuningParams() {
1049 }
1050 
1051 void QueryRunner::reset() {
1052  qr_instance_.reset(nullptr);
1054 }
1055 
1056 ImportDriver::ImportDriver(std::shared_ptr<Catalog_Namespace::Catalog> cat,
1057  const Catalog_Namespace::UserMetadata& user,
1058  const ExecutorDeviceType dt,
1059  const std::string session_id)
1060  : QueryRunner(
1061  std::make_unique<Catalog_Namespace::SessionInfo>(cat, user, dt, session_id)) {}
1062 
1063 void ImportDriver::importGeoTable(const std::string& file_path,
1064  const std::string& table_name,
1065  const bool compression,
1066  const bool create_table,
1067  const bool explode_collections) {
1068  using namespace import_export;
1069 
1070  static constexpr bool kIsGeoRaster{false};
1071 
1073  const std::string geo_column_name(OMNISCI_GEO_PREFIX);
1074 
1075  CopyParams copy_params;
1077  if (compression) {
1078  copy_params.geo_coords_encoding = EncodingType::kENCODING_GEOINT;
1079  copy_params.geo_coords_comp_param = 32;
1080  } else {
1081  copy_params.geo_coords_encoding = EncodingType::kENCODING_NONE;
1082  copy_params.geo_coords_comp_param = 0;
1083  }
1084  copy_params.geo_assign_render_groups = true;
1085  copy_params.geo_explode_collections = explode_collections;
1086 
1087  std::map<std::string, std::string> colname_to_src;
1088  auto& cat = session_info_->getCatalog();
1089  auto cds = Importer::gdalToColumnDescriptors(
1090  file_path, kIsGeoRaster, geo_column_name, copy_params);
1091 
1092  for (auto& cd : cds) {
1093  const auto col_name_sanitized = ImportHelpers::sanitize_name(cd.columnName);
1094  const auto ret =
1095  colname_to_src.insert(std::make_pair(col_name_sanitized, cd.columnName));
1096  CHECK(ret.second);
1097  cd.columnName = col_name_sanitized;
1098  }
1099 
1100  if (create_table) {
1101  const auto td = cat.getMetadataForTable(table_name);
1102  if (td != nullptr) {
1103  throw std::runtime_error("Error: Table " + table_name +
1104  " already exists. Possible failure to correctly re-create "
1105  "mapd_data directory.");
1106  }
1107  if (table_name != ImportHelpers::sanitize_name(table_name)) {
1108  throw std::runtime_error("Invalid characters in table name: " + table_name);
1109  }
1110 
1111  std::string stmt{"CREATE TABLE " + table_name};
1112  std::vector<std::string> col_stmts;
1113 
1114  for (auto& cd : cds) {
1115  if (cd.columnType.get_type() == SQLTypes::kINTERVAL_DAY_TIME ||
1116  cd.columnType.get_type() == SQLTypes::kINTERVAL_YEAR_MONTH) {
1117  throw std::runtime_error(
1118  "Unsupported type: INTERVAL_DAY_TIME or INTERVAL_YEAR_MONTH for col " +
1119  cd.columnName + " (table: " + table_name + ")");
1120  }
1121 
1122  if (cd.columnType.get_type() == SQLTypes::kDECIMAL) {
1123  if (cd.columnType.get_precision() == 0 && cd.columnType.get_scale() == 0) {
1124  cd.columnType.set_precision(14);
1125  cd.columnType.set_scale(7);
1126  }
1127  }
1128 
1129  std::string col_stmt;
1130  col_stmt.append(cd.columnName + " " + cd.columnType.get_type_name() + " ");
1131 
1132  if (cd.columnType.get_compression() != EncodingType::kENCODING_NONE) {
1133  col_stmt.append("ENCODING " + cd.columnType.get_compression_name() + " ");
1134  } else {
1135  if (cd.columnType.is_string()) {
1136  col_stmt.append("ENCODING NONE");
1137  } else if (cd.columnType.is_geometry()) {
1138  if (cd.columnType.get_output_srid() == 4326) {
1139  col_stmt.append("ENCODING NONE");
1140  }
1141  }
1142  }
1143  col_stmts.push_back(col_stmt);
1144  }
1145 
1146  stmt.append(" (" + boost::algorithm::join(col_stmts, ",") + ");");
1147  runDDLStatement(stmt);
1148 
1149  LOG(INFO) << "Created table: " << table_name;
1150  } else {
1151  LOG(INFO) << "Not creating table: " << table_name;
1152  }
1153 
1154  const auto td = cat.getMetadataForTable(table_name);
1155  if (td == nullptr) {
1156  throw std::runtime_error("Error: Failed to create table " + table_name);
1157  }
1158 
1159  import_export::Importer importer(cat, td, file_path, copy_params);
1160  auto ms = measure<>::execution(
1161  [&]() { importer.importGDAL(colname_to_src, session_info_.get(), kIsGeoRaster); });
1162  LOG(INFO) << "Import Time for " << table_name << ": " << (double)ms / 1000.0 << " s";
1163 }
1164 
1165 } // namespace QueryRunner
bool g_enable_calcite_view_optimize
Definition: QueryRunner.cpp:55
Classes used to wrap parser calls for calcite redirection.
std::unique_ptr< Parser::DDLStmt > create_ddl_from_calcite(const std::string &query_json)
static void addUdfs(const std::string &json_func_sigs)
#define CHECK_EQ(x, y)
Definition: Logger.h:219
ImportStatus importGDAL(const std::map< std::string, std::string > &colname_to_src, const Catalog_Namespace::SessionInfo *session_info, const bool is_raster)
Definition: Importer.cpp:5155
#define CALCITEPORT
Definition: QueryRunner.cpp:47
size_t DeviceIdentifier
Definition: DataRecycler.h:111
std::string cat(Ts &&...args)
std::unique_ptr< QueryDispatchQueue > dispatch_queue_
Definition: QueryRunner.h:281
static TimeT::rep execution(F func, Args &&...args)
Definition: sample.cpp:29
ExecutorDeviceType
static void initialize(const std::string &data_dir, const std::string &allowed_import_paths, const std::string &allowed_export_paths)
Definition: DdlUtils.cpp:826
std::string strip(std::string_view str)
trim any whitespace from the left and right ends of a string
static ExtractedPlanDag extractQueryPlanDag(const RelAlgNode *node, const Catalog_Namespace::Catalog &catalog, std::optional< unsigned > left_deep_tree_id, std::unordered_map< unsigned, JoinQualsPerNestingLevel > &left_deep_tree_infos, const TemporaryTables &temporary_tables, Executor *executor, const RelAlgTranslator &rel_alg_translator)
ImportDriver(std::shared_ptr< Catalog_Namespace::Catalog > cat, const Catalog_Namespace::UserMetadata &user, const ExecutorDeviceType dt=ExecutorDeviceType::GPU, const std::string session_id="")
#define LOG(tag)
Definition: Logger.h:205
size_t getNumberOfCachedOverlapsHashTables()
ExecutorExplainType explain_type_
Definition: QueryRunner.h:277
std::string join(T const &container, std::string const &delim)
static void add(const std::string &json_func_sigs)
#define UNREACHABLE()
Definition: Logger.h:255
static HashtableRecycler * getHashTableCache()
std::mutex calcite_lock
Definition: QueryRunner.cpp:56
std::optional< std::unordered_map< size_t, std::unordered_map< unsigned, RegisteredQueryHint > > > getParsedQueryHints()
std::optional< RegisteredQueryHint > getParsedQueryHint(const RelAlgNode *node)
void set_once_fatal_func(FatalFunc fatal_func)
Definition: Logger.cpp:333
void execute(const Catalog_Namespace::SessionInfo &session) override
Catalog_Namespace::DBMetadata db_metadata_
Definition: QueryRunner.h:279
static ExecutionOptions defaultExecutionOptionsForRunSQL(bool allow_loop_joins=true, bool just_explain=false)
virtual std::shared_ptr< ResultSet > runSQL(const std::string &query_str, CompilationOptions co, ExecutionOptions eo)
std::vector< std::string > split(std::string_view str, std::string_view delim, std::optional< size_t > maxsplit)
split apart a string into a vector of substrings
double running_query_interrupt_freq
#define LOG_IF(severity, condition)
Definition: Logger.h:301
static void clearMemory(const Data_Namespace::MemoryLevel memory_level)
Definition: Execute.cpp:202
static void addShutdownCallback(std::function< void()> shutdown_callback)
std::shared_ptr< const RelAlgNode > getRootRelAlgNodeShPtr() const
static std::shared_ptr< Executor > getExecutor(const ExecutorId id, const std::string &debug_dir="", const std::string &debug_file="", const SystemParameters &system_parameters=SystemParameters())
Definition: Execute.cpp:177
This file contains the class specification and related data structures for Catalog.
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
bool g_enable_columnar_output
Definition: Execute.cpp:95
static SysCatalog & instance()
Definition: SysCatalog.h:326
CacheItemType
Definition: DataRecycler.h:36
std::string g_base_path
Definition: SysCatalog.cpp:63
void init(LogOptions const &log_opts)
Definition: Logger.cpp:305
QueryState & getQueryState()
Definition: QueryState.h:181
const std::string OMNISCI_DEFAULT_DB
Definition: SysCatalog.h:59
static HashtableRecycler * getHashTableCache()
ExecutorExplainType explain_type
void execute(const Catalog_Namespace::SessionInfo &session) override
virtual void runDDLStatement(const std::string &)
static std::unique_ptr< QueryRunner > qr_instance_
Definition: QueryRunner.h:275
double g_gpu_mem_limit_percent
Definition: QueryRunner.cpp:52
std::string sanitize_name(const std::string &name)
import_export::SourceType source_type
Definition: CopyParams.h:56
void execute(const Catalog_Namespace::SessionInfo &session) override
static OverlapsTuningParamRecycler * getOverlapsTuningParamCache()
unsigned pending_query_interrupt_freq
bool g_serialize_temp_tables
Definition: Catalog.cpp:101
const std::string OMNISCI_GEO_PREFIX
Definition: Transforms.h:22
ExecutorDeviceType device_type
std::optional< RegisteredQueryHint > getGlobalQueryHint()
ExecutionResult execute()
void importGeoTable(const std::string &file_path, const std::string &table_name, const bool compression, const bool create_table, const bool explode_collections)
static RegisteredQueryHint defaults()
Definition: QueryHint.h:222
TExtArgumentType::type to_thrift(const ExtArgumentType &t)
std::shared_ptr< ExecutionResult > run_select_query_with_filter_push_down(QueryStateProxy query_state_proxy, const ExecutorDeviceType device_type, const bool hoist_literals, const bool allow_loop_joins, const bool just_explain, const ExecutorExplainType explain_type, const bool with_filter_push_down)
const std::string OMNISCI_ROOT_USER
Definition: SysCatalog.h:60
bool g_read_only
Definition: File.cpp:40
std::shared_ptr< Catalog_Namespace::SessionInfo > session_info_
Definition: QueryRunner.h:280
size_t QueryPlanHash
virtual std::shared_ptr< ExecutionResult > runSelectQuery(const std::string &query_str, CompilationOptions co, ExecutionOptions eo)
std::shared_ptr< Calcite > g_calcite
Definition: QueryRunner.cpp:61
static std::shared_ptr< query_state::QueryState > create_query_state(Ts &&...args)
Definition: QueryRunner.h:253
static CompilationOptions defaults(const ExecutorDeviceType device_type=ExecutorDeviceType::GPU)
bool g_enable_filter_push_down
Definition: Execute.cpp:91
QueryPlanDagInfo getQueryInfoForDataRecyclerTest(const std::string &)
#define CHECK(condition)
Definition: Logger.h:211
size_t getNumberOfCachedOverlapsHashTableTuringParams()
static HashtableRecycler * getHashTableCache()
double gpu_input_mem_limit_percent
static std::vector< TableFunction > get_table_funcs(const std::string &name, const bool is_gpu)
Serializers for query engine types to/from thrift.
std::shared_ptr< Catalog_Namespace::Catalog > getCatalog() const
unsigned dynamic_watchdog_time_limit
void execute(const Catalog_Namespace::SessionInfo &session)
std::shared_ptr< Data_Namespace::DataMgr > data_mgr_
Definition: QueryRunner.h:282
size_t g_leaf_count
Definition: ParserNode.cpp:78
static constexpr DeviceIdentifier CPU_DEVICE_IDENTIFIER
Definition: DataRecycler.h:132
static ExecutionOptions defaults()
ExecutorExplainType
std::string QueryPlan
std::string pg_shim(const std::string &query)
#define STDLOG(...)
Definition: QueryState.h:235
#define VLOG(n)
Definition: Logger.h:305
std::atomic< bool > isSuper
Definition: SysCatalog.h:120
static const ExecutorId UNITARY_EXECUTOR_ID
Definition: Execute.h:376