**Describe the bug**

-2147483648 is the minimum integer representable with Int32, but ``toInt32OrNull('-2147483648')`` returns ``NULL``. On the other hand ``toInt32('-2147483648')`` correctly returns ``-2147483648``.

**Does it reproduce on recent release?**

Yes. It happens on 21.7.5.29-stable

**How to reproduce**

```
SELECT
    toInt32('-2147483648'),
    toInt32OrNull('-2147483648')

Query id: 94f4e069-6c0e-44d9-8e94-7ee83b90a529

┌─toInt32('-2147483648')─┬─toInt32OrNull('-2147483648')─┐
│            -2147483648 │                         ᴺᵁᴸᴸ │
└────────────────────────┴──────────────────────────────┘
```

**Expected behavior**

``toInt32('-2147483648')`` and ``toInt32OrNull('-2147483648')`` should both return ``-2147483648``.

{
        return __builtin_add_overflow(x, y, &res);
    }
    template <>
    inline bool addOverflow(int x, int y, int & res)
    {
        return __builtin_sadd_overflow(x, y, &res);
    }
    template <>
    inline bool addOverflow(long x, long y, long & res)
    {
        return __builtin_saddl_overflow(x, y, &res);
    }
    template <>
    inline bool addOverflow(long long x, long long y, long long & res)
    {
        return __builtin_saddll_overflow(x, y, &res);
    }
    template <>
    inline bool addOverflow(Int128 x, Int128 y, Int128 & res)
    {
        res = addIgnoreOverflow(x, y);
        return (y > 0 && x > std::numeric_limits<Int128>::max() - y) ||
            (y < 0 && x < std::numeric_limits<Int128>::min() - y);
    }
    template <>
    inline bool addOverflow(UInt128 x, UInt128 y, UInt128 & res)