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(ClientContext &context, vector<vector<Value>> values, vector<string> names_p,
12 string alias_p)
13 : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(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(
20 make_unique<ConstantExpression>(SQLTypeFromInternalType(list[col_idx].type), list[col_idx]));
21 }
22 this->expressions.push_back(move(expressions));
23 }
24 context.TryBindRelation(*this, this->columns);
25}
26
27ValueRelation::ValueRelation(ClientContext &context, string values_list, vector<string> names_p, string alias_p)
28 : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(move(alias_p)) {
29 this->expressions = Parser::ParseValuesList(values_list);
30 context.TryBindRelation(*this, this->columns);
31}
32
33unique_ptr<QueryNode> ValueRelation::GetQueryNode() {
34 auto result = make_unique<SelectNode>();
35 result->select_list.push_back(make_unique<StarExpression>());
36 result->from_table = GetTableRef();
37 return move(result);
38}
39
40unique_ptr<TableRef> ValueRelation::GetTableRef() {
41 auto table_ref = make_unique<ExpressionListRef>();
42 // set the expected types/names
43 if (columns.size() == 0) {
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(names[i]);
47 }
48 } else {
49 for (idx_t i = 0; i < columns.size(); i++) {
50 table_ref->expected_names.push_back(columns[i].name);
51 table_ref->expected_types.push_back(columns[i].type);
52 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 for (auto &expr : expr_list) {
59 copied_list.push_back(expr->Copy());
60 }
61 table_ref->values.push_back(move(copied_list));
62 }
63 table_ref->alias = GetAlias();
64 return move(table_ref);
65}
66
67string ValueRelation::GetAlias() {
68 return alias;
69}
70
71const vector<ColumnDefinition> &ValueRelation::Columns() {
72 return columns;
73}
74
75string ValueRelation::ToString(idx_t depth) {
76 string str = RenderWhitespace(depth) + "Values ";
77 for (idx_t row_idx = 0; row_idx < expressions.size(); row_idx++) {
78 auto &list = expressions[row_idx];
79 str += row_idx > 0 ? ", (" : "(";
80 for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) {
81 str += col_idx > 0 ? ", " : "";
82 str += list[col_idx]->ToString();
83 }
84 str += ")";
85 }
86 str += "\n";
87 return str;
88}
89
90} // namespace duckdb
91