bool C4Network2Players::JoinLocalPlayer(const char *szLocalPlayerFilename, bool initial)
{
	// ignore in replay
	// shouldn't even come here though
	assert(!Game.C4S.Head.Replay);
	if (Game.C4S.Head.Replay) return false;
	// if observing: don't try
	if (Game.Clients.getLocal()->isObserver()) return false;
	// network only
	assert(::Network.isEnabled());
	// create join info packet
	C4ClientPlayerInfos JoinInfo(szLocalPlayerFilename, !initial);
	// league game: get authentication for players
	if (Game.Parameters.isLeague())
		for (int i = 0; i < JoinInfo.GetPlayerCount(); i++)
		{
			C4PlayerInfo *pInfo = JoinInfo.GetPlayerInfo(i);
			if (!::Network.LeaguePlrAuth(pInfo))
			{
				JoinInfo.RemoveIndexedInfo(i);
				i--;
			}
		}
	// host or client?
	if (::Network.isHost())
	{
		// error joining players? Zero players is OK for initial packet; marks host as observer
		if (!initial && !JoinInfo.GetPlayerCount()) return false;
		// handle it as a direct request
		HandlePlayerInfoUpdRequest(&JoinInfo, true);
	}
	else
	{
		// clients request initial joins at host only
		// create player info for local player joins
		C4PacketPlayerInfoUpdRequest JoinRequest(JoinInfo);
		// any players to join? Zero players is OK for initial packet; marks client as observer
		// it's also necessary to send the empty player info packet, so the host will answer
		// with infos of all other clients
		if (!initial && !JoinRequest.Info.GetPlayerCount()) return false;
		::Network.Clients.SendMsgToHost(MkC4NetIOPacket(PID_PlayerInfoUpdReq, JoinRequest));
		// request activation
		if (JoinRequest.Info.GetPlayerCount() && !Game.Clients.getLocal()->isActivated())
			::Network.RequestActivate();
	}
	// done, success
	return true;
}
Exemple #2
0
RowSetPtr Executor::executeResultPlan(const Planner::Result* result_plan,
                                      const bool hoist_literals,
                                      const ExecutorDeviceType device_type,
                                      const ExecutorOptLevel opt_level,
                                      const Catalog_Namespace::Catalog& cat,
                                      size_t& max_groups_buffer_entry_guess,
                                      int32_t* error_code,
                                      const Planner::Sort* sort_plan,
                                      const bool allow_multifrag,
                                      const bool just_explain,
                                      const bool allow_loop_joins) {
  const auto agg_plan = dynamic_cast<const Planner::AggPlan*>(result_plan->get_child_plan());
  if (!agg_plan) {  // TODO(alex)
    throw std::runtime_error("Query not supported yet, child plan needs to be an aggregate plan.");
  }
  row_set_mem_owner_ = std::make_shared<RowSetMemoryOwner>();
  lit_str_dict_proxy_ = nullptr;
  const auto scan_plan = dynamic_cast<const Planner::Scan*>(agg_plan->get_child_plan());
  auto simple_quals = scan_plan ? scan_plan->get_simple_quals() : std::list<std::shared_ptr<Analyzer::Expr>>{};
  auto quals = scan_plan ? scan_plan->get_quals() : std::list<std::shared_ptr<Analyzer::Expr>>{};
  std::vector<InputDescriptor> input_descs;
  std::list<std::shared_ptr<const InputColDescriptor>> input_col_descs;
  collect_input_descs(input_descs, input_col_descs, agg_plan, cat);
  const auto join_plan = get_join_child(agg_plan);
  if (join_plan) {
    collect_quals_from_join(simple_quals, quals, join_plan);
  }
  const auto join_quals = join_plan ? join_plan->get_quals() : std::list<std::shared_ptr<Analyzer::Expr>>{};
  CHECK(check_plan_sanity(agg_plan));
  const auto query_infos = get_table_infos(input_descs, this);
  const auto ra_exe_unit_in = RelAlgExecutionUnit{input_descs,
                                                  {},
                                                  input_col_descs,
                                                  simple_quals,
                                                  quals,
                                                  JoinType::INVALID,
                                                  {},
                                                  join_quals,
                                                  {},
                                                  agg_plan->get_groupby_list(),
                                                  get_agg_target_exprs(agg_plan),
                                                  {},
                                                  nullptr,
                                                  {{}, SortAlgorithm::Default, 0, 0},
                                                  0};
  QueryRewriter query_rewriter(ra_exe_unit_in, query_infos, this, result_plan);
  const auto ra_exe_unit = query_rewriter.rewrite();
  auto result = executeWorkUnit(error_code,
                                max_groups_buffer_entry_guess,
                                true,
                                query_infos,
                                ra_exe_unit,
                                {device_type, hoist_literals, opt_level, g_enable_dynamic_watchdog},
                                {false,
                                 allow_multifrag,
                                 just_explain,
                                 allow_loop_joins,
                                 g_enable_watchdog,
                                 false,
                                 false,
                                 g_enable_dynamic_watchdog,
                                 g_dynamic_watchdog_time_limit},
                                cat,
                                row_set_mem_owner_,
                                nullptr,
                                true);
  auto& rows = boost::get<RowSetPtr>(result);
  CHECK(rows);
  if (just_explain) {
    return std::move(rows);
  }

  const int in_col_count{static_cast<int>(agg_plan->get_targetlist().size())};
  std::list<std::shared_ptr<const InputColDescriptor>> pseudo_input_col_descs;
  for (int pseudo_col = 1; pseudo_col <= in_col_count; ++pseudo_col) {
    pseudo_input_col_descs.push_back(std::make_shared<const InputColDescriptor>(pseudo_col, 0, -1));
  }
  const auto order_entries = sort_plan ? sort_plan->get_order_entries() : std::list<Analyzer::OrderEntry>{};
  const RelAlgExecutionUnit res_ra_unit{{},
                                        {},
                                        pseudo_input_col_descs,
                                        result_plan->get_constquals(),
                                        result_plan->get_quals(),
                                        JoinType::INVALID,
                                        {},
                                        {},
                                        {},
                                        {nullptr},
                                        get_agg_target_exprs(result_plan),
                                        {},
                                        nullptr,
                                        {
                                            order_entries, SortAlgorithm::Default, 0, 0,
                                        },
                                        0};
  if (*error_code) {
    return std::make_shared<ResultSet>(
        std::vector<TargetInfo>{}, ExecutorDeviceType::CPU, QueryMemoryDescriptor{}, nullptr, this);
  }
  const auto& targets = result_plan->get_targetlist();
  CHECK(!targets.empty());
  std::vector<AggInfo> agg_infos;
  for (size_t target_idx = 0; target_idx < targets.size(); ++target_idx) {
    const auto target_entry = targets[target_idx];
    const auto target_type = target_entry->get_expr()->get_type_info().get_type();
    agg_infos.emplace_back((target_type == kFLOAT || target_type == kDOUBLE) ? "agg_id_double" : "agg_id",
                           target_entry->get_expr(),
                           0,
                           target_idx);
  }
  std::vector<SQLTypeInfo> target_types;
  for (auto in_col : agg_plan->get_targetlist()) {
    target_types.push_back(in_col->get_expr()->get_type_info());
  }
  CHECK(rows);
  ColumnarResults result_columns(row_set_mem_owner_, *rows, in_col_count, target_types);
  std::vector<llvm::Value*> col_heads;
  // Nested query, let the compiler know
  ResetIsNested reset_is_nested(this);
  is_nested_ = true;
  std::vector<Analyzer::Expr*> target_exprs;
  for (auto target_entry : targets) {
    target_exprs.emplace_back(target_entry->get_expr());
  }
  const auto row_count = rows->rowCount();
  if (!row_count) {
    return std::make_shared<ResultSet>(
        std::vector<TargetInfo>{}, ExecutorDeviceType::CPU, QueryMemoryDescriptor{}, nullptr, this);
  }
  std::vector<ColWidths> agg_col_widths;
  for (auto wid : get_col_byte_widths(target_exprs, {})) {
    agg_col_widths.push_back(
        {wid, int8_t(compact_byte_width(wid, pick_target_compact_width(res_ra_unit, {}, get_min_byte_width())))});
  }
  QueryMemoryDescriptor query_mem_desc{this,
                                       allow_multifrag,
                                       GroupByColRangeType::Projection,
                                       false,
                                       false,
                                       -1,
                                       0,
                                       {sizeof(int64_t)},
#ifdef ENABLE_KEY_COMPACTION
                                       0,
#endif
                                       agg_col_widths,
                                       {},
                                       row_count,
                                       small_groups_buffer_entry_count_,
                                       0,
                                       0,
                                       0,
                                       false,
                                       GroupByMemSharing::Shared,
                                       CountDistinctDescriptors{},
                                       false,
                                       true,
                                       false,
                                       false,
                                       {},
                                       {},
                                       false};
  auto compilation_result =
      compileWorkUnit(false,
                      {},
                      res_ra_unit,
                      {ExecutorDeviceType::CPU, hoist_literals, opt_level, g_enable_dynamic_watchdog},
                      {false,
                       allow_multifrag,
                       just_explain,
                       allow_loop_joins,
                       g_enable_watchdog,
                       false,
                       false,
                       g_enable_dynamic_watchdog,
                       g_dynamic_watchdog_time_limit},
                      nullptr,
                      false,
                      row_set_mem_owner_,
                      row_count,
                      small_groups_buffer_entry_count_,
                      get_min_byte_width(),
                      JoinInfo(JoinImplType::Invalid, std::vector<std::shared_ptr<Analyzer::BinOper>>{}, {}, ""),
                      false);
  auto column_buffers = result_columns.getColumnBuffers();
  CHECK_EQ(column_buffers.size(), static_cast<size_t>(in_col_count));
  std::vector<int64_t> init_agg_vals(query_mem_desc.agg_col_widths.size());
  auto query_exe_context = query_mem_desc.getQueryExecutionContext(res_ra_unit,
                                                                   init_agg_vals,
                                                                   this,
                                                                   ExecutorDeviceType::CPU,
                                                                   0,
                                                                   {},
                                                                   {},
                                                                   {},
                                                                   row_set_mem_owner_,
                                                                   false,
                                                                   false,
                                                                   nullptr);
  const auto hoist_buf = serializeLiterals(compilation_result.literal_values, 0);
  *error_code = 0;
  std::vector<std::vector<const int8_t*>> multi_frag_col_buffers{column_buffers};
  query_exe_context->launchCpuCode(res_ra_unit,
                                   compilation_result.native_functions,
                                   hoist_literals,
                                   hoist_buf,
                                   multi_frag_col_buffers,
                                   {{static_cast<int64_t>(result_columns.size())}},
                                   {{0}},
                                   1u,
                                   0,
                                   init_agg_vals,
                                   error_code,
                                   1,
                                   {});
  CHECK_GE(*error_code, 0);
  return query_exe_context->groupBufferToResults(0, target_exprs, false);
}