DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override { if (!isStringOrFixedString(arguments[0]) && !isArray(arguments[0])) throw Exception( "Illegal type " + arguments[0]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); return arguments[0]; }
Columns FunctionArrayIntersect::castColumns( Block & block, const ColumnNumbers & arguments, const DataTypePtr & return_type, const DataTypePtr & return_type_with_nulls) const { size_t num_args = arguments.size(); Columns columns(num_args); auto type_array = checkAndGetDataType<DataTypeArray>(return_type.get()); auto & type_nested = type_array->getNestedType(); auto type_not_nullable_nested = removeNullable(type_nested); const bool is_numeric_or_string = isNumber(type_not_nullable_nested) || isDateOrDateTime(type_not_nullable_nested) || isStringOrFixedString(type_not_nullable_nested); DataTypePtr nullable_return_type; if (is_numeric_or_string) { auto type_nullable_nested = makeNullable(type_nested); nullable_return_type = std::make_shared<DataTypeArray>(type_nullable_nested); } const bool nested_is_nullable = type_nested->isNullable(); for (size_t i = 0; i < num_args; ++i) { const ColumnWithTypeAndName & arg = block.getByPosition(arguments[i]); auto & column = columns[i]; if (is_numeric_or_string) { /// Cast to Array(T) or Array(Nullable(T)). if (nested_is_nullable) { if (arg.type->equals(*return_type)) column = arg.column; else column = castColumn(arg, return_type, context); } else { /// If result has array type Array(T) still cast Array(Nullable(U)) to Array(Nullable(T)) /// because cannot cast Nullable(T) to T. if (arg.type->equals(*return_type) || arg.type->equals(*nullable_return_type)) column = arg.column; else if (static_cast<const DataTypeArray &>(*arg.type).getNestedType()->isNullable()) column = castColumn(arg, nullable_return_type, context); else column = castColumn(arg, return_type, context); } } else { /// return_type_with_nulls is the most common subtype with possible nullable parts. if (arg.type->equals(*return_type_with_nulls)) column = arg.column; else column = castColumn(arg, return_type_with_nulls, context); } } return columns; }