```
SET compile_expressions = 1
SELECT GREATEST(2,0)
```

const auto & right_argument = block.getByPosition(arguments[1]);
        auto * left_generic = left_argument.type.get();
        auto * right_generic = right_argument.type.get();
        bool valid = castBothTypes(left_generic, right_generic, [&](const auto & left, const auto & right)
        {
            using LeftDataType = std::decay_t<decltype(left)>;
            using RightDataType = std::decay_t<decltype(right)>;
            if constexpr (std::is_same_v<DataTypeFixedString, LeftDataType> || std::is_same_v<DataTypeFixedString, RightDataType>)
            {
                if constexpr (!Op<DataTypeFixedString, DataTypeFixedString>::allow_fixed_string)
                    return false;
                else
                    return executeFixedString(block, arguments, result);
            }
            else
                return executeNumeric(block, arguments, result, left, right);
        });
        if (!valid)
        {
            
            
            throw Exception(ErrorCodes::LOGICAL_ERROR,
                "Arguments of '{}' have incorrect data types: '{}' of type '{}',"
                " '{}' of type '{}'", getName(),
                left_argument.name, left_argument.type->getName(),
                right_argument.name, right_argument.type->getName());
        }
    }
#if USE_EMBEDDED_COMPILER
    bool isCompilableImpl(const DataTypes & arguments) const override