Note: this function has a codegen'd version. Changing this function requires corresponding changes to CodegenWriteSlot().
| 40 | /// Note: this function has a codegen'd version. Changing this function requires |
| 41 | /// corresponding changes to CodegenWriteSlot(). |
| 42 | inline bool TextConverter::WriteSlot(const SlotDescriptor* slot_desc, Tuple* tuple, |
| 43 | const char* data, int len, bool copy_string, bool need_escape, MemPool* pool) { |
| 44 | if ((len == 0 && !slot_desc->type().IsStringType()) || data == NULL) { |
| 45 | tuple->SetNull(slot_desc->null_indicator_offset()); |
| 46 | return true; |
| 47 | } else if (check_null_ && len == null_col_val_.size() && |
| 48 | StringCompare(data, len, null_col_val_.data(), null_col_val_.size(), len) == 0) { |
| 49 | // We matched the special NULL indicator. |
| 50 | tuple->SetNull(slot_desc->null_indicator_offset()); |
| 51 | return true; |
| 52 | } |
| 53 | |
| 54 | StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS; |
| 55 | void* slot = tuple->GetSlot(slot_desc->tuple_offset()); |
| 56 | |
| 57 | // Parse the raw-text data. Translate the text string to internal format. |
| 58 | const ColumnType& type = slot_desc->type(); |
| 59 | switch (type.type) { |
| 60 | case TYPE_STRING: |
| 61 | case TYPE_VARCHAR: |
| 62 | case TYPE_CHAR: { |
| 63 | int buffer_len = len; |
| 64 | if (type.type == TYPE_VARCHAR || type.type == TYPE_CHAR) buffer_len = type.len; |
| 65 | |
| 66 | bool reuse_data = type.IsVarLenStringType() && |
| 67 | !(len != 0 && (copy_string || need_escape)); |
| 68 | |
| 69 | bool base64_decode = false; |
| 70 | if (type.IsBinaryType() && decode_binary_ && len != 0) { |
| 71 | base64_decode = true; |
| 72 | reuse_data = false; |
| 73 | int64_t out_len; |
| 74 | if (!Base64DecodeBufLen(data, len, &out_len)) { |
| 75 | parse_result = StringParser::PARSE_FAILURE; |
| 76 | break; |
| 77 | } |
| 78 | buffer_len = out_len; |
| 79 | } |
| 80 | |
| 81 | StringValue::SimpleString str; |
| 82 | str.ptr = nullptr; |
| 83 | str.len = std::min(buffer_len, len); |
| 84 | if (reuse_data) { |
| 85 | str.ptr = const_cast<char*>(data); |
| 86 | } else { |
| 87 | // The codegen version of this code (generated by CodegenWriteSlot()) doesn't |
| 88 | // include this path. In other words, 'reuse_data' will always be true in the |
| 89 | // codegen version: |
| 90 | // 1. CodegenWriteSlot() doesn't yet support slot of TYPE_CHAR |
| 91 | // 2. HdfsScanner::InitializeWriteTuplesFn() will not codegen if there is |
| 92 | // any escape character. |
| 93 | // 3. HdfsScanner::WriteCompleteTuple() always calls this function with |
| 94 | // 'copy_string' == false. |
| 95 | str.ptr = type.IsVarLenStringType() ? |
| 96 | reinterpret_cast<char*>(pool->TryAllocateUnaligned(buffer_len)) : |
| 97 | reinterpret_cast<char*>(slot); |
| 98 | if (UNLIKELY(str.ptr == nullptr)) { |
| 99 | parse_result = StringParser::PARSE_FAILURE; |
no test coverage detected