------------------------------------------------------------------------------ ARRAY -> VARCHAR ------------------------------------------------------------------------------
| 92 | // ARRAY -> VARCHAR |
| 93 | //------------------------------------------------------------------------------ |
| 94 | static bool ArrayToVarcharCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { |
| 95 | auto is_constant = source.GetVectorType() == VectorType::CONSTANT_VECTOR; |
| 96 | |
| 97 | auto size = ArrayType::GetSize(source.GetType()); |
| 98 | Vector varchar_list(LogicalType::ARRAY(LogicalType::VARCHAR, size), count); |
| 99 | ArrayToArrayCast(source, varchar_list, count, parameters); |
| 100 | |
| 101 | varchar_list.Flatten(count); |
| 102 | auto &validity = FlatVector::Validity(varchar_list); |
| 103 | auto &child = ArrayVector::GetEntry(varchar_list); |
| 104 | |
| 105 | child.Flatten(count); |
| 106 | auto &child_validity = FlatVector::Validity(child); |
| 107 | |
| 108 | auto in_data = FlatVector::GetData<string_t>(child); |
| 109 | auto out_data = FlatVector::GetData<string_t>(result); |
| 110 | |
| 111 | static constexpr const idx_t SEP_LENGTH = 2; |
| 112 | static constexpr const idx_t NULL_LENGTH = 4; |
| 113 | |
| 114 | for (idx_t i = 0; i < count; i++) { |
| 115 | if (!validity.RowIsValid(i)) { |
| 116 | FlatVector::SetNull(result, i, true); |
| 117 | continue; |
| 118 | } |
| 119 | |
| 120 | // First pass, compute the length |
| 121 | idx_t array_varchar_length = 2; |
| 122 | for (idx_t j = 0; j < size; j++) { |
| 123 | auto elem_idx = (i * size) + j; |
| 124 | auto elem = in_data[elem_idx]; |
| 125 | if (j > 0) { |
| 126 | array_varchar_length += SEP_LENGTH; |
| 127 | } |
| 128 | array_varchar_length += child_validity.RowIsValid(elem_idx) ? elem.GetSize() : NULL_LENGTH; |
| 129 | } |
| 130 | |
| 131 | out_data[i] = StringVector::EmptyString(result, array_varchar_length); |
| 132 | auto dataptr = out_data[i].GetDataWriteable(); |
| 133 | idx_t offset = 0; |
| 134 | dataptr[offset++] = '['; |
| 135 | |
| 136 | // Second pass, write the actual data |
| 137 | for (idx_t j = 0; j < size; j++) { |
| 138 | auto elem_idx = (i * size) + j; |
| 139 | auto elem = in_data[elem_idx]; |
| 140 | if (j > 0) { |
| 141 | memcpy(dataptr + offset, ", ", SEP_LENGTH); |
| 142 | offset += SEP_LENGTH; |
| 143 | } |
| 144 | if (child_validity.RowIsValid(elem_idx)) { |
| 145 | auto len = elem.GetSize(); |
| 146 | memcpy(dataptr + offset, elem.GetData(), len); |
| 147 | offset += len; |
| 148 | } else { |
| 149 | memcpy(dataptr + offset, "NULL", NULL_LENGTH); |
| 150 | offset += NULL_LENGTH; |
| 151 | } |
nothing calls this directly
no test coverage detected