21.5.1
```sql

create table test(d Date, k Int64, s String) 
Engine=MergeTree partition by (toYYYYMM(d),k) order by (d, k)

insert into test values ('2020-01-01', 1, '');
insert into test values ('2020-01-02', 1, '');

SELECT * FROM test WHERE d != '2020-01-01'
0 rows in set. Elapsed: 0.003 sec.


SELECT * FROM test WHERE identity(d) !=  '2020-01-01';
┌──────────d─┬─k─┬─s─┐
│ 2020-01-02 │ 1 │   │
└────────────┴───┴───┘

SELECT * FROM test WHERE toDate(d) != '2020-01-01';
┌──────────d─┬─k─┬─s─┐
│ 2020-01-02 │ 1 │   │
└────────────┴───┴───┘
```

{
    return (func_name == "and" || func_name == "or" || func_name == "not" || func_name == "indexHint");
}
ASTPtr cloneASTWithInversionPushDown(const ASTPtr node, const bool need_inversion = false)
{
    const ASTFunction * func = node->as<ASTFunction>();
    if (func && isLogicalOperator(func->name))
    {
        if (func->name == "not")
        {
            return cloneASTWithInversionPushDown(func->arguments->children.front(), !need_inversion);
        }
        const auto result_node = makeASTFunction(func->name);
        
        if (result_node->name != "indexHint" && need_inversion)
        {
            result_node->name = (result_node->name == "and") ? "or" : "and";
        }
        if (func->arguments)
        {
            for (const auto & child : func->arguments->children)
            {
                result_node->arguments->children.push_back(cloneASTWithInversionPushDown(child, need_inversion));
            }
        }