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