**Use case**

Viewing binary data such as bitmasks, hashes, internal representation of IEEE-754 numbers, etc.
Mostly for debugging.

**Describe the solution you'd like**

Similar to `hex`/`unhex`.

`bin` - returns a string with `0` and `1`. Bits are in "human" order, most significant first. Most significant zero bits are not printed (except the case with single zero).

**Describe alternatives you've considered**

Now I have to run interactive `python` from command line, but I will be more happy using ClickHouse.

**Caveats**

The name `bin` may suggest that the function will "split data into bins" but it is completely unrelated.
String getName() const override { return name; }
    size_t getNumberOfArguments() const override { return 2; }
    DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
    {
        const auto * first_argument = checkAndGetDataType<DataTypeFixedString>(arguments[0].get());
        if (!first_argument || first_argument->getN() != IPV6_BINARY_LENGTH)
            throw Exception("Illegal type " + arguments[0]->getName() +
                            " of first argument of function " + getName() +
                            ", expected FixedString(" + toString(IPV6_BINARY_LENGTH) + ")",
                            ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
        const DataTypePtr & second_argument = arguments[1];
        if (!isUInt8(second_argument))
            throw Exception{"Illegal type " + second_argument->getName()
                            + " of second argument of function " + getName()
                            + ", expected UInt8", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT};
        DataTypePtr element = DataTypeFactory::instance().get("IPv6");
        return std::make_shared<DataTypeTuple>(DataTypes{element, element});
    }
    bool useDefaultImplementationForConstants() const override { return true; }