Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
exec-node.cc
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "exec/exec-node.h"
16 
17 #include <sstream>
18 #include <unistd.h> // for sleep()
19 
20 #include <thrift/protocol/TDebugProtocol.h>
21 
22 #include "codegen/codegen-anyval.h"
23 #include "codegen/llvm-codegen.h"
24 #include "common/object-pool.h"
25 #include "common/status.h"
26 #include "exprs/expr.h"
27 #include "exec/aggregation-node.h"
29 #include "exec/cross-join-node.h"
31 #include "exec/empty-set-node.h"
32 #include "exec/exchange-node.h"
33 #include "exec/hash-join-node.h"
34 #include "exec/hdfs-scan-node.h"
35 #include "exec/hbase-scan-node.h"
36 #include "exec/select-node.h"
39 #include "exec/sort-node.h"
40 #include "exec/topn-node.h"
41 #include "exec/union-node.h"
42 #include "runtime/descriptors.h"
43 #include "runtime/mem-tracker.h"
44 #include "runtime/mem-pool.h"
45 #include "runtime/row-batch.h"
46 #include "runtime/runtime-state.h"
47 #include "util/debug-util.h"
48 #include "util/runtime-profile.h"
49 
50 #include "common/names.h"
51 
52 using namespace llvm;
53 
54 // TODO: remove when we remove hash-join-node.cc and aggregation-node.cc
55 DEFINE_bool(enable_partitioned_hash_join, true, "Enable partitioned hash join");
56 DEFINE_bool(enable_partitioned_aggregation, true, "Enable partitioned hash agg");
57 
58 namespace impala {
59 
60 const string ExecNode::ROW_THROUGHPUT_COUNTER = "RowsReturnedRate";
61 
62 int ExecNode::GetNodeIdFromProfile(RuntimeProfile* p) {
63  return p->metadata();
64 }
65 
66 ExecNode::RowBatchQueue::RowBatchQueue(int max_batches) :
67  BlockingQueue<RowBatch*>(max_batches) {
68 }
69 
71  DCHECK(cleanup_queue_.empty());
72 }
73 
75  if (!BlockingPut(batch)) {
76  lock_guard<SpinLock> l(lock_);
77  cleanup_queue_.push_back(batch);
78  }
79 }
80 
82  RowBatch* result = NULL;
83  if (BlockingGet(&result)) return result;
84  return NULL;
85 }
86 
88  int num_io_buffers = 0;
89 
90  RowBatch* batch = NULL;
91  while ((batch = GetBatch()) != NULL) {
92  num_io_buffers += batch->num_io_buffers();
93  delete batch;
94  }
95 
96  lock_guard<SpinLock> l(lock_);
97  for (list<RowBatch*>::iterator it = cleanup_queue_.begin();
98  it != cleanup_queue_.end(); ++it) {
99  num_io_buffers += (*it)->num_io_buffers();
100  delete *it;
101  }
102  cleanup_queue_.clear();
103  return num_io_buffers;
104 }
105 
106 ExecNode::ExecNode(ObjectPool* pool, const TPlanNode& tnode, const DescriptorTbl& descs)
107  : id_(tnode.node_id),
108  type_(tnode.node_type),
109  pool_(pool),
110  row_descriptor_(descs, tnode.row_tuples, tnode.nullable_tuples),
111  debug_phase_(TExecNodePhase::INVALID),
112  debug_action_(TDebugAction::WAIT),
113  limit_(tnode.limit),
116  rows_returned_rate_(NULL),
117  is_closed_(false) {
118  InitRuntimeProfile(PrintPlanNodeType(tnode.node_type));
119 }
120 
122 }
123 
124 Status ExecNode::Init(const TPlanNode& tnode) {
126  Expr::CreateExprTrees(pool_, tnode.conjuncts, &conjunct_ctxs_));
127  return Status::OK;
128 }
129 
131  RETURN_IF_ERROR(ExecDebugAction(TExecNodePhase::PREPARE, state));
132  DCHECK(runtime_profile_.get() != NULL);
134  ADD_COUNTER(runtime_profile_, "RowsReturned", TUnit::UNIT);
135  mem_tracker_.reset(new MemTracker(
136  runtime_profile_.get(), -1, -1, runtime_profile_->name(),
137  state->instance_mem_tracker()));
138  expr_mem_tracker_.reset(new MemTracker(-1, -1, "Exprs", mem_tracker_.get(), false));
139 
141  ROW_THROUGHPUT_COUNTER, TUnit::UNIT_PER_SECOND,
142  bind<int64_t>(&RuntimeProfile::UnitsPerSecond, rows_returned_counter_,
143  runtime_profile()->total_time_counter()));
144 
147 
148  for (int i = 0; i < children_.size(); ++i) {
149  RETURN_IF_ERROR(children_[i]->Prepare(state));
150  }
151  return Status::OK;
152 }
153 
155  RETURN_IF_ERROR(ExecDebugAction(TExecNodePhase::OPEN, state));
156  return Expr::Open(conjunct_ctxs_, state);
157 }
158 
160  for (int i = 0; i < children_.size(); ++i) {
161  RETURN_IF_ERROR(children_[i]->Reset(state));
162  }
163  return Status::OK;
164 }
165 
167  if (is_closed_) return;
168  is_closed_ = true;
169 
170  if (rows_returned_counter_ != NULL) {
172  }
173  for (int i = 0; i < children_.size(); ++i) {
174  children_[i]->Close(state);
175  }
176  Expr::Close(conjunct_ctxs_, state);
177 
178  if (mem_tracker() != NULL) {
179  if (mem_tracker()->consumption() != 0) {
180  LOG(WARNING) << "Query " << state->query_id() << " leaked memory." << endl
181  << state->instance_mem_tracker()->LogUsage();
182  DCHECK_EQ(mem_tracker()->consumption(), 0)
183  << "Leaked memory." << endl << state->instance_mem_tracker()->LogUsage();
184  }
185  }
186 }
187 
188 void ExecNode::AddRuntimeExecOption(const string& str) {
189  lock_guard<mutex> l(exec_options_lock_);
190  if (runtime_exec_options_.empty()) {
191  runtime_exec_options_ = str;
192  } else {
193  runtime_exec_options_.append(", ");
194  runtime_exec_options_.append(str);
195  }
197 }
198 
200  const DescriptorTbl& descs, ExecNode** root) {
201  if (plan.nodes.size() == 0) {
202  *root = NULL;
203  return Status::OK;
204  }
205  int node_idx = 0;
206  Status status = CreateTreeHelper(pool, plan.nodes, descs, NULL, &node_idx, root);
207  if (status.ok() && node_idx + 1 != plan.nodes.size()) {
208  status = Status(
209  "Plan tree only partially reconstructed. Not all thrift nodes were used.");
210  }
211  if (!status.ok()) {
212  LOG(ERROR) << "Could not construct plan tree:\n"
213  << apache::thrift::ThriftDebugString(plan);
214  }
215  return status;
216 }
217 
219  ObjectPool* pool,
220  const vector<TPlanNode>& tnodes,
221  const DescriptorTbl& descs,
222  ExecNode* parent,
223  int* node_idx,
224  ExecNode** root) {
225  // propagate error case
226  if (*node_idx >= tnodes.size()) {
227  return Status("Failed to reconstruct plan tree from thrift.");
228  }
229  int num_children = tnodes[*node_idx].num_children;
230  ExecNode* node = NULL;
231  RETURN_IF_ERROR(CreateNode(pool, tnodes[*node_idx], descs, &node));
232  // assert(parent != NULL || (node_idx == 0 && root_expr != NULL));
233  if (parent != NULL) {
234  parent->children_.push_back(node);
235  } else {
236  *root = node;
237  }
238  for (int i = 0; i < num_children; ++i) {
239  ++*node_idx;
240  RETURN_IF_ERROR(CreateTreeHelper(pool, tnodes, descs, node, node_idx, NULL));
241  // we are expecting a child, but have used all nodes
242  // this means we have been given a bad tree and must fail
243  if (*node_idx >= tnodes.size()) {
244  return Status("Failed to reconstruct plan tree from thrift.");
245  }
246  }
247 
248  // build up tree of profiles; add children >0 first, so that when we print
249  // the profile, child 0 is printed last (makes the output more readable)
250  for (int i = 1; i < node->children_.size(); ++i) {
251  node->runtime_profile()->AddChild(node->children_[i]->runtime_profile());
252  }
253  if (!node->children_.empty()) {
254  node->runtime_profile()->AddChild(node->children_[0]->runtime_profile(), false);
255  }
256 
257  return Status::OK;
258 }
259 
260 Status ExecNode::CreateNode(ObjectPool* pool, const TPlanNode& tnode,
261  const DescriptorTbl& descs, ExecNode** node) {
262  stringstream error_msg;
263  switch (tnode.node_type) {
264  case TPlanNodeType::HDFS_SCAN_NODE:
265  *node = pool->Add(new HdfsScanNode(pool, tnode, descs));
266  break;
267  case TPlanNodeType::HBASE_SCAN_NODE:
268  *node = pool->Add(new HBaseScanNode(pool, tnode, descs));
269  break;
270  case TPlanNodeType::DATA_SOURCE_NODE:
271  *node = pool->Add(new DataSourceScanNode(pool, tnode, descs));
272  break;
273  case TPlanNodeType::AGGREGATION_NODE:
274  if (FLAGS_enable_partitioned_aggregation) {
275  *node = pool->Add(new PartitionedAggregationNode(pool, tnode, descs));
276  } else {
277  *node = pool->Add(new AggregationNode(pool, tnode, descs));
278  }
279  break;
280  case TPlanNodeType::HASH_JOIN_NODE:
281  // The (old) HashJoinNode does not support left-anti, right-semi, and right-anti
282  // joins.
283  if (tnode.hash_join_node.join_op == TJoinOp::LEFT_ANTI_JOIN ||
284  tnode.hash_join_node.join_op == TJoinOp::RIGHT_SEMI_JOIN ||
285  tnode.hash_join_node.join_op == TJoinOp::RIGHT_ANTI_JOIN ||
286  tnode.hash_join_node.join_op == TJoinOp::NULL_AWARE_LEFT_ANTI_JOIN ||
287  FLAGS_enable_partitioned_hash_join) {
288  *node = pool->Add(new PartitionedHashJoinNode(pool, tnode, descs));
289  } else {
290  *node = pool->Add(new HashJoinNode(pool, tnode, descs));
291  }
292  break;
293  case TPlanNodeType::CROSS_JOIN_NODE:
294  *node = pool->Add(new CrossJoinNode(pool, tnode, descs));
295  break;
296  case TPlanNodeType::EMPTY_SET_NODE:
297  *node = pool->Add(new EmptySetNode(pool, tnode, descs));
298  break;
299  case TPlanNodeType::EXCHANGE_NODE:
300  *node = pool->Add(new ExchangeNode(pool, tnode, descs));
301  break;
302  case TPlanNodeType::SELECT_NODE:
303  *node = pool->Add(new SelectNode(pool, tnode, descs));
304  break;
305  case TPlanNodeType::SORT_NODE:
306  if (tnode.sort_node.use_top_n) {
307  *node = pool->Add(new TopNNode(pool, tnode, descs));
308  } else {
309  *node = pool->Add(new SortNode(pool, tnode, descs));
310  }
311  break;
312  case TPlanNodeType::UNION_NODE:
313  *node = pool->Add(new UnionNode(pool, tnode, descs));
314  break;
315  case TPlanNodeType::ANALYTIC_EVAL_NODE:
316  *node = pool->Add(new AnalyticEvalNode(pool, tnode, descs));
317  break;
318  default:
319  map<int, const char*>::const_iterator i =
320  _TPlanNodeType_VALUES_TO_NAMES.find(tnode.node_type);
321  const char* str = "unknown node type";
322  if (i != _TPlanNodeType_VALUES_TO_NAMES.end()) {
323  str = i->second;
324  }
325  error_msg << str << " not implemented";
326  return Status(error_msg.str());
327  }
328  RETURN_IF_ERROR((*node)->Init(tnode));
329  return Status::OK;
330 }
331 
333  int node_id, TExecNodePhase::type phase, TDebugAction::type action,
334  ExecNode* root) {
335  if (root->id_ == node_id) {
336  root->debug_phase_ = phase;
337  root->debug_action_ = action;
338  return;
339  }
340  for (int i = 0; i < root->children_.size(); ++i) {
341  SetDebugOptions(node_id, phase, action, root->children_[i]);
342  }
343 }
344 
345 string ExecNode::DebugString() const {
346  stringstream out;
347  this->DebugString(0, &out);
348  return out.str();
349 }
350 
351 void ExecNode::DebugString(int indentation_level, stringstream* out) const {
352  *out << " conjuncts=" << Expr::DebugString(conjunct_ctxs_);
353  for (int i = 0; i < children_.size(); ++i) {
354  *out << "\n";
355  children_[i]->DebugString(indentation_level + 1, out);
356  }
357 }
358 
359 void ExecNode::CollectNodes(TPlanNodeType::type node_type, vector<ExecNode*>* nodes) {
360  if (type_ == node_type) nodes->push_back(this);
361  for (int i = 0; i < children_.size(); ++i) {
362  children_[i]->CollectNodes(node_type, nodes);
363  }
364 }
365 
366 void ExecNode::CollectScanNodes(vector<ExecNode*>* nodes) {
367  CollectNodes(TPlanNodeType::HDFS_SCAN_NODE, nodes);
368  CollectNodes(TPlanNodeType::HBASE_SCAN_NODE, nodes);
369 }
370 
371 void ExecNode::InitRuntimeProfile(const string& name) {
372  stringstream ss;
373  ss << name << " (id=" << id_ << ")";
374  runtime_profile_.reset(new RuntimeProfile(pool_, ss.str()));
375  runtime_profile_->set_metadata(id_);
376 }
377 
378 Status ExecNode::ExecDebugAction(TExecNodePhase::type phase, RuntimeState* state) {
379  DCHECK(phase != TExecNodePhase::INVALID);
380  if (debug_phase_ != phase) return Status::OK;
381  if (debug_action_ == TDebugAction::FAIL) {
382  return Status(TErrorCode::INTERNAL_ERROR, "Debug Action: FAIL");
383  }
384  if (debug_action_ == TDebugAction::WAIT) {
385  while (!state->is_cancelled()) {
386  sleep(1);
387  }
388  return Status::CANCELLED;
389  }
390  return Status::OK;
391 }
392 
393 bool ExecNode::EvalConjuncts(ExprContext* const* ctxs, int num_ctxs, TupleRow* row) {
394  for (int i = 0; i < num_ctxs; ++i) {
395  BooleanVal v = ctxs[i]->GetBooleanVal(row);
396  if (v.is_null || !v.val) return false;
397  }
398  return true;
399 }
400 
403  return state->CheckQueryState();
404 }
405 
406 void ExecNode::AddExprCtxsToFree(const vector<ExprContext*>& ctxs) {
407  for (int i = 0; i < ctxs.size(); ++i) AddExprCtxToFree(ctxs[i]);
408 }
409 
410 void ExecNode::AddExprCtxsToFree(const SortExecExprs& sort_exec_exprs) {
411  AddExprCtxsToFree(sort_exec_exprs.sort_tuple_slot_expr_ctxs());
412  AddExprCtxsToFree(sort_exec_exprs.lhs_ordering_expr_ctxs());
413  AddExprCtxsToFree(sort_exec_exprs.rhs_ordering_expr_ctxs());
414 }
415 
416 // Codegen for EvalConjuncts. The generated signature is
417 // For a node with two conjunct predicates
418 // define i1 @EvalConjuncts(%"class.impala::ExprContext"** %ctxs, i32 %num_ctxs,
419 // %"class.impala::TupleRow"* %row) #20 {
420 // entry:
421 // %ctx_ptr = getelementptr %"class.impala::ExprContext"** %ctxs, i32 0
422 // %ctx = load %"class.impala::ExprContext"** %ctx_ptr
423 // %result = call i16 @Eq_StringVal_StringValWrapper3(
424 // %"class.impala::ExprContext"* %ctx, %"class.impala::TupleRow"* %row)
425 // %is_null = trunc i16 %result to i1
426 // %0 = ashr i16 %result, 8
427 // %1 = trunc i16 %0 to i8
428 // %val = trunc i8 %1 to i1
429 // %is_false = xor i1 %val, true
430 // %return_false = or i1 %is_null, %is_false
431 // br i1 %return_false, label %false, label %continue
432 //
433 // continue: ; preds = %entry
434 // %ctx_ptr2 = getelementptr %"class.impala::ExprContext"** %ctxs, i32 1
435 // %ctx3 = load %"class.impala::ExprContext"** %ctx_ptr2
436 // %result4 = call i16 @Gt_BigIntVal_BigIntValWrapper5(
437 // %"class.impala::ExprContext"* %ctx3, %"class.impala::TupleRow"* %row)
438 // %is_null5 = trunc i16 %result4 to i1
439 // %2 = ashr i16 %result4, 8
440 // %3 = trunc i16 %2 to i8
441 // %val6 = trunc i8 %3 to i1
442 // %is_false7 = xor i1 %val6, true
443 // %return_false8 = or i1 %is_null5, %is_false7
444 // br i1 %return_false8, label %false, label %continue1
445 //
446 // continue1: ; preds = %continue
447 // ret i1 true
448 //
449 // false: ; preds = %continue, %entry
450 // ret i1 false
451 // }
453  RuntimeState* state, const vector<ExprContext*>& conjunct_ctxs, const char* name) {
454  Function* conjunct_fns[conjunct_ctxs.size()];
455  for (int i = 0; i < conjunct_ctxs.size(); ++i) {
456  Status status =
457  conjunct_ctxs[i]->root()->GetCodegendComputeFn(state, &conjunct_fns[i]);
458  if (!status.ok()) {
459  VLOG_QUERY << "Could not codegen EvalConjuncts: " << status.GetDetail();
460  return NULL;
461  }
462  }
463  LlvmCodeGen* codegen;
464  if (!state->GetCodegen(&codegen).ok()) return NULL;
465 
466  // Construct function signature to match
467  // bool EvalConjuncts(Expr** exprs, int num_exprs, TupleRow* row)
468  Type* tuple_row_type = codegen->GetType(TupleRow::LLVM_CLASS_NAME);
469  Type* expr_ctx_type = codegen->GetType(ExprContext::LLVM_CLASS_NAME);
470 
471  DCHECK(tuple_row_type != NULL);
472  DCHECK(expr_ctx_type != NULL);
473 
474  PointerType* tuple_row_ptr_type = PointerType::get(tuple_row_type, 0);
475  PointerType* expr_ctx_ptr_type = PointerType::get(expr_ctx_type, 0);
476 
477  LlvmCodeGen::FnPrototype prototype(codegen, name, codegen->GetType(TYPE_BOOLEAN));
478  prototype.AddArgument(
479  LlvmCodeGen::NamedVariable("ctxs", PointerType::get(expr_ctx_ptr_type, 0)));
480  prototype.AddArgument(
481  LlvmCodeGen::NamedVariable("num_ctxs", codegen->GetType(TYPE_INT)));
482  prototype.AddArgument(LlvmCodeGen::NamedVariable("row", tuple_row_ptr_type));
483 
484  LlvmCodeGen::LlvmBuilder builder(codegen->context());
485  Value* args[3];
486  Function* fn = prototype.GeneratePrototype(&builder, args);
487  Value* ctxs_arg = args[0];
488  Value* tuple_row_arg = args[2];
489 
490  if (conjunct_ctxs.size() > 0) {
491  LLVMContext& context = codegen->context();
492  BasicBlock* false_block = BasicBlock::Create(context, "false", fn);
493 
494  for (int i = 0; i < conjunct_ctxs.size(); ++i) {
495  BasicBlock* true_block = BasicBlock::Create(context, "continue", fn, false_block);
496 
497  Value* ctx_arg_ptr = builder.CreateConstGEP1_32(ctxs_arg, i, "ctx_ptr");
498  Value* ctx_arg = builder.CreateLoad(ctx_arg_ptr, "ctx");
499  Value* expr_args[] = { ctx_arg, tuple_row_arg };
500 
501  // Call conjunct_fns[i]
503  codegen, &builder, conjunct_ctxs[i]->root()->type(), conjunct_fns[i], expr_args,
504  "result");
505 
506  // Return false if result.is_null || !result
507  Value* is_null = result.GetIsNull();
508  Value* is_false = builder.CreateNot(result.GetVal(), "is_false");
509  Value* return_false = builder.CreateOr(is_null, is_false, "return_false");
510  builder.CreateCondBr(return_false, false_block, true_block);
511 
512  // Set insertion point for continue/end
513  builder.SetInsertPoint(true_block);
514  }
515  builder.CreateRet(codegen->true_value());
516 
517  builder.SetInsertPoint(false_block);
518  builder.CreateRet(codegen->false_value());
519  } else {
520  builder.CreateRet(codegen->true_value());
521  }
522 
523  return codegen->FinalizeFunction(fn);
524 }
525 
526 }
DerivedCounter * AddDerivedCounter(const std::string &name, TUnit::type unit, const DerivedCounterFunction &counter_fn, const std::string &parent_counter_name="")
void AddRuntimeExecOption(const std::string &option)
Appends option to 'runtime_exec_options_'.
Definition: exec-node.cc:188
void CollectNodes(TPlanNodeType::type node_type, std::vector< ExecNode * > *nodes)
Definition: exec-node.cc:359
void CollectScanNodes(std::vector< ExecNode * > *nodes)
Collect all scan node types.
Definition: exec-node.cc:366
const std::string GetDetail() const
Definition: status.cc:184
static CodegenAnyVal CreateCallWrapped(LlvmCodeGen *cg, LlvmCodeGen::LlvmBuilder *builder, const ColumnType &type, llvm::Function *fn, llvm::ArrayRef< llvm::Value * > args, const char *name="", llvm::Value *result_ptr=NULL)
Same as above but wraps the result in a CodegenAnyVal.
BooleanVal GetBooleanVal(TupleRow *row)
Calls Get*Val on root_.
const TUniqueId & query_id() const
void AddInfoString(const std::string &key, const std::string &value)
int64_t num_rows_returned_
Definition: exec-node.h:223
std::vector< ExprContext * > expr_ctxs_to_free_
Expr contexts whose local allocations are safe to free in the main execution thread.
Definition: exec-node.h:286
MemTracker * mem_tracker()
Definition: exec-node.h:162
Utility struct that wraps a variable name and llvm type.
Definition: llvm-codegen.h:149
boost::scoped_ptr< RuntimeProfile > runtime_profile_
Definition: exec-node.h:225
static Status Open(const std::vector< ExprContext * > &ctxs, RuntimeState *state)
Convenience function for opening multiple expr trees.
int num_io_buffers() const
Definition: row-batch.h:149
boost::scoped_ptr< MemTracker > expr_mem_tracker_
MemTracker that should be used for ExprContexts.
Definition: exec-node.h:233
#define RETURN_IF_ERROR(stmt)
some generally useful macros
Definition: status.h:242
void InitRuntimeProfile(const std::string &name)
Definition: exec-node.cc:371
boost::mutex lock_
protects all fields below
Definition: coordinator.h:233
virtual Status Init(const TPlanNode &tnode)
Definition: exec-node.cc:124
RowDescriptor row_descriptor_
Definition: exec-node.h:215
static Status CreateTree(ObjectPool *pool, const TPlan &plan, const DescriptorTbl &descs, ExecNode **root)
Definition: exec-node.cc:199
static int64_t UnitsPerSecond(const Counter *total_counter, const Counter *timer)
Derived counter function: return measured throughput as input_value/second.
const RowDescriptor & row_desc() const
Definition: exec-node.h:156
Status ExecDebugAction(TExecNodePhase::type phase, RuntimeState *state)
Definition: exec-node.cc:378
void AddExprCtxToFree(ExprContext *ctx)
Definition: exec-node.h:276
int64_t limit_
Definition: exec-node.h:222
static void Close(const std::vector< ExprContext * > &ctxs, RuntimeState *state)
Convenience function for closing multiple expr trees.
boost::mutex exec_options_lock_
Definition: exec-node.h:238
TPlanNodeType::type type() const
Definition: exec-node.h:155
bool is_null
Definition: udf.h:359
LLVM code generator. This is the top level object to generate jitted code.
Definition: llvm-codegen.h:107
ExecNode(ObjectPool *pool, const TPlanNode &tnode, const DescriptorTbl &descs)
Init conjuncts.
Definition: exec-node.cc:106
std::string DebugString() const
Returns a string representation in DFS order of the plan rooted at this.
Definition: exec-node.cc:345
MemTracker * expr_mem_tracker()
Definition: exec-node.h:163
static const char * LLVM_CLASS_NAME
Definition: tuple-row.h:76
#define VLOG_QUERY
Definition: logging.h:57
static const char * LLVM_CLASS_NAME
Definition: expr-context.h:126
virtual ~ExecNode()
Definition: exec-node.cc:121
void AddArgument(const NamedVariable &var)
Add argument.
Definition: llvm-codegen.h:171
static llvm::Function * CodegenEvalConjuncts(RuntimeState *state, const std::vector< ExprContext * > &conjunct_ctxs, const char *name="EvalConjuncts")
Definition: exec-node.cc:452
TExecNodePhase::type debug_phase_
Definition: exec-node.h:219
ObjectPool pool
virtual Status Prepare(RuntimeState *state)
Definition: exec-node.cc:130
static Status CreateNode(ObjectPool *pool, const TPlanNode &tnode, const DescriptorTbl &descs, ExecNode **node)
Create a single exec node derived from thrift node; place exec node in 'pool'.
Definition: exec-node.cc:260
#define ADD_COUNTER(profile, name, unit)
DEFINE_bool(enable_partitioned_hash_join, true,"Enable partitioned hash join")
const std::vector< ExprContext * > & lhs_ordering_expr_ctxs() const
Can only be used after calling Prepare()
void AddExprCtxsToFree(const std::vector< ExprContext * > &ctxs)
virtual Status QueryMaintenance(RuntimeState *state)
Definition: exec-node.cc:401
TDebugAction::type debug_action_
Definition: exec-node.h:220
static const std::string ROW_THROUGHPUT_COUNTER
Names of counters shared by all exec nodes.
Definition: exec-node.h:169
static Status CreateTreeHelper(ObjectPool *pool, const std::vector< TPlanNode > &tnodes, const DescriptorTbl &descs, ExecNode *parent, int *node_idx, ExecNode **root)
Definition: exec-node.cc:218
This class is thread-safe.
Definition: mem-tracker.h:61
std::vector< ExecNode * > children_
Definition: exec-node.h:214
llvm::Value * true_value()
Returns true/false constants (bool type)
Definition: llvm-codegen.h:380
#define COUNTER_SET(c, v)
static const Status CANCELLED
Definition: status.h:88
int64_t metadata() const
RuntimeProfile::Counter * rows_returned_counter_
Definition: exec-node.h:226
bool is_cancelled() const
MemTracker * instance_mem_tracker()
boost::scoped_ptr< MemTracker > mem_tracker_
Account for peak memory used by this node.
Definition: exec-node.h:230
TPlanNodeType::type type_
Definition: exec-node.h:210
llvm::Value * false_value()
Definition: llvm-codegen.h:381
string PrintPlanNodeType(const TPlanNodeType::type &type)
Definition: debug-util.cc:157
std::string LogUsage(const std::string &prefix="") const
Logs the usage of this tracker and all of its children (recursively).
llvm::Value * GetVal(const char *name="val")
static const Status OK
Definition: status.h:87
ObjectPool * pool_
Definition: exec-node.h:211
llvm::Type * GetType(const ColumnType &type)
Returns llvm type for the column type.
Status GetCodegen(LlvmCodeGen **codegen, bool initialize=true)
llvm::Value * GetIsNull(const char *name="is_null")
Gets the 'is_null' field of the *Val.
static Status CreateExprTrees(ObjectPool *pool, const std::vector< TExpr > &texprs, std::vector< ExprContext * > *ctxs)
Definition: expr.cc:149
llvm::Function * FinalizeFunction(llvm::Function *function)
static bool EvalConjuncts(ExprContext *const *ctxs, int num_ctxs, TupleRow *row)
Definition: exec-node.cc:393
void AddBatch(RowBatch *batch)
Adds a batch to the queue. This is blocking if the queue is full.
Definition: exec-node.cc:74
static Status Prepare(const std::vector< ExprContext * > &ctxs, RuntimeState *state, const RowDescriptor &row_desc, MemTracker *tracker)
void AddChild(RuntimeProfile *child, bool indent=true, RuntimeProfile *location=NULL)
virtual Status Open(RuntimeState *state)
Definition: exec-node.cc:154
bool ok() const
Definition: status.h:172
std::string runtime_exec_options_
Definition: exec-node.h:239
std::vector< ExprContext * > conjunct_ctxs_
Definition: exec-node.h:212
virtual void Close(RuntimeState *state)
Definition: exec-node.cc:166
static void SetDebugOptions(int node_id, TExecNodePhase::type phase, TDebugAction::type action, ExecNode *tree)
Set debug action for node with given id in 'tree'.
Definition: exec-node.cc:332
string name
Definition: cpu-info.cc:50
llvm::LLVMContext & context()
Definition: llvm-codegen.h:214
virtual std::string DebugString() const
Definition: expr.cc:385
const std::vector< ExprContext * > & sort_tuple_slot_expr_ctxs() const
const std::vector< ExprContext * > & rhs_ordering_expr_ctxs() const
Can only be used after calling Open()
RuntimeProfile::Counter * rows_returned_rate_
Definition: exec-node.h:227
int64_t limit() const
Definition: exec-node.h:158
virtual Status Reset(RuntimeState *state)
Definition: exec-node.cc:159
RuntimeProfile * runtime_profile()
Definition: exec-node.h:161