1#include "duckdb/planner/binder.hpp"
2#include "duckdb/planner/tableref/bound_expressionlistref.hpp"
3#include "duckdb/parser/tableref/expressionlistref.hpp"
4#include "duckdb/planner/expression_binder/insert_binder.hpp"
5
6using namespace duckdb;
7using namespace std;
8
9unique_ptr<BoundTableRef> Binder::Bind(ExpressionListRef &expr) {
10 auto result = make_unique<BoundExpressionListRef>();
11 result->types = expr.expected_types;
12 result->names = expr.expected_names;
13 // bind value list
14 InsertBinder binder(*this, context);
15 binder.target_type = SQLType(SQLTypeId::INVALID);
16 for (idx_t list_idx = 0; list_idx < expr.values.size(); list_idx++) {
17 auto &expression_list = expr.values[list_idx];
18 if (result->names.size() == 0) {
19 // no names provided, generate them
20 for (idx_t val_idx = 0; val_idx < expression_list.size(); val_idx++) {
21 result->names.push_back("col" + to_string(val_idx));
22 }
23 }
24
25 vector<unique_ptr<Expression>> list;
26 if (result->types.size() == 0) {
27 // for the first list, we set the expected types as the types of these expressions
28 for (idx_t val_idx = 0; val_idx < expression_list.size(); val_idx++) {
29 SQLType result_type;
30 auto expr = binder.Bind(expression_list[val_idx], &result_type);
31 result->types.push_back(result_type);
32 list.push_back(move(expr));
33 }
34 } else {
35 // for subsequent lists, we apply the expected types we found in the first list
36 for (idx_t val_idx = 0; val_idx < expression_list.size(); val_idx++) {
37 binder.target_type = result->types[val_idx];
38 list.push_back(binder.Bind(expression_list[val_idx]));
39 }
40 }
41 result->values.push_back(move(list));
42 }
43 result->bind_index = GenerateTableIndex();
44 bind_context.AddGenericBinding(result->bind_index, expr.alias, result->names, result->types);
45 return move(result);
46}
47