1#include "duckdb/parser/expression/operator_expression.hpp"
2#include "duckdb/parser/expression/subquery_expression.hpp"
3#include "duckdb/parser/transformer.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8unique_ptr<ParsedExpression> Transformer::TransformSubquery(PGSubLink *root) {
9 if (!root) {
10 return nullptr;
11 }
12 auto subquery_expr = make_unique<SubqueryExpression>();
13 subquery_expr->subquery = TransformSelectNode((PGSelectStmt *)root->subselect);
14 if (!subquery_expr->subquery) {
15 return nullptr;
16 }
17 assert(subquery_expr->subquery->GetSelectList().size() > 0);
18
19 switch (root->subLinkType) {
20 case PG_EXISTS_SUBLINK: {
21 subquery_expr->subquery_type = SubqueryType::EXISTS;
22 break;
23 }
24 case PG_ANY_SUBLINK:
25 case PG_ALL_SUBLINK: {
26 // comparison with ANY() or ALL()
27 subquery_expr->subquery_type = SubqueryType::ANY;
28 subquery_expr->child = TransformExpression(root->testexpr);
29 // get the operator name
30 if (!root->operName) {
31 // simple IN
32 subquery_expr->comparison_type = ExpressionType::COMPARE_EQUAL;
33 } else {
34 auto operator_name = string((reinterpret_cast<PGValue *>(root->operName->head->data.ptr_value))->val.str);
35 subquery_expr->comparison_type = OperatorToExpressionType(operator_name);
36 }
37 assert(subquery_expr->comparison_type == ExpressionType::COMPARE_EQUAL ||
38 subquery_expr->comparison_type == ExpressionType::COMPARE_NOTEQUAL ||
39 subquery_expr->comparison_type == ExpressionType::COMPARE_GREATERTHAN ||
40 subquery_expr->comparison_type == ExpressionType::COMPARE_GREATERTHANOREQUALTO ||
41 subquery_expr->comparison_type == ExpressionType::COMPARE_LESSTHAN ||
42 subquery_expr->comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO);
43 if (root->subLinkType == PG_ALL_SUBLINK) {
44 // ALL sublink is equivalent to NOT(ANY) with inverted comparison
45 // e.g. [= ALL()] is equivalent to [NOT(<> ANY())]
46 // first invert the comparison type
47 subquery_expr->comparison_type = NegateComparisionExpression(subquery_expr->comparison_type);
48 return make_unique<OperatorExpression>(ExpressionType::OPERATOR_NOT, move(subquery_expr));
49 }
50 break;
51 }
52 case PG_EXPR_SUBLINK: {
53 // return a single scalar value from the subquery
54 // no child expression to compare to
55 subquery_expr->subquery_type = SubqueryType::SCALAR;
56 break;
57 }
58 default:
59 throw NotImplementedException("Subquery of type %d not implemented\n", (int)root->subLinkType);
60 }
61 return move(subquery_expr);
62}
63