Skip to content
Merged
1 change: 1 addition & 0 deletions be/src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ add_library(Common STATIC
resource_tls.cpp
logconfig.cpp
configbase.cpp
exception.cpp
)

# Generate env_config.h according to env_config.h.in
Expand Down
41 changes: 41 additions & 0 deletions be/src/common/exception.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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.

#include "common/exception.h"

#include "util/stack_util.h"
namespace doris {

Exception::Exception(int code, const std::string_view msg) {
_code = code;
_err_msg = std::make_unique<ErrMsg>();
_err_msg->_msg = msg;
_err_msg->_stack = get_stack_trace();
}
Exception::Exception(const Exception& nested, int code, const std::string_view msg) {
_code = code;
_err_msg = std::make_unique<ErrMsg>();
_err_msg->_msg = msg;
_err_msg->_stack = get_stack_trace();
_nested_excption = std::make_unique<Exception>();
_nested_excption->_code = nested._code;
_nested_excption->_err_msg = std::make_unique<ErrMsg>();
_nested_excption->_err_msg->_msg = nested._err_msg->_msg;
_nested_excption->_err_msg->_stack = nested._err_msg->_stack;
}

} // namespace doris
76 changes: 76 additions & 0 deletions be/src/common/exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// 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 "common/status.h"

namespace doris {

class Exception : public std::exception {
public:
Exception() : _code(ErrorCode::OK) {}
Exception(int code, const std::string_view msg);
// add nested exception as first param, or the template may could not find
// the correct method for ...args
Exception(const Exception& nested, int code, const std::string_view msg);

// Format message with fmt::format, like the logging functions.
template <typename... Args>
Exception(int code, const std::string_view fmt, Args&&... args)
: Exception(code, fmt::format(fmt, std::forward<Args>(args)...)) {}

std::string code_as_string() const {
return (int)_code >= 0 ? doris::to_string(static_cast<TStatusCode::type>(_code))
: fmt::format("E{}", (int16_t)_code);
}

int code() const { return _code; }

std::string to_string() const;

friend std::ostream& operator<<(std::ostream& ostr, const Exception& exp);

private:
int _code;
struct ErrMsg {
std::string _msg;
std::string _stack;
};
std::unique_ptr<ErrMsg> _err_msg;
std::unique_ptr<Exception> _nested_excption;
};

inline std::ostream& operator<<(std::ostream& ostr, const Exception& exp) {
ostr << '[' << exp.code_as_string() << "] ";
ostr << (exp._err_msg ? exp._err_msg->_msg : "");
if (exp._err_msg && !exp._err_msg->_stack.empty()) {
ostr << '\n' << exp._err_msg->_stack;
}
if (exp._nested_excption != nullptr) {
ostr << '\n' << "Caused by:" << *exp._nested_excption;
}
return ostr;
}

inline std::string Exception::to_string() const {
std::stringstream ss;
ss << *this;
return ss.str();
}

} // namespace doris
13 changes: 1 addition & 12 deletions be/src/vec/exprs/table_function/vexplode_bitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ VExplodeBitmapTableFunction::VExplodeBitmapTableFunction() {
_fn_name = "vexplode_bitmap";
}

VExplodeBitmapTableFunction::~VExplodeBitmapTableFunction() {
if (_cur_iter != nullptr) {
delete _cur_iter;
_cur_iter = nullptr;
}
}

Status VExplodeBitmapTableFunction::process_init(vectorized::Block* block) {
CHECK(_vexpr_context->root()->children().size() == 1)
<< "VExplodeNumbersTableFunction must be have 1 children but have "
Expand Down Expand Up @@ -84,11 +77,7 @@ Status VExplodeBitmapTableFunction::get_value(void** output) {

void VExplodeBitmapTableFunction::_reset_iterator() {
DCHECK(_cur_bitmap->cardinality() > 0) << _cur_bitmap->cardinality();
if (_cur_iter != nullptr) {
delete _cur_iter;
_cur_iter = nullptr;
}
_cur_iter = new BitmapValueIterator(*_cur_bitmap);
_cur_iter.reset(new BitmapValueIterator(*_cur_bitmap));
_cur_value = **_cur_iter;
_cur_offset = 0;
}
Expand Down
6 changes: 3 additions & 3 deletions be/src/vec/exprs/table_function/vexplode_bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace doris::vectorized {
class VExplodeBitmapTableFunction final : public TableFunction {
public:
VExplodeBitmapTableFunction();
~VExplodeBitmapTableFunction() override;
~VExplodeBitmapTableFunction() override = default;

Status reset() override;
Status get_value(void** output) override;
Expand All @@ -39,10 +39,10 @@ class VExplodeBitmapTableFunction final : public TableFunction {

private:
void _reset_iterator();

// Not own object, just a reference
const BitmapValue* _cur_bitmap = nullptr;
// iterator of _cur_bitmap
BitmapValueIterator* _cur_iter = nullptr;
std::unique_ptr<BitmapValueIterator> _cur_iter = nullptr;
// current value read from bitmap, it will be referenced by
// table function scan node.
uint64_t _cur_value = 0;
Expand Down
1 change: 1 addition & 0 deletions be/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(COMMON_TEST_FILES
common/resource_tls_test.cpp
common/status_test.cpp
common/config_test.cpp
common/exception_test.cpp
)
set(ENV_TEST_FILES
env/env_posix_test.cpp
Expand Down
60 changes: 60 additions & 0 deletions be/test/common/exception_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// 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.

#include "common/exception.h"

#include <gtest/gtest.h>

#include <iostream>
#include <string>

namespace doris {

class ExceptionTest : public testing::Test {};

TEST_F(ExceptionTest, OK) {
// default
try {
throw doris::Exception();
} catch (doris::Exception& e) {
EXPECT_TRUE(e.code() == ErrorCode::OK);
}
}

TEST_F(ExceptionTest, SingleError) {
try {
throw doris::Exception(ErrorCode::OS_ERROR, "test OS_ERROR {}", "bug");
} catch (doris::Exception& e) {
EXPECT_TRUE(e.to_string().find("OS_ERROR") != std::string::npos);
}
}

TEST_F(ExceptionTest, NestedError) {
try {
throw doris::Exception(ErrorCode::OS_ERROR, "test OS_ERROR {}", "bug");
} catch (doris::Exception& e1) {
EXPECT_TRUE(e1.to_string().find("OS_ERROR") != std::string::npos);
try {
throw doris::Exception(e1, ErrorCode::INVALID_ARGUMENT, "test INVALID_ARGUMENT");
} catch (doris::Exception& e2) {
EXPECT_TRUE(e2.to_string().find("OS_ERROR") != std::string::npos);
EXPECT_TRUE(e2.to_string().find("INVALID_ARGUMENT") != std::string::npos);
}
}
}

} // namespace doris