Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
expr-context.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 "exprs/expr-context.h"
16 
17 #include <sstream>
18 
19 #include "exprs/expr.h"
20 #include "runtime/mem-pool.h"
21 #include "runtime/runtime-state.h"
22 #include "udf/udf-internal.h"
23 
24 #include "common/names.h"
25 
26 using namespace impala;
27 using namespace impala_udf;
28 
29 const char* ExprContext::LLVM_CLASS_NAME = "class.impala::ExprContext";
30 
32  : fn_contexts_ptr_(NULL),
33  root_(root),
34  is_clone_(false),
35  prepared_(false),
36  opened_(false),
37  closed_(false) {
38 }
39 
41  DCHECK(!prepared_ || closed_);
42  for (int i = 0; i < fn_contexts_.size(); ++i) {
43  delete fn_contexts_[i];
44  }
45 }
46 
49  DCHECK(tracker != NULL);
50  DCHECK(pool_.get() == NULL);
51  prepared_ = true;
52  pool_.reset(new MemPool(tracker));
53  return root_->Prepare(state, row_desc, this);
54 }
55 
57  DCHECK(prepared_);
58  DCHECK(!opened_);
59  opened_ = true;
60  // Fragment-local state is only initialized for original contexts. Clones inherit the
61  // original's fragment state and only need to have thread-local state initialized.
63  is_clone_? FunctionContext::THREAD_LOCAL : FunctionContext::FRAGMENT_LOCAL;
64  return root_->Open(state, this, scope);
65 }
66 
68  DCHECK(!closed_);
70  is_clone_? FunctionContext::THREAD_LOCAL : FunctionContext::FRAGMENT_LOCAL;
71  root_->Close(state, this, scope);
72 
73  for (int i = 0; i < fn_contexts_.size(); ++i) {
74  fn_contexts_[i]->impl()->Close();
75  }
76  // pool_ can be NULL if Prepare() was never called
77  if (pool_ != NULL) pool_->FreeAll();
78  closed_ = true;
79 }
80 
82  const impala_udf::FunctionContext::TypeDesc& return_type,
83  const vector<impala_udf::FunctionContext::TypeDesc>& arg_types,
84  int varargs_buffer_size) {
86  state, pool_.get(), return_type, arg_types, varargs_buffer_size));
88  return fn_contexts_.size() - 1;
89 }
90 
92  DCHECK(prepared_);
93  DCHECK(opened_);
94 
95  *new_ctx = state->obj_pool()->Add(new ExprContext(root_));
96  (*new_ctx)->pool_.reset(new MemPool(pool_->mem_tracker()));
97  for (int i = 0; i < fn_contexts_.size(); ++i) {
98  (*new_ctx)->fn_contexts_.push_back(
99  fn_contexts_[i]->impl()->Clone((*new_ctx)->pool_.get()));
100  }
101  (*new_ctx)->fn_contexts_ptr_ = &((*new_ctx)->fn_contexts_[0]);
102 
103  (*new_ctx)->prepared_ = true;
104  (*new_ctx)->is_clone_ = true;
105 
106  return root_->Open(state, *new_ctx, FunctionContext::THREAD_LOCAL);
107 }
108 
111 }
112 
113 void ExprContext::FreeLocalAllocations(const vector<ExprContext*>& ctxs) {
114  for (int i = 0; i < ctxs.size(); ++i) {
115  ctxs[i]->FreeLocalAllocations();
116  }
117 }
118 
119 void ExprContext::FreeLocalAllocations(const vector<FunctionContext*>& fn_ctxs) {
120  for (int i = 0; i < fn_ctxs.size(); ++i) {
121  if (fn_ctxs[i]->impl()->closed()) continue;
122  fn_ctxs[i]->impl()->FreeLocalAllocations();
123  }
124 }
125 
126 void ExprContext::GetValue(TupleRow* row, bool as_ascii, TColumnValue* col_val) {
127  void* value = GetValue(row);
128  if (as_ascii) {
129  RawValue::PrintValue(value, root_->type_, root_->output_scale_, &col_val->string_val);
130  col_val->__isset.string_val = true;
131  return;
132  }
133  if (value == NULL) return;
134 
135  StringValue* string_val = NULL;
136  string tmp;
137  switch (root_->type_.type) {
138  case TYPE_BOOLEAN:
139  col_val->__set_bool_val(*reinterpret_cast<bool*>(value));
140  break;
141  case TYPE_TINYINT:
142  col_val->__set_byte_val(*reinterpret_cast<int8_t*>(value));
143  break;
144  case TYPE_SMALLINT:
145  col_val->__set_short_val(*reinterpret_cast<int16_t*>(value));
146  break;
147  case TYPE_INT:
148  col_val->__set_int_val(*reinterpret_cast<int32_t*>(value));
149  break;
150  case TYPE_BIGINT:
151  col_val->__set_long_val(*reinterpret_cast<int64_t*>(value));
152  break;
153  case TYPE_FLOAT:
154  col_val->__set_double_val(*reinterpret_cast<float*>(value));
155  break;
156  case TYPE_DOUBLE:
157  col_val->__set_double_val(*reinterpret_cast<double*>(value));
158  break;
159  case TYPE_DECIMAL:
160  switch (root_->type_.GetByteSize()) {
161  case 4:
162  col_val->string_val =
163  reinterpret_cast<Decimal4Value*>(value)->ToString(root_->type_);
164  break;
165  case 8:
166  col_val->string_val =
167  reinterpret_cast<Decimal8Value*>(value)->ToString(root_->type_);
168  break;
169  case 16:
170  col_val->string_val =
171  reinterpret_cast<Decimal16Value*>(value)->ToString(root_->type_);
172  break;
173  default:
174  DCHECK(false) << "Bad Type: " << root_->type_;
175  }
176  col_val->__isset.string_val = true;
177  break;
178  case TYPE_STRING:
179  case TYPE_VARCHAR:
180  string_val = reinterpret_cast<StringValue*>(value);
181  tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
182  col_val->string_val.swap(tmp);
183  col_val->__isset.string_val = true;
184  break;
185  case TYPE_CHAR:
186  tmp.assign(StringValue::CharSlotToPtr(value, root_->type_), root_->type_.len);
187  col_val->string_val.swap(tmp);
188  col_val->__isset.string_val = true;
189  break;
190  case TYPE_TIMESTAMP:
192  value, root_->type_, root_->output_scale_, &col_val->string_val);
193  col_val->__isset.string_val = true;
194  break;
195  default:
196  DCHECK(false) << "bad GetValue() type: " << root_->type_.DebugString();
197  }
198 }
199 
201  return GetValue(root_, row);
202 }
203 
205  switch (e->type_.type) {
206  case TYPE_BOOLEAN: {
207  impala_udf::BooleanVal v = e->GetBooleanVal(this, row);
208  if (v.is_null) return NULL;
209  result_.bool_val = v.val;
210  return &result_.bool_val;
211  }
212  case TYPE_TINYINT: {
213  impala_udf::TinyIntVal v = e->GetTinyIntVal(this, row);
214  if (v.is_null) return NULL;
215  result_.tinyint_val = v.val;
216  return &result_.tinyint_val;
217  }
218  case TYPE_SMALLINT: {
219  impala_udf::SmallIntVal v = e->GetSmallIntVal(this, row);
220  if (v.is_null) return NULL;
222  return &result_.smallint_val;
223  }
224  case TYPE_INT: {
225  impala_udf::IntVal v = e->GetIntVal(this, row);
226  if (v.is_null) return NULL;
227  result_.int_val = v.val;
228  return &result_.int_val;
229  }
230  case TYPE_BIGINT: {
231  impala_udf::BigIntVal v = e->GetBigIntVal(this, row);
232  if (v.is_null) return NULL;
233  result_.bigint_val = v.val;
234  return &result_.bigint_val;
235  }
236  case TYPE_FLOAT: {
237  impala_udf::FloatVal v = e->GetFloatVal(this, row);
238  if (v.is_null) return NULL;
239  result_.float_val = v.val;
240  return &result_.float_val;
241  }
242  case TYPE_DOUBLE: {
243  impala_udf::DoubleVal v = e->GetDoubleVal(this, row);
244  if (v.is_null) return NULL;
245  result_.double_val = v.val;
246  return &result_.double_val;
247  }
248  case TYPE_STRING:
249  case TYPE_VARCHAR: {
250  impala_udf::StringVal v = e->GetStringVal(this, row);
251  if (v.is_null) return NULL;
252  result_.string_val.ptr = reinterpret_cast<char*>(v.ptr);
254  return &result_.string_val;
255  }
256  case TYPE_CHAR: {
257  impala_udf::StringVal v = e->GetStringVal(this, row);
258  if (v.is_null) return NULL;
259  result_.string_val.ptr = reinterpret_cast<char*>(v.ptr);
261  if (e->type_.IsVarLen()) {
262  return &result_.string_val;
263  } else {
264  return result_.string_val.ptr;
265  }
266  }
267  case TYPE_TIMESTAMP: {
268  impala_udf::TimestampVal v = e->GetTimestampVal(this, row);
269  if (v.is_null) return NULL;
271  return &result_.timestamp_val;
272  }
273  case TYPE_DECIMAL: {
274  DecimalVal v = e->GetDecimalVal(this, row);
275  if (v.is_null) return NULL;
276  switch (e->type_.GetByteSize()) {
277  case 4:
279  return &result_.decimal4_val;
280  case 8:
282  return &result_.decimal8_val;
283  case 16:
285  return &result_.decimal16_val;
286  default:
287  DCHECK(false) << e->type_.GetByteSize();
288  return NULL;
289  }
290  }
291  default:
292  DCHECK(false) << "Type not implemented: " << e->type_.DebugString();
293  return NULL;
294  }
295 }
296 
297 void ExprContext::PrintValue(TupleRow* row, string* str) {
299 }
300 void ExprContext::PrintValue(void* value, string* str) {
302 }
303 void ExprContext::PrintValue(void* value, stringstream* stream) {
304  RawValue::PrintValue(value, root_->type(), root_->output_scale_, stream);
305 }
306 void ExprContext::PrintValue(TupleRow* row, stringstream* stream) {
308 }
309 
311  return root_->GetBooleanVal(this, row);
312 }
314  return root_->GetTinyIntVal(this, row);
315 }
317  return root_->GetSmallIntVal(this, row);
318 }
320  return root_->GetIntVal(this, row);
321 }
323  return root_->GetBigIntVal(this, row);
324 }
326  return root_->GetFloatVal(this, row);
327 }
329  return root_->GetDoubleVal(this, row);
330 }
332  return root_->GetStringVal(this, row);
333 }
335  return root_->GetTimestampVal(this, row);
336 }
338  return root_->GetDecimalVal(this, row);
339 }
bool IsVarLen() const
Definition: types.h:172
static void PrintValue(const void *value, const ColumnType &type, int scale, std::stringstream *stream)
Definition: raw-value.h:224
BooleanVal GetBooleanVal(TupleRow *row)
Calls Get*Val on root_.
virtual IntVal GetIntVal(ExprContext *context, TupleRow *)
Definition: expr.cc:585
virtual TimestampVal GetTimestampVal(ExprContext *context, TupleRow *)
Definition: expr.cc:605
MemTracker tracker
virtual SmallIntVal GetSmallIntVal(ExprContext *context, TupleRow *)
Definition: expr.cc:581
static Status Open(const std::vector< ExprContext * > &ctxs, RuntimeState *state)
Convenience function for opening multiple expr trees.
IntVal GetIntVal(TupleRow *row)
__int128_t val16
Definition: udf.h:572
Decimal8Value decimal8_val
Definition: expr-value.h:36
int32_t val
Definition: udf.h:421
boost::scoped_ptr< MemPool > pool_
Pool backing fn_contexts_. Counts against the runtime state's UDF mem tracker.
Definition: expr-context.h:144
void * GetValue(TupleRow *row)
virtual BooleanVal GetBooleanVal(ExprContext *context, TupleRow *)
Definition: expr.cc:573
Expr * root_
The expr tree this context is for.
Definition: expr-context.h:147
virtual DoubleVal GetDoubleVal(ExprContext *context, TupleRow *)
Definition: expr.cc:597
Status Clone(RuntimeState *state, ExprContext **new_context)
Definition: expr-context.cc:91
TimestampValue timestamp_val
Definition: expr-value.h:34
This object has a compatible storage format with boost::ptime.
Definition: udf.h:495
uint8_t * ptr
Definition: udf.h:523
StringValue string_val
Definition: expr-value.h:33
virtual StringVal GetStringVal(ExprContext *context, TupleRow *)
Definition: expr.cc:601
virtual DecimalVal GetDecimalVal(ExprContext *context, TupleRow *)
Definition: expr.cc:609
static void Close(const std::vector< ExprContext * > &ctxs, RuntimeState *state)
Convenience function for closing multiple expr trees.
void PrintValue(TupleRow *row, std::string *str)
Convenience functions: print value into 'str' or 'stream'. NULL turns into "NULL".
Status Prepare(RuntimeState *state, const RowDescriptor &row_desc, MemTracker *tracker)
Definition: expr-context.cc:47
bool is_null
Definition: udf.h:359
std::string DebugString() const
Definition: types.cc:194
TimestampVal GetTimestampVal(TupleRow *row)
static const char * LLVM_CLASS_NAME
Definition: expr-context.h:126
PrimitiveType type
Definition: types.h:60
DecimalVal GetDecimalVal(TupleRow *row)
ExprContext(Expr *root)
Definition: expr-context.cc:31
FloatVal GetFloatVal(TupleRow *row)
FunctionContext ** fn_contexts_ptr_
Definition: expr-context.h:141
bool is_clone_
Debugging variables.
Definition: expr-context.h:154
ObjectPool * obj_pool() const
Definition: runtime-state.h:92
int GetByteSize() const
Returns the byte size of this type. Returns 0 for variable length types.
Definition: types.h:178
TinyIntVal GetTinyIntVal(TupleRow *row)
int len
Only set if type == TYPE_CHAR or type == TYPE_VARCHAR.
Definition: types.h:62
StringVal GetStringVal(TupleRow *row)
DoubleVal GetDoubleVal(TupleRow *row)
This is the superclass of all expr evaluation nodes.
Definition: expr.h:116
virtual FloatVal GetFloatVal(ExprContext *context, TupleRow *)
Definition: expr.cc:593
This class is thread-safe.
Definition: mem-tracker.h:61
const RowDescriptor & row_desc() const
virtual BigIntVal GetBigIntVal(ExprContext *context, TupleRow *)
Definition: expr.cc:589
int64_t bigint_val
Definition: expr-value.h:30
static TimestampValue FromTimestampVal(const impala_udf::TimestampVal &udf_value)
const ColumnType & type() const
Definition: expr.h:145
Decimal4Value decimal4_val
Definition: expr-value.h:35
static impala_udf::FunctionContext * CreateContext(RuntimeState *state, MemPool *pool, const impala_udf::FunctionContext::TypeDesc &return_type, const std::vector< impala_udf::FunctionContext::TypeDesc > &arg_types, int varargs_buffer_size=0, bool debug=false)
Create a FunctionContext for a UDF. Caller is responsible for deleting it.
int output_scale_
Definition: expr.h:291
SmallIntVal GetSmallIntVal(TupleRow *row)
Decimal16Value decimal16_val
Definition: expr-value.h:37
static char * CharSlotToPtr(void *slot, const ColumnType &type)
virtual TinyIntVal GetTinyIntVal(ExprContext *context, TupleRow *)
Definition: expr.cc:577
std::vector< FunctionContext * > fn_contexts_
Definition: expr-context.h:136
int Register(RuntimeState *state, const FunctionContext::TypeDesc &return_type, const std::vector< FunctionContext::TypeDesc > &arg_types, int varargs_buffer_size=0)
Definition: expr-context.cc:81
const ColumnType type_
analysis is done, types are fixed at this point
Definition: expr.h:289
int16_t smallint_val
Definition: expr-value.h:28
static Status Prepare(const std::vector< ExprContext * > &ctxs, RuntimeState *state, const RowDescriptor &row_desc, MemTracker *tracker)
Status Open(RuntimeState *state)
Must be called after calling Prepare(). Should not be called on clones.
Definition: expr-context.cc:56
BigIntVal GetBigIntVal(TupleRow *row)
int8_t tinyint_val
Definition: expr-value.h:27
void Close(RuntimeState *state)
Closes all FunctionContexts. Must be called on every ExprContext, including clones.
Definition: expr-context.cc:67