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)
```
size_t rows = cond_data.size();
        if ((col_arr_then || col_arr_then_const)
            && (col_arr_else || col_arr_else_const))
        {
            auto res = result_type->createColumn();
            auto * col_res = assert_cast<ColumnArray *>(res.get());
            if (col_arr_then && col_arr_else)
                conditional(GenericArraySource(*col_arr_then), GenericArraySource(*col_arr_else), GenericArraySink(col_res->getData(), col_res->getOffsets(), rows), cond_data);
            else if (col_arr_then && col_arr_else_const)
                conditional(GenericArraySource(*col_arr_then), ConstSource<GenericArraySource>(*col_arr_else_const), GenericArraySink(col_res->getData(), col_res->getOffsets(), rows), cond_data);
            else if (col_arr_then_const && col_arr_else)
                conditional(ConstSource<GenericArraySource>(*col_arr_then_const), GenericArraySource(*col_arr_else), GenericArraySink(col_res->getData(), col_res->getOffsets(), rows), cond_data);
            else if (col_arr_then_const && col_arr_else_const)
                conditional(ConstSource<GenericArraySource>(*col_arr_then_const), ConstSource<GenericArraySource>(*col_arr_else_const), GenericArraySink(col_res->getData(), col_res->getOffsets(), rows), cond_data);
            else
                return nullptr;
            return res;
        }
        return nullptr;
    }
    ColumnPtr executeTuple(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
    {
        
        const ColumnWithTypeAndName & arg1 = arguments[1];
        const ColumnWithTypeAndName & arg2 = arguments[2];
        Columns col1_contents;
        Columns col2_contents;
        if (const ColumnTuple * tuple1 = typeid_cast<const ColumnTuple *>(arg1.column.get()))
            col1_contents = tuple1->getColumnsCopy();
        else if (const ColumnConst * const_tuple = checkAndGetColumnConst<ColumnTuple>(arg1.column.get()))