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)
```
{
        ColumnsWithTypeAndName arguments = std::move(args);
        executeShortCircuitArguments(arguments);
        /** We will gather values from columns in branches to result column,
        *  depending on values of conditions.
        */
        struct Instruction
        {
            IColumn::Ptr condition = nullptr;
            IColumn::Ptr source = nullptr;
            bool condition_always_true = false;
            bool condition_is_nullable = false;
            bool source_is_constant = false;
            bool condition_is_short = false;
            bool source_is_short = false;
            size_t condition_index = 0;
            size_t source_index = 0;
        };
        std::vector<Instruction> instructions;
        instructions.reserve(arguments.size() / 2 + 1);
        Columns converted_columns_holder;
        converted_columns_holder.reserve(instructions.size());
        const DataTypePtr & return_type = result_type;
        for (size_t i = 0; i < arguments.size(); i += 2)
        {
            Instruction instruction;
            size_t source_idx = i + 1;