21 #include "gen-cpp/Exprs_types.h" 
   26 using namespace impala_udf;
 
   31 SlotRef::SlotRef(
const TExprNode& node)
 
   34     null_indicator_offset_(0, 0),
 
   35     slot_id_(node.slot_ref.slot_id) {
 
   40   : 
Expr(desc->type(), true),
 
   42     null_indicator_offset_(0, 0),
 
   43     slot_id_(desc->id()) {
 
   50     null_indicator_offset_(0, 0),
 
   51     slot_id_(desc->id()) {
 
   59     null_indicator_offset_(0, -1),
 
   69   if (slot_desc == NULL) {
 
   72     error << 
"couldn't resolve slot descriptor " << 
slot_id_;
 
   73     LOG(INFO) << error.str();
 
   74     return Status(error.str());
 
   78     error << 
"reference to non-materialized slot " << 
slot_id_;
 
   79     return Status(error.str());
 
   85     LOG(INFO) << 
"invalid idx: " << slot_desc->
DebugString()
 
   89     error << 
"invalid tuple_idx";
 
   90     return Status(error.str());
 
  106   out << 
"SlotRef(slot_id=" << 
slot_id_ 
  158     return Status(
"Codegen for Char not supported.");
 
  175   const int64_t TUPLE_NULLABLE_MASK = 1L << 63;
 
  177   DCHECK_EQ(unique_slot_id & TUPLE_NULLABLE_MASK, 0);
 
  180   if (ir_compute_fn_ != NULL) {
 
  185   LLVMContext& context = codegen->
context();
 
  188   Value* row_ptr = args[1];
 
  191   Value* null_byte_offset =
 
  199   BasicBlock* entry_block = BasicBlock::Create(context, 
"entry", *fn);
 
  200   BasicBlock* check_slot_null_indicator_block = NULL;
 
  202     check_slot_null_indicator_block =
 
  203         BasicBlock::Create(context, 
"check_slot_null", *fn);
 
  205   BasicBlock* get_slot_block = BasicBlock::Create(context, 
"get_slot", *fn);
 
  206   BasicBlock* ret_block = BasicBlock::Create(context, 
"ret", *fn);
 
  210   Value* cast_row_ptr = builder.CreateBitCast(
 
  211       row_ptr, PointerType::get(codegen->
ptr_type(), 0), 
"cast_row_ptr");
 
  212   Value* tuple_addr = builder.CreateGEP(cast_row_ptr, tuple_offset, 
"tuple_addr");
 
  214   Value* tuple_ptr = builder.CreateLoad(tuple_addr, 
"tuple_ptr");
 
  218     Value* tuple_is_null = builder.CreateIsNull(tuple_ptr, 
"tuple_is_null");
 
  221       builder.CreateCondBr(tuple_is_null, ret_block, get_slot_block);
 
  223       builder.CreateCondBr(tuple_is_null, ret_block, check_slot_null_indicator_block);
 
  227       builder.CreateBr(get_slot_block);
 
  229       builder.CreateBr(check_slot_null_indicator_block);
 
  234   if (check_slot_null_indicator_block != NULL) {
 
  235     builder.SetInsertPoint(check_slot_null_indicator_block);
 
  236     Value* null_addr = builder.CreateGEP(tuple_ptr, null_byte_offset, 
"null_ptr");
 
  237     Value* null_val = builder.CreateLoad(null_addr, 
"null_byte");
 
  238     Value* slot_null_mask = builder.CreateAnd(null_val, null_mask, 
"null_byte_set");
 
  239     Value* is_slot_null = builder.CreateICmpNE(slot_null_mask, zero, 
"slot_is_null");
 
  240     builder.CreateCondBr(is_slot_null, ret_block, get_slot_block);
 
  244   builder.SetInsertPoint(get_slot_block);
 
  245   Value* slot_ptr = builder.CreateGEP(tuple_ptr, slot_offset, 
"slot_addr");
 
  246   Value* val_ptr = builder.CreateBitCast(slot_ptr, codegen->
GetPtrType(
type_), 
"val_ptr");
 
  251   Value* time_of_day = NULL;
 
  254     Value* ptr_ptr = builder.CreateStructGEP(val_ptr, 0, 
"ptr_ptr");
 
  255     ptr = builder.CreateLoad(ptr_ptr, 
"ptr");
 
  256     Value* len_ptr = builder.CreateStructGEP(val_ptr, 1, 
"len_ptr");
 
  257     len = builder.CreateLoad(len_ptr, 
"len");
 
  259     Value* time_of_day_ptr = builder.CreateStructGEP(val_ptr, 0, 
"time_of_day_ptr");
 
  261     Value* time_of_day_cast =
 
  263     time_of_day = builder.CreateLoad(time_of_day_cast, 
"time_of_day");
 
  264     Value* date_ptr = builder.CreateStructGEP(val_ptr, 1, 
"date_ptr");
 
  267     date = builder.CreateLoad(date_cast, 
"date");
 
  270     val = builder.CreateLoad(val_ptr, 
"val");
 
  272   builder.CreateBr(ret_block);
 
  275   builder.SetInsertPoint(ret_block);
 
  276   PHINode* is_null_phi = builder.CreatePHI(codegen->
tinyint_type(), 2, 
"is_null_phi");
 
  278   if (check_slot_null_indicator_block != NULL) {
 
  279     is_null_phi->addIncoming(one, check_slot_null_indicator_block);
 
  281   is_null_phi->addIncoming(zero, get_slot_block);
 
  287   if (
type().IsVarLen()) {
 
  290     PHINode* ptr_phi = builder.CreatePHI(ptr->getType(), 2, 
"ptr_phi");
 
  291     Value* null = Constant::getNullValue(ptr->getType());
 
  293       ptr_phi->addIncoming(null, entry_block);
 
  295     if (check_slot_null_indicator_block != NULL) {
 
  296       ptr_phi->addIncoming(null, check_slot_null_indicator_block);
 
  298     ptr_phi->addIncoming(ptr, get_slot_block);
 
  300     PHINode* len_phi = builder.CreatePHI(len->getType(), 2, 
"len_phi");
 
  301     null = ConstantInt::get(len->getType(), 0);
 
  303       len_phi->addIncoming(null, entry_block);
 
  305     if (check_slot_null_indicator_block != NULL) {
 
  306       len_phi->addIncoming(null, check_slot_null_indicator_block);
 
  308     len_phi->addIncoming(len, get_slot_block);
 
  315     builder.CreateRet(result.
value());
 
  317     DCHECK(time_of_day != NULL);
 
  318     DCHECK(date != NULL);
 
  319     PHINode* time_of_day_phi =
 
  320         builder.CreatePHI(time_of_day->getType(), 2, 
"time_of_day_phi");
 
  321     Value* null = ConstantInt::get(time_of_day->getType(), 0);
 
  323       time_of_day_phi->addIncoming(null, entry_block);
 
  325     if (check_slot_null_indicator_block != NULL) {
 
  326       time_of_day_phi->addIncoming(null, check_slot_null_indicator_block);
 
  328     time_of_day_phi->addIncoming(time_of_day, get_slot_block);
 
  330     PHINode* date_phi = builder.CreatePHI(date->getType(), 2, 
"date_phi");
 
  331     null = ConstantInt::get(date->getType(), 0);
 
  333       date_phi->addIncoming(null, entry_block);
 
  335     if (check_slot_null_indicator_block != NULL) {
 
  336       date_phi->addIncoming(null, check_slot_null_indicator_block);
 
  338     date_phi->addIncoming(date, get_slot_block);
 
  345     builder.CreateRet(result.
value());
 
  348     PHINode* val_phi = builder.CreatePHI(val->getType(), 2, 
"val_phi");
 
  349     Value* null = Constant::getNullValue(val->getType());
 
  351       val_phi->addIncoming(null, entry_block);
 
  353     if (check_slot_null_indicator_block != NULL) {
 
  354       val_phi->addIncoming(null, check_slot_null_indicator_block);
 
  356     val_phi->addIncoming(val, get_slot_block);
 
  362     builder.CreateRet(result.
value());
 
  367   ir_compute_fn_ = *fn;
 
  426     result.
ptr = 
reinterpret_cast<uint8_t*
>(
 
  459       return DecimalVal::null();
 
virtual impala_udf::BooleanVal GetBooleanVal(ExprContext *context, TupleRow *)
llvm::Function * ir_compute_fn_
Cached codegened compute function. Exprs should set this in GetCodegendComputeFn(). 
std::string DebugString() const 
virtual impala_udf::SmallIntVal GetSmallIntVal(ExprContext *context, TupleRow *)
llvm::PointerType * GetPtrType(llvm::Type *type)
Return a pointer type to 'type'. 
Tuple * GetTuple(int tuple_idx)
void SetLen(llvm::Value *len)
virtual Status GetCodegendComputeFn(RuntimeState *state, llvm::Function **fn)
virtual impala_udf::TimestampVal GetTimestampVal(ExprContext *context, TupleRow *)
A tuple with 0 materialised slots is represented as NULL. 
void SetIsNull(llvm::Value *is_null)
Sets the 'is_null' field of the *Val. 
virtual impala_udf::IntVal GetIntVal(ExprContext *context, TupleRow *)
virtual impala_udf::FloatVal GetFloatVal(ExprContext *context, TupleRow *)
#define RETURN_IF_ERROR(stmt)
some generally useful macros 
virtual impala_udf::TinyIntVal GetTinyIntVal(ExprContext *context, TupleRow *)
void SetVal(llvm::Value *val)
void * GetSlot(int offset)
This object has a compatible storage format with boost::ptime. 
const NullIndicatorOffset & null_indicator_offset() const 
void SetDate(llvm::Value *date)
Setters for TimestampVals. 
TupleDescriptor * GetTupleDescriptor(TupleId id) const 
bool TupleIsNullable(int tuple_idx) const 
Return true if the Tuple of the given Tuple index is nullable. 
static CodegenAnyVal GetNonNullVal(LlvmCodeGen *codegen, LlvmCodeGen::LlvmBuilder *builder, const ColumnType &type, const char *name="")
static const int INVALID_IDX
virtual impala_udf::StringVal GetStringVal(ExprContext *context, TupleRow *)
bool IsNull(const NullIndicatorOffset &offset) const 
void ToTimestampVal(impala_udf::TimestampVal *tv) const 
LLVM code generator. This is the top level object to generate jitted code. 
virtual impala_udf::DoubleVal GetDoubleVal(ExprContext *context, TupleRow *)
llvm::Function * CreateIrFunctionPrototype(LlvmCodeGen *codegen, const std::string &name, llvm::Value *(*args)[2])
bool IsStringType() const 
void RegisterExprFn(int64_t id, llvm::Function *function)
NullIndicatorOffset null_indicator_offset_
void SetPtr(llvm::Value *ptr)
Setters for StringVals. 
void SetTimeOfDay(llvm::Value *time_of_day)
int GetByteSize() const 
Returns the byte size of this type. Returns 0 for variable length types. 
int len
Only set if type == TYPE_CHAR or type == TYPE_VARCHAR. 
std::string DebugString() const 
This is the superclass of all expr evaluation nodes. 
SlotRef(const TExprNode &node)
const DescriptorTbl & desc_tbl() const 
int GetTupleIdx(TupleId id) const 
Returns INVALID_IDX if id not part of this row. 
const RowDescriptor & row_desc() const 
llvm::Type * tinyint_type()
const ColumnType & type() const 
llvm::Value * value()
Returns the current type-lowered value. 
SlotDescriptor * GetSlotDescriptor(SlotId id) const 
virtual int GetSlotIds(std::vector< SlotId > *slot_ids) const 
static char * CharSlotToPtr(void *slot, const ColumnType &type)
virtual impala_udf::BigIntVal GetBigIntVal(ExprContext *context, TupleRow *)
llvm::Type * GetType(const ColumnType &type)
Returns llvm type for the column type. 
uint8_t offset[7 *64-sizeof(uint64_t)]
std::string DebugString() const 
Status GetCodegen(LlvmCodeGen **codegen, bool initialize=true)
const ColumnType type_
analysis is done, types are fixed at this point 
llvm::Function * GetRegisteredExprFn(int64_t id)
Returns a registered expr function for id or NULL if it does not exist. 
llvm::Function * FinalizeFunction(llvm::Function *function)
bool is_materialized() const 
virtual Status Prepare(RuntimeState *state, const RowDescriptor &row_desc, ExprContext *context)
std::vector< Expr * > children_
virtual impala_udf::DecimalVal GetDecimalVal(ExprContext *context, TupleRow *)
void ToStringVal(impala_udf::StringVal *sv) const 
virtual std::string DebugString() const 
llvm::LLVMContext & context()
virtual std::string DebugString() const 
int GetNumChildren() const 
llvm::PointerType * ptr_type()