For example, if I use UInt8 constant for if condition then only one branch is evaluated:
```sql
SELECT if(1, 'success', throwIf(1, 'Executing FALSE branch'))

┌─'success'─┐
│ success   │
└───────────┘

1 rows in set. Elapsed: 0.003 sec.
```

But if I use some constant expression, then both branches are evaluated:
```sql
SELECT if(empty(''), 'success', throwIf(1, 'Executing FALSE branch'))

0 rows in set. Elapsed: 0.003 sec.

Received exception from server (version 21.12.2):
Code: 395. DB::Exception: Received from localhost:9000. DB::Exception: Executing FALSE branch: While processing if(empty(''), 'success', throwIf(1, 'Executing FALSE branch')). (FUNCTION_THROW_IF_VALUE_IS_NON_ZERO)
```
const ColumnWithTypeAndName & arg_else = arguments[2];
        
        if (arg_then.column.get() == arg_else.column.get())
        {
            
            return arg_then.column;
        }
        const ColumnUInt8 * cond_col = typeid_cast<const ColumnUInt8 *>(arg_cond.column.get());
        const ColumnConst * cond_const_col = checkAndGetColumnConst<ColumnVector<UInt8>>(arg_cond.column.get());
        ColumnPtr materialized_cond_col;
        if (cond_const_col)
        {
            if (arg_then.type->equals(*arg_else.type))
            {
                return cond_const_col->getValue<UInt8>()
                    ? arg_then.column
                    : arg_else.column;
            }
            else
            {
                materialized_cond_col = cond_const_col->convertToFullColumn();
                cond_col = typeid_cast<const ColumnUInt8 *>(&*materialized_cond_col);
            }
        }
        if (!cond_col)
            throw Exception("Illegal column " + arg_cond.column->getName() + " of first argument of function " + getName()
                + ". Must be ColumnUInt8 or ColumnConstUInt8.",
                ErrorCodes::ILLEGAL_COLUMN);
        auto call = [&](const auto & types) -> bool
        {