| 859 | } |
| 860 | |
| 861 | bool QueryState::StartFInstances() { |
| 862 | VLOG(2) << "StartFInstances(): query_id=" << PrintId(query_id()) |
| 863 | << " #instances=" << fragment_info_.fragment_instance_ctxs.size(); |
| 864 | DCHECK_GT(refcnt_.Load(), 0); |
| 865 | DCHECK_GT(backend_resource_refcnt_.Load(), 0) << "Should have been taken in Init()"; |
| 866 | |
| 867 | DCHECK_GT(fragment_info_.fragments.size(), 0); |
| 868 | vector<unique_ptr<Thread>> codegen_threads; |
| 869 | int num_unstarted_instances = fragment_info_.fragment_instance_ctxs.size(); |
| 870 | |
| 871 | // set up desc tbl |
| 872 | DCHECK(query_ctx().__isset.desc_tbl_serialized); |
| 873 | Status start_finstances_status = |
| 874 | DescriptorTbl::Create(&obj_pool_, query_ctx().desc_tbl_serialized, &desc_tbl_); |
| 875 | if (UNLIKELY(!start_finstances_status.ok())) goto error; |
| 876 | VLOG(2) << "descriptor table for query=" << PrintId(query_id()) |
| 877 | << "\n" << desc_tbl_->DebugString(); |
| 878 | // IMPALA-13378: Verify that tuple ids in all PlanNode exist in the descriptor table. |
| 879 | for (TPlanFragment f : fragment_info_.fragments) { |
| 880 | for (TPlanNode node : f.plan.nodes) { |
| 881 | for (TTupleId tuple_id : node.row_tuples) { |
| 882 | if (UNLIKELY(desc_tbl_->GetTupleDescriptor(tuple_id) == nullptr)) { |
| 883 | string msg = Substitute( |
| 884 | "Tuple id $0 of PlanNode $1 not found in descriptor table", |
| 885 | tuple_id, node.node_id); |
| 886 | // It'd be helpful to also print 'fragment_info_' but it might lead to crash |
| 887 | // if it's corrupt. |
| 888 | LOG(ERROR) << msg << ": " << desc_tbl_->DebugString(); |
| 889 | start_finstances_status = Status(msg); |
| 890 | goto error; |
| 891 | } |
| 892 | } |
| 893 | } |
| 894 | } |
| 895 | |
| 896 | start_finstances_status = FragmentState::CreateFragmentStateMap( |
| 897 | fragment_info_, exec_rpc_params_, this, fragment_state_map_); |
| 898 | if (UNLIKELY(!start_finstances_status.ok())) goto error; |
| 899 | |
| 900 | fragment_events_start_time_ = MonotonicStopWatch::Now(); |
| 901 | for (auto& fragment : fragment_state_map_) { |
| 902 | FragmentState* fragment_state = fragment.second; |
| 903 | for (int i = 0; i < fragment_state->instance_ctxs().size(); ++i) { |
| 904 | const TPlanFragmentInstanceCtx* instance_ctx = fragment_state->instance_ctxs()[i]; |
| 905 | const PlanFragmentInstanceCtxPB* instance_ctx_pb = |
| 906 | fragment_state->instance_ctx_pbs()[i]; |
| 907 | DCHECK_EQ(instance_ctx->fragment_idx, instance_ctx_pb->fragment_idx()); |
| 908 | FragmentInstanceState* fis = obj_pool_.Add(new FragmentInstanceState( |
| 909 | this, fragment_state, *instance_ctx, *instance_ctx_pb)); |
| 910 | |
| 911 | // start new thread to execute instance |
| 912 | refcnt_.Add(1); // decremented in ExecFInstance() |
| 913 | AcquireBackendResourceRefcount(); // decremented in ExecFInstance() |
| 914 | |
| 915 | // Add the fragment instance ID to the 'fis_map_'. Has to happen before the thread |
| 916 | // is spawned or we may race with users of 'fis_map_'. |
| 917 | fis_map_.emplace(fis->instance_id(), fis); |
| 918 |
no test coverage detected