blob: 6068c3e47d1590251405c95f64bcc2b82ef04e2d [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <glog/logging.h>
#include <ranges>
#include <set>
#include <string>
#include <utility>
#include <vector>
namespace doris {
class LambdaExecutionContext {
public:
struct Binding {
std::string name;
int column_position = -1;
};
struct Frame {
bool bind_by_name = true;
bool parent_bindings_visible = true;
std::vector<Binding> argument_bindings;
};
struct ResolveResult {
bool searched_named_scope = false;
bool found = false;
int column_position = -1;
};
class FrameGuard {
public:
FrameGuard(LambdaExecutionContext& context, Frame frame) : _context(&context) {
_context->push_frame(std::move(frame));
}
FrameGuard(FrameGuard&& other) = delete;
FrameGuard& operator=(FrameGuard&& other) = delete;
FrameGuard(const FrameGuard&) = delete;
FrameGuard& operator=(const FrameGuard&) = delete;
~FrameGuard() { release(); }
private:
void release() {
if (_context != nullptr) {
_context->pop_frame();
_context = nullptr;
}
}
LambdaExecutionContext* _context;
};
void push_frame(Frame frame) { _frames.push_back(std::move(frame)); }
void pop_frame() {
DCHECK(!_frames.empty());
_frames.pop_back();
}
ResolveResult resolve_column_position(const std::string& name) const {
ResolveResult result;
for (const auto& frame : std::ranges::reverse_view(_frames)) {
result.searched_named_scope |= frame.bind_by_name;
for (const auto& argument_binding :
std::ranges::reverse_view(frame.argument_bindings)) {
if (argument_binding.name == name) {
result.found = true;
result.column_position = argument_binding.column_position;
return result;
}
}
if (!frame.parent_bindings_visible) {
break;
}
}
return result;
}
void collect_visible_binding_column_positions(std::set<int>& column_positions) const {
for (const auto& _frame : std::ranges::reverse_view(_frames)) {
for (const auto& binding : _frame.argument_bindings) {
if (binding.column_position >= 0) {
column_positions.insert(binding.column_position);
}
}
if (!_frame.parent_bindings_visible) {
break;
}
}
}
private:
std::vector<Frame> _frames;
};
} // namespace doris