1#include "duckdb/parser/expression/conjunction_expression.hpp"
2#include "duckdb/parser/expression/operator_expression.hpp"
3#include "duckdb/parser/transformer.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8unique_ptr<ParsedExpression> Transformer::TransformBoolExpr(PGBoolExpr *root) {
9 unique_ptr<ParsedExpression> result;
10 for (auto node = root->args->head; node != nullptr; node = node->next) {
11 auto next = TransformExpression(reinterpret_cast<PGNode *>(node->data.ptr_value));
12
13 switch (root->boolop) {
14 case PG_AND_EXPR: {
15 if (!result) {
16 result = move(next);
17 } else {
18 result = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_AND, move(result), move(next));
19 }
20 break;
21 }
22 case PG_OR_EXPR: {
23 if (!result) {
24 result = move(next);
25 } else {
26 result = make_unique<ConjunctionExpression>(ExpressionType::CONJUNCTION_OR, move(result), move(next));
27 }
28 break;
29 }
30 case PG_NOT_EXPR: {
31 if (next->type == ExpressionType::COMPARE_IN) {
32 // convert COMPARE_IN to COMPARE_NOT_IN
33 next->type = ExpressionType::COMPARE_NOT_IN;
34 result = move(next);
35 } else if (next->type >= ExpressionType::COMPARE_EQUAL &&
36 next->type <= ExpressionType::COMPARE_GREATERTHANOREQUALTO) {
37 // NOT on a comparison: we can negate the comparison
38 // e.g. NOT(x > y) is equivalent to x <= y
39 next->type = NegateComparisionExpression(next->type);
40 result = move(next);
41 } else {
42 result = make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(next));
43 }
44 break;
45 }
46 }
47 }
48 return result;
49}
50