예제 #1
0
 void _pmdEDUCB::resetDisconnect ()
 {
    resetInterrupt () ;
    _ctrlFlag &= ~EDU_CTRL_DISCONNECTED ;
 }
예제 #2
0
std::shared_ptr<ResultSet> Executor::execute(const Planner::RootPlan* root_plan,
                                             const Catalog_Namespace::SessionInfo& session,
                                             const bool hoist_literals,
                                             const ExecutorDeviceType device_type,
                                             const ExecutorOptLevel opt_level,
                                             const bool allow_multifrag,
                                             const bool allow_loop_joins,
                                             RenderInfo* render_info) {
  catalog_ = &root_plan->get_catalog();
  const auto stmt_type = root_plan->get_stmt_type();
  // capture the lock acquistion time
  auto clock_begin = timer_start();
  std::lock_guard<std::mutex> lock(execute_mutex_);
  if (g_enable_dynamic_watchdog) {
    resetInterrupt();
  }
  ScopeGuard restore_metainfo_cache = [this] { clearMetaInfoCache(); };
  int64_t queue_time_ms = timer_stop(clock_begin);
  ScopeGuard row_set_holder = [this] { row_set_mem_owner_ = nullptr; };
  switch (stmt_type) {
    case kSELECT: {
      int32_t error_code{0};
      size_t max_groups_buffer_entry_guess{16384};

      std::unique_ptr<RenderInfo> render_info_ptr;
      if (root_plan->get_plan_dest() == Planner::RootPlan::kRENDER) {
        if (device_type != ExecutorDeviceType::GPU) {
          throw std::runtime_error("Backend rendering is only supported on GPU");
        }

        if (!render_manager_) {
          throw std::runtime_error("This build doesn't support backend rendering");
        }

        CHECK(render_info);

        if (!render_info->render_allocator_map_ptr) {
          // make backwards compatible, can be removed when MapDHandler::render(...)
          // in MapDServer.cpp is removed
          render_info->render_allocator_map_ptr.reset(
              new RenderAllocatorMap(catalog_->get_dataMgr().cudaMgr_, render_manager_, blockSize(), gridSize()));
        }
      }
      auto rows = executeSelectPlan(
          root_plan->get_plan(),
          root_plan->get_limit(),
          root_plan->get_offset(),
          hoist_literals,
          device_type,
          opt_level,
          root_plan->get_catalog(),
          max_groups_buffer_entry_guess,
          &error_code,
          nullptr,
          allow_multifrag,
          root_plan->get_plan_dest() == Planner::RootPlan::kEXPLAIN,
          allow_loop_joins,
          render_info && render_info->do_render ? render_info->render_allocator_map_ptr.get() : nullptr);
      if (error_code == ERR_OVERFLOW_OR_UNDERFLOW) {
        throw std::runtime_error("Overflow or underflow");
      }
      if (error_code == ERR_DIV_BY_ZERO) {
        throw std::runtime_error("Division by zero");
      }
      if (error_code == ERR_UNSUPPORTED_SELF_JOIN) {
        throw std::runtime_error("Self joins not supported yet");
      }
      if (error_code == ERR_OUT_OF_TIME) {
        if (!interrupted_)
          throw std::runtime_error("Query execution has exceeded the time limit");
        error_code = ERR_INTERRUPTED;
      }
      if (error_code == ERR_INTERRUPTED) {
        throw std::runtime_error("Query execution has been interrupted");
      }
      if (error_code == ERR_OUT_OF_CPU_MEM) {
        throw std::runtime_error("Not enough host memory to execute the query");
      }
      if (error_code == ERR_OUT_OF_GPU_MEM) {
        rows = executeSelectPlan(root_plan->get_plan(),
                                 root_plan->get_limit(),
                                 root_plan->get_offset(),
                                 hoist_literals,
                                 device_type,
                                 opt_level,
                                 root_plan->get_catalog(),
                                 max_groups_buffer_entry_guess,
                                 &error_code,
                                 nullptr,
                                 false,
                                 false,
                                 allow_loop_joins,
                                 nullptr);
      }
      if (error_code) {
        max_groups_buffer_entry_guess = 0;
        while (true) {
          rows = executeSelectPlan(root_plan->get_plan(),
                                   root_plan->get_limit(),
                                   root_plan->get_offset(),
                                   hoist_literals,
                                   ExecutorDeviceType::CPU,
                                   opt_level,
                                   root_plan->get_catalog(),
                                   max_groups_buffer_entry_guess,
                                   &error_code,
                                   nullptr,
                                   false,
                                   false,
                                   allow_loop_joins,
                                   nullptr);
          CHECK(rows);
          if (!error_code) {
            rows->setQueueTime(queue_time_ms);
            return rows;
          }
          // Even the conservative guess failed; it should only happen when we group
          // by a huge cardinality array. Maybe we should throw an exception instead?
          // Such a heavy query is entirely capable of exhausting all the host memory.
          CHECK(max_groups_buffer_entry_guess);
          max_groups_buffer_entry_guess *= 2;
        }
      }
      CHECK(rows);
      rows->setQueueTime(queue_time_ms);
      return rows;
    }
    case kINSERT: {
      if (root_plan->get_plan_dest() == Planner::RootPlan::kEXPLAIN) {
        auto explanation_rs = std::make_shared<ResultSet>("No explanation available.");
        explanation_rs->setQueueTime(queue_time_ms);
        return explanation_rs;
      }
      Catalog_Namespace::Catalog& cat = session.get_catalog();
      Catalog_Namespace::SysCatalog& sys_cat = static_cast<Catalog_Namespace::SysCatalog&>(cat);
      auto user_metadata = session.get_currentUser();
      const int table_id = root_plan->get_result_table_id();
      auto td = cat.getMetadataForTable(table_id);
      DBObject dbObject(td->tableName, TableDBObjectType);
      std::vector<bool> privs{false, true, false, false};  // INSERT
      sys_cat.populateDBObjectKey(dbObject, cat);
      dbObject.setPrivileges(privs);
      std::vector<DBObject> privObjects;
      privObjects.push_back(dbObject);
      if (cat.isAccessPrivCheckEnabled() && !sys_cat.checkPrivileges(user_metadata, privObjects)) {
        throw std::runtime_error("Violation of access privileges: user " + user_metadata.userName +
                                 " has no insert privileges for table " + td->tableName + ".");
        break;
      }
      executeSimpleInsert(root_plan);
      auto empty_rs = std::make_shared<ResultSet>(
          std::vector<TargetInfo>{}, ExecutorDeviceType::CPU, QueryMemoryDescriptor{}, nullptr, this);
      empty_rs->setQueueTime(queue_time_ms);
      return empty_rs;
    }
    default:
      CHECK(false);
  }
  CHECK(false);
  return nullptr;
}