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
9namespace duckdb {
10
11ValueRelation::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
26ValueRelation::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
33unique_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
40unique_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
68string ValueRelation::GetAlias() {
69 return alias;
70}
71
72const vector<ColumnDefinition> &ValueRelation::Columns() {
73 return columns;
74}
75
76string 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