1 | #include "duckdb/main/relation/value_relation.hpp" |
2 | #include "duckdb/parser/query_node/select_node.hpp" |
3 | #include "duckdb/parser/expression/star_expression.hpp" |
4 | #include "duckdb/parser/tableref/expressionlistref.hpp" |
5 | #include "duckdb/parser/expression/constant_expression.hpp" |
6 | #include "duckdb/main/client_context.hpp" |
7 | #include "duckdb/parser/parser.hpp" |
8 | |
9 | namespace duckdb { |
10 | |
11 | ValueRelation::ValueRelation(const std::shared_ptr<ClientContext> &context, const vector<vector<Value>> &values, |
12 | vector<string> names_p, string alias_p) |
13 | : Relation(context, RelationType::VALUE_LIST_RELATION), names(std::move(names_p)), alias(std::move(alias_p)) { |
14 | // create constant expressions for the values |
15 | for (idx_t row_idx = 0; row_idx < values.size(); row_idx++) { |
16 | auto &list = values[row_idx]; |
17 | vector<unique_ptr<ParsedExpression>> expressions; |
18 | for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { |
19 | expressions.push_back(x: make_uniq<ConstantExpression>(args: list[col_idx])); |
20 | } |
21 | this->expressions.push_back(x: std::move(expressions)); |
22 | } |
23 | context->TryBindRelation(relation&: *this, result_columns&: this->columns); |
24 | } |
25 | |
26 | ValueRelation::ValueRelation(const std::shared_ptr<ClientContext> &context, const string &values_list, |
27 | vector<string> names_p, string alias_p) |
28 | : Relation(context, RelationType::VALUE_LIST_RELATION), names(std::move(names_p)), alias(std::move(alias_p)) { |
29 | this->expressions = Parser::ParseValuesList(value_list: values_list, options: context->GetParserOptions()); |
30 | context->TryBindRelation(relation&: *this, result_columns&: this->columns); |
31 | } |
32 | |
33 | unique_ptr<QueryNode> ValueRelation::GetQueryNode() { |
34 | auto result = make_uniq<SelectNode>(); |
35 | result->select_list.push_back(x: make_uniq<StarExpression>()); |
36 | result->from_table = GetTableRef(); |
37 | return std::move(result); |
38 | } |
39 | |
40 | unique_ptr<TableRef> ValueRelation::GetTableRef() { |
41 | auto table_ref = make_uniq<ExpressionListRef>(); |
42 | // set the expected types/names |
43 | if (columns.empty()) { |
44 | // no columns yet: only set up names |
45 | for (idx_t i = 0; i < names.size(); i++) { |
46 | table_ref->expected_names.push_back(x: names[i]); |
47 | } |
48 | } else { |
49 | for (idx_t i = 0; i < columns.size(); i++) { |
50 | table_ref->expected_names.push_back(x: columns[i].Name()); |
51 | table_ref->expected_types.push_back(x: columns[i].Type()); |
52 | D_ASSERT(names.size() == 0 || columns[i].Name() == names[i]); |
53 | } |
54 | } |
55 | // copy the expressions |
56 | for (auto &expr_list : expressions) { |
57 | vector<unique_ptr<ParsedExpression>> copied_list; |
58 | copied_list.reserve(n: expr_list.size()); |
59 | for (auto &expr : expr_list) { |
60 | copied_list.push_back(x: expr->Copy()); |
61 | } |
62 | table_ref->values.push_back(x: std::move(copied_list)); |
63 | } |
64 | table_ref->alias = GetAlias(); |
65 | return std::move(table_ref); |
66 | } |
67 | |
68 | string ValueRelation::GetAlias() { |
69 | return alias; |
70 | } |
71 | |
72 | const vector<ColumnDefinition> &ValueRelation::Columns() { |
73 | return columns; |
74 | } |
75 | |
76 | string ValueRelation::ToString(idx_t depth) { |
77 | string str = RenderWhitespace(depth) + "Values " ; |
78 | for (idx_t row_idx = 0; row_idx < expressions.size(); row_idx++) { |
79 | auto &list = expressions[row_idx]; |
80 | str += row_idx > 0 ? ", (" : "(" ; |
81 | for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { |
82 | str += col_idx > 0 ? ", " : "" ; |
83 | str += list[col_idx]->ToString(); |
84 | } |
85 | str += ")" ; |
86 | } |
87 | str += "\n" ; |
88 | return str; |
89 | } |
90 | |
91 | } // namespace duckdb |
92 | |