be/src/exprs/lambda_function/lambda_execution_context.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #pragma once |
19 | | |
20 | | #include <glog/logging.h> |
21 | | |
22 | | #include <ranges> |
23 | | #include <set> |
24 | | #include <string> |
25 | | #include <utility> |
26 | | #include <vector> |
27 | | |
28 | | namespace doris { |
29 | | |
30 | | class LambdaExecutionContext { |
31 | | public: |
32 | | struct Binding { |
33 | | std::string name; |
34 | | int column_position = -1; |
35 | | }; |
36 | | |
37 | | struct Frame { |
38 | | bool bind_by_name = true; |
39 | | bool parent_bindings_visible = true; |
40 | | std::vector<Binding> argument_bindings; |
41 | | }; |
42 | | |
43 | | struct ResolveResult { |
44 | | bool searched_named_scope = false; |
45 | | bool found = false; |
46 | | int column_position = -1; |
47 | | }; |
48 | | |
49 | | class FrameGuard { |
50 | | public: |
51 | 17 | FrameGuard(LambdaExecutionContext& context, Frame frame) : _context(&context) { |
52 | 17 | _context->push_frame(std::move(frame)); |
53 | 17 | } |
54 | | |
55 | | FrameGuard(FrameGuard&& other) = delete; |
56 | | FrameGuard& operator=(FrameGuard&& other) = delete; |
57 | | FrameGuard(const FrameGuard&) = delete; |
58 | | FrameGuard& operator=(const FrameGuard&) = delete; |
59 | | |
60 | 17 | ~FrameGuard() { release(); } |
61 | | |
62 | | private: |
63 | 17 | void release() { |
64 | 17 | if (_context != nullptr) { |
65 | 17 | _context->pop_frame(); |
66 | 17 | _context = nullptr; |
67 | 17 | } |
68 | 17 | } |
69 | | |
70 | | LambdaExecutionContext* _context; |
71 | | }; |
72 | | |
73 | 17 | void push_frame(Frame frame) { _frames.push_back(std::move(frame)); } |
74 | | |
75 | 17 | void pop_frame() { |
76 | 17 | DCHECK(!_frames.empty()); |
77 | 17 | _frames.pop_back(); |
78 | 17 | } |
79 | | |
80 | 24 | ResolveResult resolve_column_position(const std::string& name) const { |
81 | 24 | ResolveResult result; |
82 | 28 | for (const auto& frame : std::ranges::reverse_view(_frames)) { |
83 | 28 | result.searched_named_scope |= frame.bind_by_name; |
84 | 28 | for (const auto& argument_binding : |
85 | 28 | std::ranges::reverse_view(frame.argument_bindings)) { |
86 | 24 | if (argument_binding.name == name) { |
87 | 16 | result.found = true; |
88 | 16 | result.column_position = argument_binding.column_position; |
89 | 16 | return result; |
90 | 16 | } |
91 | 24 | } |
92 | 12 | if (!frame.parent_bindings_visible) { |
93 | 4 | break; |
94 | 4 | } |
95 | 12 | } |
96 | 8 | return result; |
97 | 24 | } |
98 | | |
99 | 16 | void collect_visible_binding_column_positions(std::set<int>& column_positions) const { |
100 | 16 | for (const auto& _frame : std::ranges::reverse_view(_frames)) { |
101 | 9 | for (const auto& binding : _frame.argument_bindings) { |
102 | 9 | if (binding.column_position >= 0) { |
103 | 9 | column_positions.insert(binding.column_position); |
104 | 9 | } |
105 | 9 | } |
106 | 8 | if (!_frame.parent_bindings_visible) { |
107 | 0 | break; |
108 | 0 | } |
109 | 8 | } |
110 | 16 | } |
111 | | |
112 | | private: |
113 | | std::vector<Frame> _frames; |
114 | | }; |
115 | | |
116 | | } // namespace doris |