15 #include <boost/algorithm/string.hpp>
29 using namespace impala;
34 : escape_char_(escape_char),
35 null_col_val_(null_col_val),
36 check_null_(check_null) {
40 char* new_data =
reinterpret_cast<char*
>(pool->
Allocate(value->
len));
42 value->
ptr = new_data;
47 const char* src_end = src + *len;
48 char* dest_end = dest + *len;
49 if (maxlen > 0) dest_end = dest + maxlen;
50 char* dest_ptr = dest;
51 bool escape_next_char =
false;
53 while ((src < src_end) && (dest_ptr < dest_end)) {
55 escape_next_char = !escape_next_char;
57 escape_next_char =
false;
59 if (escape_next_char) {
65 char* dest_start =
reinterpret_cast<char*
>(dest);
66 *len = dest_ptr - dest_start;
101 const char* null_col_val,
int len,
bool check_null) {
103 LOG(INFO) <<
"Char isn't supported for CodegenWriteSlot";
109 bool is_default_null = (len == 2 && null_col_val[0] ==
'\\' && null_col_val[1] ==
'N');
110 Function* is_null_string_fn;
111 if (is_default_null) {
112 is_null_string_fn = codegen->
GetFunction(IRFunction::IS_NULL_STRING);
114 is_null_string_fn = codegen->
GetFunction(IRFunction::GENERIC_IS_NULL_STRING);
116 if (is_null_string_fn == NULL)
return NULL;
119 if (tuple_type == NULL)
return NULL;
120 PointerType* tuple_ptr_type = PointerType::get(tuple_type, 0);
123 if (set_null_fn == NULL) {
124 LOG(ERROR) <<
"Could not codegen WriteSlot because slot update codegen failed.";
136 Function* fn = prototype.GeneratePrototype(&builder, &args[0]);
138 BasicBlock* set_null_block, *parse_slot_block, *check_zero_block = NULL;
140 &set_null_block, &parse_slot_block);
143 check_zero_block = BasicBlock::Create(codegen->
context(),
"check_zero", fn);
149 if (is_default_null) {
150 is_null = builder.CreateCall2(is_null_string_fn, args[1], args[2]);
152 is_null = builder.CreateCall4(is_null_string_fn, args[1], args[2],
154 const_cast<char*
>(null_col_val)),
162 builder.CreateCondBr(is_null, set_null_block,
163 (slot_desc->
type().
IsVarLen()) ? parse_slot_block : check_zero_block);
166 builder.SetInsertPoint(check_zero_block);
170 Value* null_len = builder.CreateICmpSLE(
172 builder.CreateCondBr(null_len, set_null_block, parse_slot_block);
176 builder.SetInsertPoint(parse_slot_block);
177 Value* slot = builder.CreateStructGEP(args[0], slot_desc->
field_idx(),
"slot");
180 Value* ptr = builder.CreateStructGEP(slot, 0,
"string_ptr");
181 Value* len = builder.CreateStructGEP(slot, 1,
"string_len");
183 builder.CreateStore(args[1], ptr);
189 Value* len_lt_maxlen = builder.CreateICmpSLT(args[2], maxlen,
"len_lt_maxlen");
190 Value* minlen = builder.CreateSelect(len_lt_maxlen, args[2], maxlen,
192 builder.CreateStore(minlen, len);
194 builder.CreateStore(args[2], len);
198 IRFunction::Type parse_fn_enum;
199 Function* parse_fn = NULL;
202 parse_fn_enum = IRFunction::STRING_TO_BOOL;
205 parse_fn_enum = IRFunction::STRING_TO_INT8;
208 parse_fn_enum = IRFunction::STRING_TO_INT16;
211 parse_fn_enum = IRFunction::STRING_TO_INT32;
214 parse_fn_enum = IRFunction::STRING_TO_INT64;
217 parse_fn_enum = IRFunction::STRING_TO_FLOAT;
220 parse_fn_enum = IRFunction::STRING_TO_DOUBLE;
227 DCHECK(parse_fn != NULL);
230 BasicBlock* parse_success_block, *parse_failed_block;
232 &parse_success_block, &parse_failed_block);
238 Value* result = builder.CreateCall3(parse_fn, args[1], args[2], parse_result_ptr);
239 Value* parse_result_val = builder.CreateLoad(parse_result_ptr,
"parse_result");
242 Value* parse_failed = builder.CreateICmpEQ(parse_result_val, failed_value,
"failed");
243 builder.CreateCondBr(parse_failed, parse_failed_block, parse_success_block);
246 builder.SetInsertPoint(parse_success_block);
247 builder.CreateStore(result, slot);
251 builder.SetInsertPoint(parse_failed_block);
252 builder.CreateCall(set_null_fn, args[0]);
257 builder.SetInsertPoint(set_null_block);
258 builder.CreateCall(set_null_fn, args[0]);
RuntimeProfile::Counter * codegen_timer()
Utility struct that wraps a variable name and llvm type.
void UnescapeString(const char *src, char *dest, int *len, int64_t maxlen=-1)
TextConverter(char escape_char, const std::string &null_col_val, bool check_null=true)
llvm::StructType * GenerateLlvmStruct(LlvmCodeGen *codegen)
LLVM code generator. This is the top level object to generate jitted code.
llvm::Value * CastPtrToLlvmPtr(llvm::Type *type, const void *ptr)
void AddArgument(const NamedVariable &var)
Add argument.
const ColumnType & type() const
llvm::Function * GetFunction(IRFunction::Type)
int len
Only set if type == TYPE_CHAR or type == TYPE_VARCHAR.
void CreateIfElseBlocks(llvm::Function *fn, const std::string &if_name, const std::string &else_name, llvm::BasicBlock **if_block, llvm::BasicBlock **else_block, llvm::BasicBlock *insert_before=NULL)
llvm::Function * CodegenUpdateNull(LlvmCodeGen *, llvm::StructType *tuple, bool set_null)
llvm::Value * true_value()
Returns true/false constants (bool type)
llvm::Value * false_value()
llvm::Type * GetType(const ColumnType &type)
Returns llvm type for the column type.
int field_idx() const
Returns the field index in the generated llvm struct for this slot's tuple.
llvm::Value * GetIntConstant(PrimitiveType type, int64_t val)
Returns the constant 'val' of 'type'.
llvm::Function * FinalizeFunction(llvm::Function *function)
llvm::LLVMContext & context()
llvm::AllocaInst * CreateEntryBlockAlloca(llvm::Function *f, const NamedVariable &var)
uint8_t * Allocate(int size)
llvm::PointerType * ptr_type()
static llvm::Function * CodegenWriteSlot(LlvmCodeGen *codegen, TupleDescriptor *tuple_desc, SlotDescriptor *slot_desc, const char *null_col_val, int len, bool check_null)