```
SET compile_expressions = 1
SELECT GREATEST(2,0)
```

* Functions XOR and NOT rely on "default implementation for NULLs":
  *   - if any of the arguments is of Nullable type, the return value type is Nullable
  *   - if any of the arguments is NULL, the return value is NULL
  *
  * Functions AND and OR provide their own special implementations for ternary logic
  */
namespace DB
{
namespace FunctionsLogicalDetail
{
namespace Ternary
{
    using ResultType = UInt8;
    /** These carefully picked values magically work so bitwise "and", "or" on them
      *  corresponds to the expected results in three-valued logic.
      *
      * False and True are represented by all-0 and all-1 bits, so all bitwise operations on them work as expected.
      * Null is represented as single 1 bit. So, it is something in between False and True.
      * And "or" works like maximum and "and" works like minimum:
      *  "or" keeps True as is and lifts False with Null to Null.
      *  "and" keeps False as is and downs True with Null to Null.
      *
      * This logic does not apply for "not" and "xor" - they work with default implementation for NULLs:
      *  anything with NULL returns NULL, otherwise use conventional two-valued logic.
      */
    static constexpr UInt8 False = 0;   
    static constexpr UInt8 True = -1;   
    static constexpr UInt8 Null = 1;    
    template <typename T>
    inline ResultType makeValue(T value)