| 1 | #include "duckdb/parser/tableref/joinref.hpp" |
|---|---|
| 2 | #include "duckdb/parser/tableref/emptytableref.hpp" |
| 3 | #include "duckdb/parser/transformer.hpp" |
| 4 | |
| 5 | namespace duckdb { |
| 6 | |
| 7 | unique_ptr<TableRef> Transformer::TransformFrom(optional_ptr<duckdb_libpgquery::PGList> root) { |
| 8 | if (!root) { |
| 9 | return make_uniq<EmptyTableRef>(); |
| 10 | } |
| 11 | |
| 12 | if (root->length > 1) { |
| 13 | // Cross Product |
| 14 | auto result = make_uniq<JoinRef>(args: JoinRefType::CROSS); |
| 15 | JoinRef *cur_root = result.get(); |
| 16 | idx_t list_size = 0; |
| 17 | for (auto node = root->head; node != nullptr; node = node->next) { |
| 18 | auto n = PGPointerCast<duckdb_libpgquery::PGNode>(ptr: node->data.ptr_value); |
| 19 | unique_ptr<TableRef> next = TransformTableRefNode(n&: *n); |
| 20 | if (!cur_root->left) { |
| 21 | cur_root->left = std::move(next); |
| 22 | } else if (!cur_root->right) { |
| 23 | cur_root->right = std::move(next); |
| 24 | } else { |
| 25 | auto old_res = std::move(result); |
| 26 | result = make_uniq<JoinRef>(args: JoinRefType::CROSS); |
| 27 | result->left = std::move(old_res); |
| 28 | result->right = std::move(next); |
| 29 | cur_root = result.get(); |
| 30 | } |
| 31 | list_size++; |
| 32 | StackCheck(extra_stack: list_size); |
| 33 | } |
| 34 | return std::move(result); |
| 35 | } |
| 36 | |
| 37 | auto n = PGPointerCast<duckdb_libpgquery::PGNode>(ptr: root->head->data.ptr_value); |
| 38 | return TransformTableRefNode(n&: *n); |
| 39 | } |
| 40 | |
| 41 | } // namespace duckdb |
| 42 |