diff --git a/mysql-test/suite/tianmu/r/out_of_range_issue1151.result b/mysql-test/suite/tianmu/r/out_of_range_issue1151.result index 9e10f9fa8..ab21f7b17 100644 --- a/mysql-test/suite/tianmu/r/out_of_range_issue1151.result +++ b/mysql-test/suite/tianmu/r/out_of_range_issue1151.result @@ -1,5 +1,4 @@ drop database if exists out_of_range_issue1151; -create database test; create database out_of_range_issue1151; use out_of_range_issue1151; create table tiny(a tinyint, b tinyint unsigned) engine = tianmu DEFAULT CHARSET=utf8mb4; diff --git a/storage/tianmu/common/common_definitions.cpp b/storage/tianmu/common/common_definitions.cpp index 2745ca006..7bcf659aa 100644 --- a/storage/tianmu/common/common_definitions.cpp +++ b/storage/tianmu/common/common_definitions.cpp @@ -16,6 +16,7 @@ */ #include "common_definitions.h" +#include "exception.h" #include #include @@ -40,47 +41,58 @@ void PushWarningIfOutOfRange(THD *thd, std::string col_name, int64_t v, int type if (unsigned_flag && (static_cast(v) > TIANMU_TINYINT_MAX)) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, 0, TIANMU_TINYINT_MAX, unsigned_flag, v).c_str()); - throw std::exception(); + throw common::OutOfRangeException(getErrMsg(col_name, 0, TIANMU_TINYINT_MAX, unsigned_flag, v)); } else if (v > TIANMU_TINYINT_MAX || v < TIANMU_TINYINT_MIN) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, TIANMU_TINYINT_MIN, TIANMU_TINYINT_MAX, unsigned_flag, v).c_str()); - throw std::exception(); + throw common::OutOfRangeException( + getErrMsg(col_name, TIANMU_TINYINT_MIN, TIANMU_TINYINT_MAX, unsigned_flag, v)); } } break; case 2: { // MYSQL_TYPE_SHORT if (unsigned_flag && (static_cast(v) > TIANMU_SMALLINT_MAX)) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, 0, TIANMU_SMALLINT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException(getErrMsg(col_name, 0, TIANMU_SMALLINT_MAX, unsigned_flag, v)); } else if (v > TIANMU_SMALLINT_MAX || v < TIANMU_SMALLINT_MIN) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, TIANMU_SMALLINT_MIN, TIANMU_SMALLINT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException( + getErrMsg(col_name, TIANMU_SMALLINT_MIN, TIANMU_SMALLINT_MAX, unsigned_flag, v)); }; } break; case 9: { // MYSQL_TYPE_INT24 if (unsigned_flag && (static_cast(v) > TIANMU_MEDIUMINT_MAX)) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, 0, TIANMU_MEDIUMINT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException(getErrMsg(col_name, 0, TIANMU_MEDIUMINT_MAX, unsigned_flag, v)); } else if (v > TIANMU_MEDIUMINT_MAX || v < TIANMU_MEDIUMINT_MIN) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, TIANMU_MEDIUMINT_MIN, TIANMU_MEDIUMINT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException( + getErrMsg(col_name, TIANMU_MEDIUMINT_MIN, TIANMU_MEDIUMINT_MAX, unsigned_flag, v)); } } break; case 3: { // MYSQL_TYPE_LONG if (unsigned_flag && (static_cast(v) > TIANMU_INT_MAX)) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, 0, TIANMU_INT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException(getErrMsg(col_name, 0, TIANMU_INT_MAX, unsigned_flag, v)); } else if (v > TIANMU_INT_MAX || v < TIANMU_INT_MIN) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, TIANMU_INT_MIN, TIANMU_INT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException(getErrMsg(col_name, TIANMU_INT_MIN, TIANMU_INT_MAX, unsigned_flag, v)); } } break; case 8: { // MYSQL_TYPE_LONGLONG if (unsigned_flag && (static_cast(v) > TIANMU_BIGINT_MAX)) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, 0, TIANMU_BIGINT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException(getErrMsg(col_name, 0, TIANMU_BIGINT_MAX, unsigned_flag, v)); } else if (v > TIANMU_BIGINT_MAX || v < TIANMU_BIGINT_MIN) { PushWarning(thd, Sql_condition::SL_WARNING, ER_WARN_DATA_OUT_OF_RANGE, getErrMsg(col_name, TIANMU_BIGINT_MIN, TIANMU_BIGINT_MAX, unsigned_flag, v).c_str()); + throw common::OutOfRangeException(getErrMsg(col_name, TIANMU_BIGINT_MIN, TIANMU_BIGINT_MAX, unsigned_flag, v)); } } break; default: // For type which is not integer, nothing to do diff --git a/storage/tianmu/common/exception.h b/storage/tianmu/common/exception.h index c70ac6c79..b3b4b0a9f 100644 --- a/storage/tianmu/common/exception.h +++ b/storage/tianmu/common/exception.h @@ -217,6 +217,11 @@ class AutoIncException : public Exception { AutoIncException(std::string const &msg) : Exception(msg) {} }; +class OutOfRangeException : public Exception { + public: + OutOfRangeException(std::string const &msg) : Exception(msg) {} +}; + } // namespace common } // namespace Tianmu diff --git a/storage/tianmu/core/engine.cpp b/storage/tianmu/core/engine.cpp index d23a25f40..886e5683b 100644 --- a/storage/tianmu/core/engine.cpp +++ b/storage/tianmu/core/engine.cpp @@ -1478,11 +1478,18 @@ int Engine::InsertRow(const std::string &table_path, [[maybe_unused]] Transactio ret = rct->Insert(table); } return ret; + } catch (common::OutOfRangeException &e) { + TIANMU_LOG(LogCtl_Level::ERROR, "inserting data out of range. %s %s", e.what(), e.trace().c_str()); + // in strict sql_mode, we should return error no. + // TODO: in the future, we'll support insert success with warning in strict sql_mode, currently the data is + // not write into data file, refs crashed issue: https://github.com/stoneatom/stonedb/issues/1716 + if (trans_->Thd()->is_strict_mode()) { + ret = 1; + } } catch (common::Exception &e) { TIANMU_LOG(LogCtl_Level::ERROR, "delayed inserting failed. %s %s", e.what(), e.trace().c_str()); } catch (std::exception &e) { TIANMU_LOG(LogCtl_Level::ERROR, "delayed inserting failed. %s", e.what()); - ret = 1; } catch (...) { TIANMU_LOG(LogCtl_Level::ERROR, "delayed inserting failed."); }