forked from alibaba/AliSQL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunnest.cpp
More file actions
86 lines (69 loc) · 3.22 KB
/
unnest.cpp
File metadata and controls
86 lines (69 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "duckdb/function/table/range.hpp"
#include "duckdb/common/algorithm.hpp"
#include "duckdb/planner/expression/bound_reference_expression.hpp"
#include "duckdb/planner/expression/bound_unnest_expression.hpp"
#include "duckdb/execution/operator/projection/physical_unnest.hpp"
namespace duckdb {
struct UnnestBindData : public FunctionData {
explicit UnnestBindData(LogicalType input_type_p) : input_type(std::move(input_type_p)) {
}
LogicalType input_type;
public:
unique_ptr<FunctionData> Copy() const override {
return make_uniq<UnnestBindData>(input_type);
}
bool Equals(const FunctionData &other_p) const override {
auto &other = other_p.Cast<UnnestBindData>();
return input_type == other.input_type;
}
};
struct UnnestGlobalState : public GlobalTableFunctionState {
UnnestGlobalState() {
}
vector<unique_ptr<Expression>> select_list;
idx_t MaxThreads() const override {
return GlobalTableFunctionState::MAX_THREADS;
}
};
struct UnnestLocalState : public LocalTableFunctionState {
UnnestLocalState() {
}
unique_ptr<OperatorState> operator_state;
};
static unique_ptr<FunctionData> UnnestBind(ClientContext &context, TableFunctionBindInput &input,
vector<LogicalType> &return_types, vector<string> &names) {
if (input.input_table_types.size() != 1 || input.input_table_types[0].id() != LogicalTypeId::LIST) {
throw BinderException("UNNEST requires a single list as input");
}
return_types.push_back(ListType::GetChildType(input.input_table_types[0]));
names.push_back("unnest");
return make_uniq<UnnestBindData>(input.input_table_types[0]);
}
static unique_ptr<LocalTableFunctionState> UnnestLocalInit(ExecutionContext &context, TableFunctionInitInput &input,
GlobalTableFunctionState *global_state) {
auto &gstate = global_state->Cast<UnnestGlobalState>();
auto result = make_uniq<UnnestLocalState>();
result->operator_state = PhysicalUnnest::GetState(context, gstate.select_list);
return std::move(result);
}
static unique_ptr<GlobalTableFunctionState> UnnestInit(ClientContext &context, TableFunctionInitInput &input) {
auto &bind_data = input.bind_data->Cast<UnnestBindData>();
auto result = make_uniq<UnnestGlobalState>();
auto ref = make_uniq<BoundReferenceExpression>(bind_data.input_type, 0U);
auto bound_unnest = make_uniq<BoundUnnestExpression>(ListType::GetChildType(bind_data.input_type));
bound_unnest->child = std::move(ref);
result->select_list.push_back(std::move(bound_unnest));
return std::move(result);
}
static OperatorResultType UnnestFunction(ExecutionContext &context, TableFunctionInput &data_p, DataChunk &input,
DataChunk &output) {
auto &state = data_p.global_state->Cast<UnnestGlobalState>();
auto &lstate = data_p.local_state->Cast<UnnestLocalState>();
return PhysicalUnnest::ExecuteInternal(context, input, output, *lstate.operator_state, state.select_list, false);
}
void UnnestTableFunction::RegisterFunction(BuiltinFunctions &set) {
TableFunction unnest_function("unnest", {LogicalType::ANY}, nullptr, UnnestBind, UnnestInit, UnnestLocalInit);
unnest_function.in_out_function = UnnestFunction;
set.AddFunction(unnest_function);
}
} // namespace duckdb