ColumnPtr FunctionArrayIntersect::castRemoveNullable(const ColumnPtr & column, const DataTypePtr & data_type) const { if (auto column_nullable = checkAndGetColumn<ColumnNullable>(column.get())) { auto nullable_type = checkAndGetDataType<DataTypeNullable>(data_type.get()); const auto & nested = column_nullable->getNestedColumnPtr(); if (nullable_type) { auto casted_column = castRemoveNullable(nested, nullable_type->getNestedType()); return ColumnNullable::create(casted_column, column_nullable->getNullMapColumnPtr()); } return castRemoveNullable(nested, data_type); } else if (auto column_array = checkAndGetColumn<ColumnArray>(column.get())) { auto array_type = checkAndGetDataType<DataTypeArray>(data_type.get()); if (!array_type) throw Exception{"Cannot cast array column to column with type " + data_type->getName() + " in function " + getName(), ErrorCodes::LOGICAL_ERROR}; auto casted_column = castRemoveNullable(column_array->getDataPtr(), array_type->getNestedType()); return ColumnArray::create(casted_column, column_array->getOffsetsPtr()); } else if (auto column_tuple = checkAndGetColumn<ColumnTuple>(column.get())) { auto tuple_type = checkAndGetDataType<DataTypeTuple>(data_type.get()); if (!tuple_type) throw Exception{"Cannot cast tuple column to type " + data_type->getName() + " in function " + getName(), ErrorCodes::LOGICAL_ERROR}; auto columns_number = column_tuple->getColumns().size(); Columns columns(columns_number); const auto & types = tuple_type->getElements(); for (auto i : ext::range(0, columns_number)) { columns[i] = castRemoveNullable(column_tuple->getColumnPtr(i), types[i]); } return ColumnTuple::create(columns); } return column; }
DataPtr DataUtility::getSelectedParentDataByType(DataPtr _data, DataTypePtr _info) { if (_data == nullptr) return NULL; for (DataType::VectorString::const_iterator child = _data->getType()->getChilds().begin(); child != _data->getType()->getChilds().end(); child ++) { if ((*child) == _info->getName()) return _data; } return getSelectedParentDataByType(_data->getChildSelected(), _info); }
ColumnPtr recursiveLowCardinalityConversion(const ColumnPtr & column, const DataTypePtr & from_type, const DataTypePtr & to_type) { if (!column) return column; if (from_type->equals(*to_type)) return column; if (const auto * column_const = typeid_cast<const ColumnConst *>(column.get())) return ColumnConst::create(recursiveLowCardinalityConversion(column_const->getDataColumnPtr(), from_type, to_type), column_const->size()); if (const auto * low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(from_type.get())) { if (to_type->equals(*low_cardinality_type->getDictionaryType())) return column->convertToFullColumnIfLowCardinality(); } if (const auto * low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(to_type.get())) { if (from_type->equals(*low_cardinality_type->getDictionaryType())) { auto col = low_cardinality_type->createColumn(); static_cast<ColumnLowCardinality &>(*col).insertRangeFromFullColumn(*column, 0, column->size()); return std::move(col); } } if (const auto * from_array_type = typeid_cast<const DataTypeArray *>(from_type.get())) { if (const auto * to_array_type = typeid_cast<const DataTypeArray *>(to_type.get())) { const auto * column_array = typeid_cast<const ColumnArray *>(column.get()); if (!column_array) throw Exception("Unexpected column " + column->getName() + " for type " + from_type->getName(), ErrorCodes::ILLEGAL_COLUMN); auto & nested_from = from_array_type->getNestedType(); auto & nested_to = to_array_type->getNestedType(); return ColumnArray::create( recursiveLowCardinalityConversion(column_array->getDataPtr(), nested_from, nested_to), column_array->getOffsetsPtr()); } } if (const auto * from_tuple_type = typeid_cast<const DataTypeTuple *>(from_type.get())) { if (const auto * to_tuple_type = typeid_cast<const DataTypeTuple *>(to_type.get())) { const auto * column_tuple = typeid_cast<const ColumnTuple *>(column.get()); if (!column_tuple) throw Exception("Unexpected column " + column->getName() + " for type " + from_type->getName(), ErrorCodes::ILLEGAL_COLUMN); Columns columns = column_tuple->getColumns(); auto & from_elements = from_tuple_type->getElements(); auto & to_elements = to_tuple_type->getElements(); for (size_t i = 0; i < columns.size(); ++i) { auto & element = columns[i]; element = recursiveLowCardinalityConversion(element, from_elements.at(i), to_elements.at(i)); } return ColumnTuple::create(columns); } } throw Exception("Cannot convert: " + from_type->getName() + " to " + to_type->getName(), ErrorCodes::TYPE_MISMATCH); }