| 128 | |
| 129 | |
| 130 | ColumnPtr FunctionArrayUniq::executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t /*input_rows_count*/) const |
| 131 | { |
| 132 | const ColumnArray::Offsets * offsets = nullptr; |
| 133 | const size_t num_arguments = arguments.size(); |
| 134 | chassert(num_arguments > 0); |
| 135 | ColumnRawPtrs data_columns(num_arguments); |
| 136 | |
| 137 | Columns array_holders; |
| 138 | for (size_t i = 0; i < num_arguments; ++i) |
| 139 | { |
| 140 | const ColumnPtr & array_ptr = arguments[i].column; |
| 141 | const ColumnArray * array = checkAndGetColumn<ColumnArray>(array_ptr.get()); |
| 142 | if (!array) |
| 143 | { |
| 144 | const ColumnConst * const_array = checkAndGetColumnConst<ColumnArray>( |
| 145 | arguments[i].column.get()); |
| 146 | if (!const_array) |
| 147 | throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of {}-th argument of function {}", |
| 148 | arguments[i].column->getName(), i + 1, getName()); |
| 149 | array_holders.emplace_back(const_array->convertToFullColumn()); |
| 150 | array = checkAndGetColumn<ColumnArray>(array_holders.back().get()); |
| 151 | } |
| 152 | |
| 153 | const ColumnArray::Offsets & offsets_i = array->getOffsets(); |
| 154 | if (i == 0) |
| 155 | offsets = &offsets_i; |
| 156 | else if (offsets_i != *offsets) |
| 157 | throw Exception(ErrorCodes::SIZES_OF_ARRAYS_DONT_MATCH, "Lengths of all arrays passed to {} must be equal.", |
| 158 | getName()); |
| 159 | |
| 160 | const auto * array_data = &array->getData(); |
| 161 | data_columns[i] = array_data; |
| 162 | } |
| 163 | |
| 164 | const NullMap * null_map = nullptr; |
| 165 | |
| 166 | for (size_t i = 0; i < num_arguments; ++i) |
| 167 | { |
| 168 | if (const auto * nullable_col = checkAndGetColumn<ColumnNullable>(data_columns[i])) |
| 169 | { |
| 170 | if (num_arguments == 1) |
| 171 | data_columns[i] = &nullable_col->getNestedColumn(); |
| 172 | |
| 173 | null_map = &nullable_col->getNullMapData(); |
| 174 | break; |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | auto res = ColumnUInt32::create(); |
| 179 | ColumnUInt32::Container & res_values = res->getData(); |
| 180 | res_values.resize(offsets->size()); |
| 181 | |
| 182 | if (num_arguments == 1) |
| 183 | { |
| 184 | if (!(executeNumber<UInt8>(*offsets, *data_columns[0], null_map, res_values) |
| 185 | || executeNumber<UInt16>(*offsets, *data_columns[0], null_map, res_values) |
| 186 | || executeNumber<UInt32>(*offsets, *data_columns[0], null_map, res_values) |
| 187 | || executeNumber<UInt64>(*offsets, *data_columns[0], null_map, res_values) |
nothing calls this directly
no test coverage detected