1 | #include "duckdb/common/exception.hpp" |
---|---|
2 | #include "duckdb/parser/tableref/basetableref.hpp" |
3 | #include "duckdb/parser/tableref/joinref.hpp" |
4 | #include "duckdb/parser/transformer.hpp" |
5 | |
6 | namespace duckdb { |
7 | |
8 | unique_ptr<TableRef> Transformer::TransformJoin(duckdb_libpgquery::PGJoinExpr &root) { |
9 | auto result = make_uniq<JoinRef>(args: JoinRefType::REGULAR); |
10 | switch (root.jointype) { |
11 | case duckdb_libpgquery::PG_JOIN_INNER: { |
12 | result->type = JoinType::INNER; |
13 | break; |
14 | } |
15 | case duckdb_libpgquery::PG_JOIN_LEFT: { |
16 | result->type = JoinType::LEFT; |
17 | break; |
18 | } |
19 | case duckdb_libpgquery::PG_JOIN_FULL: { |
20 | result->type = JoinType::OUTER; |
21 | break; |
22 | } |
23 | case duckdb_libpgquery::PG_JOIN_RIGHT: { |
24 | result->type = JoinType::RIGHT; |
25 | break; |
26 | } |
27 | case duckdb_libpgquery::PG_JOIN_SEMI: { |
28 | result->type = JoinType::SEMI; |
29 | break; |
30 | } |
31 | case duckdb_libpgquery::PG_JOIN_ANTI: { |
32 | result->type = JoinType::ANTI; |
33 | break; |
34 | } |
35 | case duckdb_libpgquery::PG_JOIN_POSITION: { |
36 | result->ref_type = JoinRefType::POSITIONAL; |
37 | break; |
38 | } |
39 | default: { |
40 | throw NotImplementedException("Join type %d not supported\n", root.jointype); |
41 | } |
42 | } |
43 | |
44 | // Check the type of left arg and right arg before transform |
45 | result->left = TransformTableRefNode(n&: *root.larg); |
46 | result->right = TransformTableRefNode(n&: *root.rarg); |
47 | switch (root.joinreftype) { |
48 | case duckdb_libpgquery::PG_JOIN_NATURAL: |
49 | result->ref_type = JoinRefType::NATURAL; |
50 | break; |
51 | case duckdb_libpgquery::PG_JOIN_ASOF: |
52 | result->ref_type = JoinRefType::ASOF; |
53 | break; |
54 | default: |
55 | break; |
56 | } |
57 | result->query_location = root.location; |
58 | |
59 | if (root.usingClause && root.usingClause->length > 0) { |
60 | // usingClause is a list of strings |
61 | for (auto node = root.usingClause->head; node != nullptr; node = node->next) { |
62 | auto target = reinterpret_cast<duckdb_libpgquery::PGNode *>(node->data.ptr_value); |
63 | D_ASSERT(target->type == duckdb_libpgquery::T_PGString); |
64 | auto column_name = string(reinterpret_cast<duckdb_libpgquery::PGValue *>(target)->val.str); |
65 | result->using_columns.push_back(x: column_name); |
66 | } |
67 | return std::move(result); |
68 | } |
69 | |
70 | if (!root.quals && result->using_columns.empty() && result->ref_type == JoinRefType::REGULAR) { // CROSS PRODUCT |
71 | result->ref_type = JoinRefType::CROSS; |
72 | } |
73 | result->condition = TransformExpression(node: root.quals); |
74 | return std::move(result); |
75 | } |
76 | |
77 | } // namespace duckdb |
78 |