| 101 | |
| 102 | template <bool nullable> |
| 103 | bool executeFixedString( |
| 104 | const IColumn & src_data, const ColumnArray::Offsets & src_offsets, |
| 105 | IColumn & res_data_col, ColumnArray::Offsets & res_offsets, |
| 106 | const NullMap * src_null_map, |
| 107 | NullMap * res_null_map) |
| 108 | { |
| 109 | if (const ColumnFixedString * src_data_concrete = checkAndGetColumn<ColumnFixedString>(&src_data)) |
| 110 | { |
| 111 | const size_t n = src_data_concrete->getN(); |
| 112 | const ColumnFixedString::Chars & src_data_vec = src_data_concrete->getChars(); |
| 113 | |
| 114 | auto * concrete_res_data = typeid_cast<ColumnFixedString *>(&res_data_col); |
| 115 | if (!concrete_res_data) |
| 116 | throw Exception(ErrorCodes::LOGICAL_ERROR, "Internal error"); |
| 117 | |
| 118 | ColumnFixedString::Chars & res_data = concrete_res_data->getChars(); |
| 119 | size_t size = src_offsets.size(); |
| 120 | res_offsets.resize(size); |
| 121 | res_data.reserve(src_data_vec.size()); |
| 122 | |
| 123 | if (nullable) |
| 124 | res_null_map->reserve(src_null_map->size()); |
| 125 | |
| 126 | ColumnArray::Offset src_prev_offset = 0; |
| 127 | ColumnArray::Offset res_prev_offset = 0; |
| 128 | |
| 129 | for (size_t i = 0; i < size; ++i) |
| 130 | { |
| 131 | if (src_offsets[i] != src_prev_offset) |
| 132 | { |
| 133 | size_t size_to_write = src_offsets[i] - src_prev_offset; |
| 134 | size_t prev_res_data_size = res_data.size(); |
| 135 | res_data.resize(prev_res_data_size + size_to_write * n); |
| 136 | memcpy(&res_data[prev_res_data_size], &src_data_vec[src_prev_offset * n], size_to_write * n); |
| 137 | |
| 138 | if (nullable) |
| 139 | { |
| 140 | res_null_map->resize(res_prev_offset + size_to_write); |
| 141 | memcpy(&(*res_null_map)[res_prev_offset], &(*src_null_map)[src_prev_offset], size_to_write); |
| 142 | } |
| 143 | |
| 144 | res_prev_offset += size_to_write; |
| 145 | res_offsets[i] = res_prev_offset; |
| 146 | } |
| 147 | else |
| 148 | { |
| 149 | size_t prev_res_data_size = res_data.size(); |
| 150 | res_data.resize(prev_res_data_size + n); |
| 151 | memset(&res_data[prev_res_data_size], 0, n); |
| 152 | ++res_prev_offset; |
| 153 | res_offsets[i] = res_prev_offset; |
| 154 | |
| 155 | if (nullable) |
| 156 | res_null_map->push_back(ColumnNullable::IS_NULL_MASK); |
| 157 | } |
| 158 | |
| 159 | src_prev_offset = src_offsets[i]; |
| 160 | } |
no test coverage detected