提交 f0e34e03 编写于 作者: L leslieyuchen 提交者: LINGuanRen

add dml data strict defensive check

上级 bd258f93
...@@ -2956,13 +2956,13 @@ int ObObjCmpFuncs::compare(const ObObj& obj1, const ObObj& obj2, ObCollationType ...@@ -2956,13 +2956,13 @@ int ObObjCmpFuncs::compare(const ObObj& obj1, const ObObj& obj2, ObCollationType
obj_cmp_func cmp_func = NULL; obj_cmp_func cmp_func = NULL;
cmp = CR_EQ; cmp = CR_EQ;
if (OB_UNLIKELY(false == can_cmp_without_cast(obj1.get_meta(), obj2.get_meta(), CO_CMP, cmp_func))) { if (OB_UNLIKELY(false == can_cmp_without_cast(obj1.get_meta(), obj2.get_meta(), CO_CMP, cmp_func))) {
LOG_ERROR("obj1 and obj2 can't compare", K(obj1), K(obj2), K(obj1.get_meta()), K(obj2.get_meta()));
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("obj1 and obj2 can't compare", K(obj1), K(obj2), K(obj1.get_meta()), K(obj2.get_meta()));
} else { } else {
ObCompareCtx cmp_ctx(ObMaxType, cs_type, true, INVALID_TZ_OFF, lib::is_oracle_mode() ? NULL_LAST : NULL_FIRST); ObCompareCtx cmp_ctx(ObMaxType, cs_type, true, INVALID_TZ_OFF, lib::is_oracle_mode() ? NULL_LAST : NULL_FIRST);
if (OB_UNLIKELY(CR_OB_ERROR == (cmp = cmp_func(obj1, obj2, cmp_ctx)))) { if (OB_UNLIKELY(CR_OB_ERROR == (cmp = cmp_func(obj1, obj2, cmp_ctx)))) {
LOG_ERROR("failed to compare obj1 and obj2", K(obj1), K(obj2), K(obj1.get_meta()), K(obj2.get_meta()));
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed to compare obj1 and obj2", K(obj1), K(obj2), K(obj1.get_meta()), K(obj2.get_meta()));
} }
} }
return ret; return ret;
......
...@@ -135,6 +135,11 @@ public: ...@@ -135,6 +135,11 @@ public:
} }
bool enable_static_engine_for_query() const; bool enable_static_engine_for_query() const;
bool enable_defensive_check() const
{
return _enable_defensive_check && lib::is_diagnose_info_enabled();
}
bool is_major_version_upgrade() const bool is_major_version_upgrade() const
{ {
return false; return false;
......
...@@ -3298,6 +3298,26 @@ static struct ObStrErrorInit ...@@ -3298,6 +3298,26 @@ static struct ObStrErrorInit
ORACLE_ERRNO[-OB_UNIMPLEMENTED_FEATURE] = 3001; ORACLE_ERRNO[-OB_UNIMPLEMENTED_FEATURE] = 3001;
ORACLE_STR_ERROR[-OB_UNIMPLEMENTED_FEATURE] = "ORA-03001: unimplemented feature"; ORACLE_STR_ERROR[-OB_UNIMPLEMENTED_FEATURE] = "ORA-03001: unimplemented feature";
ORACLE_STR_USER_ERROR[-OB_UNIMPLEMENTED_FEATURE] = "ORA-03001: unimplemented feature"; ORACLE_STR_USER_ERROR[-OB_UNIMPLEMENTED_FEATURE] = "ORA-03001: unimplemented feature";
ERROR_NAME[-OB_ERR_DEFENSIVE_CHECK] = "OB_ERR_DEFENSIVE_CHECK";
ERROR_CAUSE[-OB_ERR_DEFENSIVE_CHECK] = "Internal Error";
ERROR_SOLUTION[-OB_ERR_DEFENSIVE_CHECK] = "Contact OceanBase Support";
MYSQL_ERRNO[-OB_ERR_DEFENSIVE_CHECK] = -1;
SQLSTATE[-OB_ERR_DEFENSIVE_CHECK] = "HY000";
STR_ERROR[-OB_ERR_DEFENSIVE_CHECK] = "fatal internal error";
STR_USER_ERROR[-OB_ERR_DEFENSIVE_CHECK] = "fatal internal error in [%.*s]";
ORACLE_ERRNO[-OB_ERR_DEFENSIVE_CHECK] = 600;
ORACLE_STR_ERROR[-OB_ERR_DEFENSIVE_CHECK] = "ORA-00600: internal error code, arguments: -4377, fatal internal error";
ORACLE_STR_USER_ERROR[-OB_ERR_DEFENSIVE_CHECK] = "ORA-00600: internal error code, arguments: -4377, fatal internal error in [%.*s]";
ERROR_NAME[-OB_CLUSTER_NAME_HASH_CONFLICT] = "OB_CLUSTER_NAME_HASH_CONFLICT";
ERROR_CAUSE[-OB_CLUSTER_NAME_HASH_CONFLICT] = "Internal Error";
ERROR_SOLUTION[-OB_CLUSTER_NAME_HASH_CONFLICT] = "Contact OceanBase Support";
MYSQL_ERRNO[-OB_CLUSTER_NAME_HASH_CONFLICT] = -1;
SQLSTATE[-OB_CLUSTER_NAME_HASH_CONFLICT] = "HY000";
STR_ERROR[-OB_CLUSTER_NAME_HASH_CONFLICT] = "cluster name conflict";
STR_USER_ERROR[-OB_CLUSTER_NAME_HASH_CONFLICT] = "cluster name conflict";
ORACLE_ERRNO[-OB_CLUSTER_NAME_HASH_CONFLICT] = 600;
ORACLE_STR_ERROR[-OB_CLUSTER_NAME_HASH_CONFLICT] = "ORA-00600: internal error code, arguments: -4378, cluster name conflict";
ORACLE_STR_USER_ERROR[-OB_CLUSTER_NAME_HASH_CONFLICT] = "ORA-00600: internal error code, arguments: -4378, cluster name conflict";
ERROR_NAME[-OB_IMPORT_NOT_IN_SERVER] = "OB_IMPORT_NOT_IN_SERVER"; ERROR_NAME[-OB_IMPORT_NOT_IN_SERVER] = "OB_IMPORT_NOT_IN_SERVER";
ERROR_CAUSE[-OB_IMPORT_NOT_IN_SERVER] = "Internal Error"; ERROR_CAUSE[-OB_IMPORT_NOT_IN_SERVER] = "Internal Error";
ERROR_SOLUTION[-OB_IMPORT_NOT_IN_SERVER] = "Contact OceanBase Support"; ERROR_SOLUTION[-OB_IMPORT_NOT_IN_SERVER] = "Contact OceanBase Support";
...@@ -421,6 +421,7 @@ DEFINE_ERROR(OB_OBCONFIG_CLUSTER_NOT_EXIST, -4368, -1, "HY000", "cluster not exi ...@@ -421,6 +421,7 @@ DEFINE_ERROR(OB_OBCONFIG_CLUSTER_NOT_EXIST, -4368, -1, "HY000", "cluster not exi
DEFINE_ORACLE_ERROR(OB_ERR_VALUE_LARGER_THAN_ALLOWED, -4374, -1, "HY000", "value larger than specified precision allowed for this column", 1438, "value larger than specified precision allowed for this column"); DEFINE_ORACLE_ERROR(OB_ERR_VALUE_LARGER_THAN_ALLOWED, -4374, -1, "HY000", "value larger than specified precision allowed for this column", 1438, "value larger than specified precision allowed for this column");
DEFINE_ERROR(OB_DISK_ERROR, -4375, -1, "HY000", "observer has disk error"); DEFINE_ERROR(OB_DISK_ERROR, -4375, -1, "HY000", "observer has disk error");
DEFINE_ORACLE_ERROR(OB_UNIMPLEMENTED_FEATURE, -4376, -1, "HY000", "unimplemented feature", 3001, "unimplemented feature"); DEFINE_ORACLE_ERROR(OB_UNIMPLEMENTED_FEATURE, -4376, -1, "HY000", "unimplemented feature", 3001, "unimplemented feature");
DEFINE_ERROR_EXT(OB_ERR_DEFENSIVE_CHECK, -4377, -1, "HY000", "fatal internal error", "fatal internal error in [%.*s]");
DEFINE_ERROR(OB_CLUSTER_NAME_HASH_CONFLICT, -4378, -1, "HY000", "cluster name conflict"); DEFINE_ERROR(OB_CLUSTER_NAME_HASH_CONFLICT, -4378, -1, "HY000", "cluster name conflict");
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
......
...@@ -235,6 +235,8 @@ constexpr int OB_OBCONFIG_CLUSTER_NOT_EXIST = -4368; ...@@ -235,6 +235,8 @@ constexpr int OB_OBCONFIG_CLUSTER_NOT_EXIST = -4368;
constexpr int OB_ERR_VALUE_LARGER_THAN_ALLOWED = -4374; constexpr int OB_ERR_VALUE_LARGER_THAN_ALLOWED = -4374;
constexpr int OB_DISK_ERROR = -4375; constexpr int OB_DISK_ERROR = -4375;
constexpr int OB_UNIMPLEMENTED_FEATURE = -4376; constexpr int OB_UNIMPLEMENTED_FEATURE = -4376;
constexpr int OB_ERR_DEFENSIVE_CHECK = -4377;
constexpr int OB_CLUSTER_NAME_HASH_CONFLICT = -4378;
constexpr int OB_IMPORT_NOT_IN_SERVER = -4505; constexpr int OB_IMPORT_NOT_IN_SERVER = -4505;
constexpr int OB_CONVERT_ERROR = -4507; constexpr int OB_CONVERT_ERROR = -4507;
constexpr int OB_BYPASS_TIMEOUT = -4510; constexpr int OB_BYPASS_TIMEOUT = -4510;
...@@ -1563,6 +1565,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; ...@@ -1563,6 +1565,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_VALUE_LARGER_THAN_ALLOWED__USER_ERROR_MSG "value larger than specified precision allowed for this column" #define OB_ERR_VALUE_LARGER_THAN_ALLOWED__USER_ERROR_MSG "value larger than specified precision allowed for this column"
#define OB_DISK_ERROR__USER_ERROR_MSG "observer has disk error" #define OB_DISK_ERROR__USER_ERROR_MSG "observer has disk error"
#define OB_UNIMPLEMENTED_FEATURE__USER_ERROR_MSG "unimplemented feature" #define OB_UNIMPLEMENTED_FEATURE__USER_ERROR_MSG "unimplemented feature"
#define OB_ERR_DEFENSIVE_CHECK__USER_ERROR_MSG "fatal internal error in [%.*s]"
#define OB_CLUSTER_NAME_HASH_CONFLICT__USER_ERROR_MSG "cluster name conflict"
#define OB_IMPORT_NOT_IN_SERVER__USER_ERROR_MSG "Import not in service" #define OB_IMPORT_NOT_IN_SERVER__USER_ERROR_MSG "Import not in service"
#define OB_CONVERT_ERROR__USER_ERROR_MSG "Convert error" #define OB_CONVERT_ERROR__USER_ERROR_MSG "Convert error"
#define OB_BYPASS_TIMEOUT__USER_ERROR_MSG "Bypass timeout" #define OB_BYPASS_TIMEOUT__USER_ERROR_MSG "Bypass timeout"
...@@ -2991,6 +2995,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; ...@@ -2991,6 +2995,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_VALUE_LARGER_THAN_ALLOWED__ORA_USER_ERROR_MSG "ORA-01438: value larger than specified precision allowed for this column" #define OB_ERR_VALUE_LARGER_THAN_ALLOWED__ORA_USER_ERROR_MSG "ORA-01438: value larger than specified precision allowed for this column"
#define OB_DISK_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4375, observer has disk error" #define OB_DISK_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4375, observer has disk error"
#define OB_UNIMPLEMENTED_FEATURE__ORA_USER_ERROR_MSG "ORA-03001: unimplemented feature" #define OB_UNIMPLEMENTED_FEATURE__ORA_USER_ERROR_MSG "ORA-03001: unimplemented feature"
#define OB_ERR_DEFENSIVE_CHECK__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4377, fatal internal error in [%.*s]"
#define OB_CLUSTER_NAME_HASH_CONFLICT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4378, cluster name conflict"
#define OB_IMPORT_NOT_IN_SERVER__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4505, Import not in service" #define OB_IMPORT_NOT_IN_SERVER__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4505, Import not in service"
#define OB_CONVERT_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4507, Convert error" #define OB_CONVERT_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4507, Convert error"
#define OB_BYPASS_TIMEOUT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4510, Bypass timeout" #define OB_BYPASS_TIMEOUT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4510, Bypass timeout"
......
...@@ -275,6 +275,10 @@ DEF_BOOL(_enable_static_typing_engine, OB_CLUSTER_PARAMETER, "True", ...@@ -275,6 +275,10 @@ DEF_BOOL(_enable_static_typing_engine, OB_CLUSTER_PARAMETER, "True",
"specifies whether static typing sql execution engine is activated", "specifies whether static typing sql execution engine is activated",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
// https://yuque.antfin-inc.com/ob/product_functionality_review/zlp56c
DEF_BOOL(_enable_defensive_check, OB_CLUSTER_PARAMETER, "True",
"specifies whether allow to do some defensive checks when the query is executed",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
//// tenant config //// tenant config
DEF_TIME_WITH_CHECKER(max_stale_time_for_weak_consistency, OB_TENANT_PARAMETER, "5s", common::ObConfigStaleTimeChecker, DEF_TIME_WITH_CHECKER(max_stale_time_for_weak_consistency, OB_TENANT_PARAMETER, "5s", common::ObConfigStaleTimeChecker,
"[5s,)", "[5s,)",
......
...@@ -31,9 +31,14 @@ ObTableSchemaParam::ObTableSchemaParam(ObIAllocator& allocator) ...@@ -31,9 +31,14 @@ ObTableSchemaParam::ObTableSchemaParam(ObIAllocator& allocator)
fulltext_col_id_(OB_INVALID_ID), fulltext_col_id_(OB_INVALID_ID),
index_name_(), index_name_(),
columns_(allocator), columns_(allocator),
col_descs_(allocator),
col_map_(allocator), col_map_(allocator),
projector_(allocator),
is_dropped_schema_(false), is_dropped_schema_(false),
pk_name_() pk_name_(),
full_col_descs_(allocator),
full_col_map_(allocator),
full_projector_(allocator)
{} {}
ObTableSchemaParam::~ObTableSchemaParam() ObTableSchemaParam::~ObTableSchemaParam()
...@@ -54,8 +59,12 @@ void ObTableSchemaParam::reset() ...@@ -54,8 +59,12 @@ void ObTableSchemaParam::reset()
index_name_.reset(); index_name_.reset();
columns_.reset(); columns_.reset();
col_map_.clear(); col_map_.clear();
projector_.reset();
is_dropped_schema_ = false; is_dropped_schema_ = false;
pk_name_.reset(); pk_name_.reset();
full_col_descs_.reset();
full_col_map_.clear();
full_projector_.reset();
} }
int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint64_t>& col_ids) int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint64_t>& col_ids)
...@@ -63,7 +72,8 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint ...@@ -63,7 +72,8 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
static const int64_t COMMON_COLUMN_NUM = 16; static const int64_t COMMON_COLUMN_NUM = 16;
ObSEArray<ObColumnParam*, COMMON_COLUMN_NUM> tmp_cols; ObSEArray<ObColumnParam*, COMMON_COLUMN_NUM> tmp_cols;
ObSEArray<ObColDesc, COMMON_COLUMN_NUM> column_ids_no_virtual; ObSEArray<ObColDesc, COMMON_COLUMN_NUM> all_column_ids;
ObSEArray<ObColDesc, COMMON_COLUMN_NUM> tmp_col_descs;
if (OB_ISNULL(schema)) { if (OB_ISNULL(schema)) {
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
...@@ -100,19 +110,19 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint ...@@ -100,19 +110,19 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (OB_FAIL(schema->get_column_ids(column_ids_no_virtual, false))) { if (OB_FAIL(schema->get_column_ids(all_column_ids, false))) {
LOG_WARN("fail to get column ids", K(ret)); LOG_WARN("fail to get column ids", K(ret));
} }
for (int32_t i = 0; OB_SUCC(ret) && i < column_ids_no_virtual.count(); ++i) { for (int32_t i = 0; OB_SUCC(ret) && i < all_column_ids.count(); ++i) {
const uint64_t column_id = column_ids_no_virtual.at(i).col_id_; const uint64_t column_id = all_column_ids.at(i).col_id_;
const ObColumnSchemaV2* column_schema = NULL; const ObColumnSchemaV2 *column_schema = NULL;
ObColumnParam* column = NULL; ObColumnParam *column = NULL;
if (OB_ISNULL(column_schema = schema->get_column_schema(column_id))) { if (OB_ISNULL(column_schema = schema->get_column_schema(column_id))) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("The column is NULL", K(schema->get_table_id()), K(column_id), K(i)); LOG_WARN("The column is NULL", K(schema->get_table_id()), K(column_id), K(i));
} else if (column_schema->is_rowid_pseudo_column() && !has_exist_in_array(col_ids, column_id)) { } else if (column_schema->is_rowid_pseudo_column() && !has_exist_in_array(col_ids, column_id)) {
// ignore rowid, because storage donot store rowid column // ignore rowid, because storage do not store rowid column
// eg: create table t1(c1 int); // eg: create table t1(c1 int);
// delete from t1; // delete from t1;
// table dml param only need c1 // table dml param only need c1
...@@ -123,8 +133,10 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint ...@@ -123,8 +133,10 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint
LOG_WARN("alloc column failed", K(ret), K(i)); LOG_WARN("alloc column failed", K(ret), K(i));
} else if (OB_FAIL(ObTableParam::convert_column_schema_to_param(*column_schema, *column))) { } else if (OB_FAIL(ObTableParam::convert_column_schema_to_param(*column_schema, *column))) {
LOG_WARN("convert failed", K(*column_schema), K(ret), K(i)); LOG_WARN("convert failed", K(*column_schema), K(ret), K(i));
} else { } else if (OB_FAIL(tmp_cols.push_back(column))) {
ret = tmp_cols.push_back(column); LOG_WARN("store tmp column param failed", K(ret));
} else if (OB_FAIL(tmp_col_descs.push_back(all_column_ids.at(i)))) {
LOG_WARN("store tmp column desc failed", K(ret));
} }
} }
} }
...@@ -133,8 +145,12 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint ...@@ -133,8 +145,12 @@ int ObTableSchemaParam::convert(const ObTableSchema* schema, const ObIArray<uint
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (OB_FAIL(columns_.assign(tmp_cols))) { if (OB_FAIL(columns_.assign(tmp_cols))) {
LOG_WARN("assign failed", K(ret), K(tmp_cols.count())); LOG_WARN("assign failed", K(ret), K(tmp_cols.count()));
} else if (OB_FAIL(col_descs_.assign(tmp_col_descs))) {
LOG_WARN("assign tmp col descs failed", K(ret));
} else if (OB_FAIL(ObTableParam::create_column_map(columns_, col_map_))) { } else if (OB_FAIL(ObTableParam::create_column_map(columns_, col_map_))) {
LOG_WARN("failed to create column map", K(ret)); LOG_WARN("failed to create column map", K(ret));
} else if (OB_FAIL(prepare_full_column_param(*schema))) {
LOG_WARN("prepare full column param failed", K(ret));
} }
} }
return ret; return ret;
...@@ -230,7 +246,27 @@ int ObTableSchemaParam::get_rowkey_column_ids(ObIArray<ObColDesc>& column_ids) c ...@@ -230,7 +246,27 @@ int ObTableSchemaParam::get_rowkey_column_ids(ObIArray<ObColDesc>& column_ids) c
return ret; return ret;
} }
int ObTableSchemaParam::get_index_name(common::ObString& index_name) const int ObTableSchemaParam::get_rowkey_column_ids(ObIArray<uint64_t> &column_ids) const
{
int ret = OB_SUCCESS;
if (!is_valid()) {
ret = OB_NOT_INIT;
LOG_WARN("param not inited", K(ret), K(*this));
} else {
const ObColumnParam *param = NULL;
for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_column_num_; ++i) {
if (OB_ISNULL(param = columns_.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column param is NULL", K(ret), K(i));
} else if (OB_FAIL(column_ids.push_back(param->get_column_id()))) {
LOG_WARN("Fail to add rowkey column id to column_ids", K(ret));
}
}
}
return ret;
}
int ObTableSchemaParam::get_index_name(common::ObString &index_name) const
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (!is_index_table()) { if (!is_index_table()) {
...@@ -258,7 +294,40 @@ bool ObTableSchemaParam::is_depend_column(uint64_t column_id) const ...@@ -258,7 +294,40 @@ bool ObTableSchemaParam::is_depend_column(uint64_t column_id) const
return is_depend; return is_depend;
} }
int64_t ObTableSchemaParam::to_string(char* buf, const int64_t buf_len) const int ObTableSchemaParam::prepare_full_column_param(const ObTableSchema &table_schema)
{
int ret = OB_SUCCESS;
static const int64_t COMMON_COLUMN_NUM = 16;
ObSEArray<ObColDesc, COMMON_COLUMN_NUM> all_column_ids;
if (OB_FAIL(table_schema.get_column_ids(all_column_ids, !table_schema.is_index_table()))) {
LOG_WARN("get column ids from table schema failed", K(ret));
} else if (OB_FAIL(full_col_descs_.assign(all_column_ids))) {
LOG_WARN("assign full column descs failed", K(ret), K(all_column_ids));
} else if (OB_FAIL(full_col_map_.init(full_col_descs_))) {
LOG_WARN("init full column map failed", K(ret));
} else {
full_projector_.set_capacity(full_col_descs_.count());
projector_.set_capacity(columns_.count());
}
for (int64_t i = 0; OB_SUCC(ret) && i < full_col_descs_.count(); ++i) {
if (OB_FAIL(full_projector_.push_back(i))) {
LOG_WARN("init full projector failed", K(ret));
}
}
for (int64_t i = 0; OB_SUCC(ret) && i < columns_.count(); ++i) {
int idx = OB_INVALID_INDEX;
const ObColumnParam *col = columns_.at(i);
if (OB_FAIL(full_col_map_.get(col->get_column_id(), idx))) {
LOG_WARN("get column index from full column map failed", K(ret));
} else if (OB_FAIL(projector_.push_back(idx))) {
LOG_WARN("store projector failed", K(ret));
}
}
return ret;
}
int64_t ObTableSchemaParam::to_string(char *buf, const int64_t buf_len) const
{ {
int64_t pos = 0; int64_t pos = 0;
J_OBJ_START(); J_OBJ_START();
...@@ -272,8 +341,10 @@ int64_t ObTableSchemaParam::to_string(char* buf, const int64_t buf_len) const ...@@ -272,8 +341,10 @@ int64_t ObTableSchemaParam::to_string(char* buf, const int64_t buf_len) const
K_(fulltext_col_id), K_(fulltext_col_id),
K_(index_name), K_(index_name),
K_(pk_name), K_(pk_name),
"columns", K_(columns),
ObArrayWrap<ObColumnParam*>(0 == columns_.count() ? NULL : &columns_.at(0), columns_.count())); K_(projector),
K_(full_col_descs),
K_(full_projector));
J_OBJ_END(); J_OBJ_END();
return pos; return pos;
} }
...@@ -304,6 +375,10 @@ OB_DEF_SERIALIZE(ObTableSchemaParam) ...@@ -304,6 +375,10 @@ OB_DEF_SERIALIZE(ObTableSchemaParam)
LOG_WARN("failed to serialize pk name", K(ret)); LOG_WARN("failed to serialize pk name", K(ret));
} }
} }
OB_UNIS_ENCODE(col_descs_);
OB_UNIS_ENCODE(projector_);
OB_UNIS_ENCODE(full_col_descs_);
OB_UNIS_ENCODE(full_projector_);
return ret; return ret;
} }
...@@ -343,6 +418,15 @@ OB_DEF_DESERIALIZE(ObTableSchemaParam) ...@@ -343,6 +418,15 @@ OB_DEF_DESERIALIZE(ObTableSchemaParam)
LOG_WARN("failed to copy pk name", K(ret), K(tmp_name)); LOG_WARN("failed to copy pk name", K(ret), K(tmp_name));
} }
} }
OB_UNIS_DECODE(col_descs_);
OB_UNIS_DECODE(projector_);
OB_UNIS_DECODE(full_col_descs_);
OB_UNIS_DECODE(full_projector_);
if (OB_SUCC(ret) && !full_col_descs_.empty()) {
if (OB_FAIL(full_col_map_.init(full_col_descs_))) {
LOG_WARN("init full col map failed", K(ret));
}
}
return ret; return ret;
} }
...@@ -372,6 +456,10 @@ OB_DEF_SERIALIZE_SIZE(ObTableSchemaParam) ...@@ -372,6 +456,10 @@ OB_DEF_SERIALIZE_SIZE(ObTableSchemaParam)
} }
LST_DO_CODE(OB_UNIS_ADD_LEN, is_dropped_schema_); LST_DO_CODE(OB_UNIS_ADD_LEN, is_dropped_schema_);
len += pk_name_.get_serialize_size(); len += pk_name_.get_serialize_size();
OB_UNIS_ADD_LEN(col_descs_);
OB_UNIS_ADD_LEN(projector_);
OB_UNIS_ADD_LEN(full_col_descs_);
OB_UNIS_ADD_LEN(full_projector_);
return len; return len;
} }
...@@ -395,8 +483,6 @@ void ObTableDMLParam::reset() ...@@ -395,8 +483,6 @@ void ObTableDMLParam::reset()
tenant_schema_version_ = OB_INVALID_VERSION; tenant_schema_version_ = OB_INVALID_VERSION;
data_table_.reset(); data_table_.reset();
index_tables_.reset(); index_tables_.reset();
col_descs_.reset();
col_map_.clear();
} }
int ObTableDMLParam::convert(const ObTableSchema* table_schema, int ObTableDMLParam::convert(const ObTableSchema* table_schema,
...@@ -608,10 +694,10 @@ int ObTableDMLParam::prepare_storage_param(const ObIArray<uint64_t>& column_ids) ...@@ -608,10 +694,10 @@ int ObTableDMLParam::prepare_storage_param(const ObIArray<uint64_t>& column_ids)
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid column_ids", K(ret), K(col_cnt)); LOG_WARN("invalid column_ids", K(ret), K(col_cnt));
} else { } else {
ObSEArray<ObColDesc, common::OB_DEFAULT_COL_DEC_NUM> tmp_col_descs; const ObColumnParam *col_param = nullptr;
const ObColumnParam* col_param = nullptr;
uint64_t column_id = OB_INVALID_ID; uint64_t column_id = OB_INVALID_ID;
ObColDesc col_desc; ObColDesc col_desc;
col_descs_.set_capacity(col_cnt);
for (int64_t i = 0; OB_SUCC(ret) && i < col_cnt; ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < col_cnt; ++i) {
column_id = column_ids.at(i); column_id = column_ids.at(i);
if (nullptr == (col_param = data_table_.get_column(column_id))) { if (nullptr == (col_param = data_table_.get_column(column_id))) {
...@@ -621,7 +707,7 @@ int ObTableDMLParam::prepare_storage_param(const ObIArray<uint64_t>& column_ids) ...@@ -621,7 +707,7 @@ int ObTableDMLParam::prepare_storage_param(const ObIArray<uint64_t>& column_ids)
col_desc.col_id_ = column_id; col_desc.col_id_ = column_id;
col_desc.col_type_ = col_param->get_meta_type(); col_desc.col_type_ = col_param->get_meta_type();
col_desc.col_order_ = col_param->get_column_order(); col_desc.col_order_ = col_param->get_column_order();
if (OB_FAIL(tmp_col_descs.push_back(col_desc))) { if (OB_FAIL(col_descs_.push_back(col_desc))) {
LOG_WARN("fail to push back column description", K(ret), K(col_desc)); LOG_WARN("fail to push back column description", K(ret), K(col_desc));
} }
} }
...@@ -629,9 +715,7 @@ int ObTableDMLParam::prepare_storage_param(const ObIArray<uint64_t>& column_ids) ...@@ -629,9 +715,7 @@ int ObTableDMLParam::prepare_storage_param(const ObIArray<uint64_t>& column_ids)
// assign // assign
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (OB_FAIL(col_descs_.assign(tmp_col_descs))) { if (OB_FAIL(col_map_.init(col_descs_))) {
LOG_WARN("fail to assign column description array", K(ret));
} else if (OB_FAIL(col_map_.init(col_descs_))) {
LOG_WARN("fail to init column map", K(ret)); LOG_WARN("fail to init column map", K(ret));
} }
} }
......
...@@ -25,13 +25,16 @@ class ObTableSchemaParam { ...@@ -25,13 +25,16 @@ class ObTableSchemaParam {
OB_UNIS_VERSION_V(1); OB_UNIS_VERSION_V(1);
public: public:
typedef common::ObFixedArray<common::ObRowkeyInfo*, common::ObIAllocator> RowKeys; typedef common::ObFixedArray<common::ObRowkeyInfo *, common::ObIAllocator> RowKeys;
typedef common::ObFixedArray<ObColumnParam*, common::ObIAllocator> Columns; typedef common::ObFixedArray<ObColumnParam *, common::ObIAllocator> Columns;
typedef common::ObFixedArray<int32_t, common::ObIAllocator> Projector;
typedef common::ObFixedArray<ObColDesc, common::ObIAllocator> ObColDescArray;
explicit ObTableSchemaParam(common::ObIAllocator& allocator); explicit ObTableSchemaParam(common::ObIAllocator& allocator);
virtual ~ObTableSchemaParam(); virtual ~ObTableSchemaParam();
void reset(); void reset();
int convert(const ObTableSchema* schema, const common::ObIArray<uint64_t>& col_ids); int convert(const ObTableSchema *schema, const common::ObIArray<uint64_t> &col_ids);
int prepare_full_column_param(const ObTableSchema &table_schema);
OB_INLINE bool is_valid() const OB_INLINE bool is_valid() const
{ {
return common::OB_INVALID_ID != table_id_; return common::OB_INVALID_ID != table_id_;
...@@ -80,6 +83,18 @@ public: ...@@ -80,6 +83,18 @@ public:
{ {
return columns_.count(); return columns_.count();
} }
OB_INLINE const Columns &get_columns() const
{
return columns_;
}
OB_INLINE const ColumnMap &get_col_map() const
{
return col_map_;
}
OB_INLINE const ObColDescArray &get_col_descs() const
{
return col_descs_;
}
OB_INLINE bool is_index_table() const OB_INLINE bool is_index_table() const
{ {
return ObTableSchema::is_index_table(table_type_); return ObTableSchema::is_index_table(table_type_);
...@@ -107,13 +122,31 @@ public: ...@@ -107,13 +122,31 @@ public:
int is_rowkey_column(const uint64_t column_id, bool& is_rowkey) const; int is_rowkey_column(const uint64_t column_id, bool& is_rowkey) const;
int is_column_nullable(const uint64_t column_id, bool& is_nullable) const; int is_column_nullable(const uint64_t column_id, bool& is_nullable) const;
const ObColumnParam* get_column(const uint64_t column_id) const; const ObColumnParam *get_column(const uint64_t column_id) const;
const ObColumnParam* get_column_by_idx(const int64_t idx) const; const ObColumnParam *get_column_by_idx(const int64_t idx) const;
const ObColumnParam* get_rowkey_column_by_idx(const int64_t idx) const; const ObColumnParam *get_rowkey_column_by_idx(const int64_t idx) const;
int get_rowkey_column_ids(common::ObIArray<ObColDesc>& column_ids) const; int get_rowkey_column_ids(common::ObIArray<ObColDesc> &column_ids) const;
int get_index_name(common::ObString& index_name) const; int get_rowkey_column_ids(common::ObIArray<uint64_t> &column_ids) const;
const common::ObString& get_pk_name() const; int get_index_name(common::ObString &index_name) const;
const common::ObString &get_pk_name() const;
bool is_depend_column(uint64_t column_id) const; bool is_depend_column(uint64_t column_id) const;
OB_INLINE const Projector &get_projector() const
{
return projector_;
}
OB_INLINE const ObColDescArray &get_full_col_descs() const
{
return full_col_descs_;
}
OB_INLINE const ColumnMap &get_full_col_map() const
{
return full_col_map_;
}
OB_INLINE const Projector &get_full_projector() const
{
return full_projector_;
}
DECLARE_TO_STRING; DECLARE_TO_STRING;
private: private:
...@@ -132,9 +165,18 @@ private: ...@@ -132,9 +165,18 @@ private:
uint64_t fulltext_col_id_; uint64_t fulltext_col_id_;
common::ObString index_name_; common::ObString index_name_;
Columns columns_; Columns columns_;
// generated storage param from columns_ids_ in ObTableModify, for performance improvement
ObColDescArray col_descs_;
ColumnMap col_map_; ColumnMap col_map_;
// generated storage column projector from full column map, for performance improvement
Projector projector_; // all column projector without virtual column
bool is_dropped_schema_; bool is_dropped_schema_;
common::ObString pk_name_; // use for printing error msg in oracle mode common::ObString pk_name_; // use for printing error msg in oracle mode
// full column info, the purpose is that read operations in DML can use fuse row cache
ObColDescArray full_col_descs_; // all column descs without virtual column
ColumnMap full_col_map_; // all column map without virtual column
Projector full_projector_; // all column projector without virtual column
}; };
class ObTableDMLParam { class ObTableDMLParam {
......
...@@ -376,6 +376,9 @@ void ObColumnParam::reset() ...@@ -376,6 +376,9 @@ void ObColumnParam::reset()
orig_default_value_.reset(); orig_default_value_.reset();
cur_default_value_.reset(); cur_default_value_.reset();
is_nullable_ = false; is_nullable_ = false;
is_gen_col_ = false;
is_virtual_gen_col_ = false;
is_hidden_ = false;
} }
int ObColumnParam::deep_copy_obj(const ObObj& src, ObObj& dest) int ObColumnParam::deep_copy_obj(const ObObj& src, ObObj& dest)
...@@ -408,8 +411,17 @@ OB_DEF_SERIALIZE(ObColumnParam) ...@@ -408,8 +411,17 @@ OB_DEF_SERIALIZE(ObColumnParam)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
LST_DO_CODE( LST_DO_CODE(OB_UNIS_ENCODE,
OB_UNIS_ENCODE, column_id_, meta_type_, accuracy_, orig_default_value_, cur_default_value_, order_, is_nullable_); column_id_,
meta_type_,
accuracy_,
orig_default_value_,
cur_default_value_,
order_,
is_nullable_,
is_gen_col_,
is_virtual_gen_col_,
is_hidden_);
return ret; return ret;
} }
...@@ -431,6 +443,9 @@ OB_DEF_DESERIALIZE(ObColumnParam) ...@@ -431,6 +443,9 @@ OB_DEF_DESERIALIZE(ObColumnParam)
is_nullable_ = false; is_nullable_ = false;
} }
} }
OB_UNIS_DECODE(is_gen_col_);
OB_UNIS_DECODE(is_virtual_gen_col_);
OB_UNIS_DECODE(is_hidden_);
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (OB_FAIL(deep_copy_obj(orig_default_value, orig_default_value_))) { if (OB_FAIL(deep_copy_obj(orig_default_value, orig_default_value_))) {
...@@ -454,7 +469,10 @@ OB_DEF_SERIALIZE_SIZE(ObColumnParam) ...@@ -454,7 +469,10 @@ OB_DEF_SERIALIZE_SIZE(ObColumnParam)
orig_default_value_, orig_default_value_,
cur_default_value_, cur_default_value_,
order_, order_,
is_nullable_); is_nullable_,
is_gen_col_,
is_virtual_gen_col_,
is_hidden_);
return len; return len;
} }
...@@ -467,6 +485,9 @@ int ObColumnParam::assign(const ObColumnParam& other) ...@@ -467,6 +485,9 @@ int ObColumnParam::assign(const ObColumnParam& other)
order_ = other.order_; order_ = other.order_;
accuracy_ = other.accuracy_; accuracy_ = other.accuracy_;
is_nullable_ = other.is_nullable_; is_nullable_ = other.is_nullable_;
is_gen_col_ = other.is_gen_col_;
is_virtual_gen_col_ = other.is_virtual_gen_col_;
is_hidden_ = other.is_hidden_;
if (OB_FAIL(deep_copy_obj(other.cur_default_value_, cur_default_value_))) { if (OB_FAIL(deep_copy_obj(other.cur_default_value_, cur_default_value_))) {
LOG_WARN("Fail to deep copy cur_default_value, ", K(ret), K(cur_default_value_)); LOG_WARN("Fail to deep copy cur_default_value, ", K(ret), K(cur_default_value_));
} else if (OB_FAIL(deep_copy_obj(other.orig_default_value_, orig_default_value_))) { } else if (OB_FAIL(deep_copy_obj(other.orig_default_value_, orig_default_value_))) {
...@@ -1659,64 +1680,7 @@ int ObTableParam::convert_join_mv_rparam( ...@@ -1659,64 +1680,7 @@ int ObTableParam::convert_join_mv_rparam(
return ret; return ret;
} }
int ObTableParam::convert_schema_param( int ObTableParam::alloc_column(ObIAllocator &allocator, ObColumnParam *&col_ptr)
const share::schema::ObTableSchemaParam& schema_param, const common::ObIArray<uint64_t>& output_column_ids)
{
int ret = OB_SUCCESS;
if (!schema_param.is_valid() || 0 == output_column_ids.count()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(schema_param), K(output_column_ids));
} else if (schema_param.get_rowkey_column_num() != output_column_ids.count()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("output column ids should be row key columns", K(ret), K(schema_param), K(output_column_ids));
} else {
const int64_t COMMON_COLUMN_NUM = 16;
const ObColumnParam* src_col = NULL;
ObSEArray<ObColumnParam*, COMMON_COLUMN_NUM> tmp_cols;
ObSEArray<int32_t, COMMON_COLUMN_NUM> tmp_projector;
ObSEArray<int32_t, COMMON_COLUMN_NUM> tmp_output_projector;
table_id_ = schema_param.get_table_id();
schema_version_ = schema_param.get_schema_version();
main_table_rowkey_cnt_ = schema_param.get_rowkey_column_num();
for (int32_t i = 0; OB_SUCC(ret) && i < schema_param.get_rowkey_column_num(); ++i) {
ObColumnParam* dst_col = nullptr;
if (NULL == (src_col = schema_param.get_rowkey_column_by_idx(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("The column param is NULL", K(ret), K(i));
} else if (src_col->get_column_id() != output_column_ids.at(i)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("row key column id not match", K(ret), K(i), K(*src_col), K(output_column_ids));
} else if (OB_FAIL(alloc_column(allocator_, dst_col))) {
LOG_WARN("alloc column failed", K(ret), K(i));
} else if (OB_FAIL(dst_col->assign(*src_col))) {
LOG_WARN("assign column failed", K(ret), K(i));
} else if (OB_FAIL(tmp_cols.push_back(dst_col))) {
LOG_WARN("push back column failed", K(ret), K(i));
} else if (OB_FAIL(tmp_projector.push_back(i))) {
LOG_WARN("push back projector failed", K(ret), K(i));
} else if (OB_FAIL(tmp_output_projector.push_back(i))) {
LOG_WARN("push back output projector failed", K(ret), K(i));
}
}
// assign
if (OB_SUCC(ret)) {
if (OB_FAIL(cols_.assign(tmp_cols))) {
LOG_WARN("assign failed", K(ret));
} else if (OB_FAIL(projector_.assign(tmp_projector))) {
LOG_WARN("assign failed", K(ret));
} else if (OB_FAIL(output_projector_.assign(tmp_output_projector))) {
LOG_WARN("assign failed", K(ret));
} else if (OB_FAIL(create_column_map(cols_, col_map_))) {
LOG_WARN("failed to create column map", K(ret));
}
}
}
return ret;
}
int ObTableParam::alloc_column(ObIAllocator& allocator, ObColumnParam*& col_ptr)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
void* tmp_ptr = nullptr; void* tmp_ptr = nullptr;
...@@ -1751,6 +1715,9 @@ int ObTableParam::convert_column_schema_to_param(const ObColumnSchemaV2& column_ ...@@ -1751,6 +1715,9 @@ int ObTableParam::convert_column_schema_to_param(const ObColumnSchemaV2& column_
column_param.set_column_order(column_schema.get_order_in_rowkey()); column_param.set_column_order(column_schema.get_order_in_rowkey());
column_param.set_accuracy(column_schema.get_accuracy()); column_param.set_accuracy(column_schema.get_accuracy());
column_param.set_nullable(column_schema.is_nullable()); column_param.set_nullable(column_schema.is_nullable());
column_param.set_gen_col_flag(column_schema.is_generated_column(), column_schema.is_virtual_generated_column());
column_param.set_is_hidden(column_schema.is_hidden());
LOG_DEBUG("convert_column_schema_to_param", K(column_schema), K(column_param), K(lbt()));
if (column_schema.is_generated_column() || OB_HIDDEN_LOGICAL_ROWID_COLUMN_ID == column_schema.get_column_id()) { if (column_schema.is_generated_column() || OB_HIDDEN_LOGICAL_ROWID_COLUMN_ID == column_schema.get_column_id()) {
ObObj nop_obj; ObObj nop_obj;
nop_obj.set_nop_value(); nop_obj.set_nop_value();
......
...@@ -234,10 +234,31 @@ public: ...@@ -234,10 +234,31 @@ public:
{ {
is_nullable_ = nullable; is_nullable_ = nullable;
} }
int assign(const ObColumnParam& other); inline void set_gen_col_flag(const bool is_gen_col, const bool is_virtual)
{
is_gen_col_ = is_gen_col;
is_virtual_gen_col_ = is_virtual;
}
inline bool is_gen_col() const
{
return is_gen_col_;
}
inline bool is_virtual_gen_col() const
{
return is_virtual_gen_col_;
}
inline void set_is_hidden(const bool is_hidden)
{
is_hidden_ = is_hidden;
}
inline bool is_hidden() const
{
return is_hidden_;
}
int assign(const ObColumnParam &other);
TO_STRING_KV(K_(column_id), K_(meta_type), K_(order), K_(accuracy), K_(orig_default_value), K_(cur_default_value), TO_STRING_KV(K_(column_id), K_(meta_type), K_(order), K_(accuracy), K_(orig_default_value), K_(cur_default_value),
K_(is_nullable)); K_(is_nullable), K_(is_gen_col), K_(is_virtual_gen_col), K_(is_hidden));
private: private:
int deep_copy_obj(const common::ObObj& src, common::ObObj& dest); int deep_copy_obj(const common::ObObj& src, common::ObObj& dest);
...@@ -251,6 +272,41 @@ private: ...@@ -251,6 +272,41 @@ private:
common::ObObj orig_default_value_; common::ObObj orig_default_value_;
common::ObObj cur_default_value_; common::ObObj cur_default_value_;
bool is_nullable_; bool is_nullable_;
bool is_gen_col_;
bool is_virtual_gen_col_;
bool is_hidden_;
};
class ObVerticalPartitionParam {
OB_UNIS_VERSION_V(1);
public:
ObVerticalPartitionParam();
virtual ~ObVerticalPartitionParam();
void reset();
public:
DECLARE_TO_STRING;
inline uint64_t get_table_id() const
{
return table_id_;
}
inline void set_table_id(uint64_t table_id)
{
table_id_ = table_id;
}
inline int64_t get_schema_version() const
{
return schema_version_;
}
inline void set_schema_version(int64_t version)
{
schema_version_ = version;
}
private:
uint64_t table_id_;
int64_t schema_version_;
}; };
class ObTableSchema; class ObTableSchema;
...@@ -282,11 +338,6 @@ public: ...@@ -282,11 +338,6 @@ public:
int convert_join_mv_rparam(const ObTableSchema& mv_schema, const ObTableSchema& right_schema, int convert_join_mv_rparam(const ObTableSchema& mv_schema, const ObTableSchema& right_schema,
const common::ObIArray<uint64_t>& mv_column_ids); const common::ObIArray<uint64_t>& mv_column_ids);
// convert from table schema param which is used in ObTableModify operators
// used to get conflict row only by row keys
int convert_schema_param(
const share::schema::ObTableSchemaParam& schema_param, const common::ObIArray<uint64_t>& output_column_ids);
inline uint64_t get_table_id() const inline uint64_t get_table_id() const
{ {
return table_id_; return table_id_;
......
...@@ -170,11 +170,12 @@ int ObMultiPartUpdate::shuffle_update_row(ObExecContext& ctx, bool& got_row) con ...@@ -170,11 +170,12 @@ int ObMultiPartUpdate::shuffle_update_row(ObExecContext& ctx, bool& got_row) con
} }
while (OB_SUCC(ret) && OB_SUCC(inner_get_next_row(ctx, full_row))) { while (OB_SUCC(ret) && OB_SUCC(inner_get_next_row(ctx, full_row))) {
for (int64_t k = 0; OB_SUCC(ret) && k < table_dml_infos_.count(); ++k) { for (int64_t k = 0; OB_SUCC(ret) && k < table_dml_infos_.count(); ++k) {
const ObTableDMLInfo& table_dml_info = table_dml_infos_.at(k); const ObTableDMLInfo &table_dml_info = table_dml_infos_.at(k);
ObTableDMLCtx& table_dml_ctx = update_ctx->table_dml_ctxs_.at(k); ObTableDMLCtx &table_dml_ctx = update_ctx->table_dml_ctxs_.at(k);
const ObArrayWrap<ObGlobalIndexDMLInfo>& global_index_dml_infos = table_dml_info.index_infos_; const ObArrayWrap<ObGlobalIndexDMLInfo> &global_index_dml_infos = table_dml_info.index_infos_;
ObArrayWrap<ObGlobalIndexDMLCtx>& global_index_dml_ctxs = table_dml_ctx.index_ctxs_; ObArrayWrap<ObGlobalIndexDMLCtx> &global_index_dml_ctxs = table_dml_ctx.index_ctxs_;
const ObTableModify* sub_update = global_index_dml_infos.at(0).dml_subplans_.at(UPDATE_OP).subplan_root_; const ObTableUpdate *sub_update =
static_cast<const ObTableUpdate *>(global_index_dml_infos.at(0).dml_subplans_.at(UPDATE_OP).subplan_root_);
bool is_updated = false; bool is_updated = false;
bool is_filtered = false; bool is_filtered = false;
common::ObNewRow old_row; common::ObNewRow old_row;
...@@ -220,9 +221,7 @@ int ObMultiPartUpdate::shuffle_update_row(ObExecContext& ctx, bool& got_row) con ...@@ -220,9 +221,7 @@ int ObMultiPartUpdate::shuffle_update_row(ObExecContext& ctx, bool& got_row) con
continue; continue;
} }
} }
if (OB_SUCC(ret)) { OZ(check_row_null(ctx, new_row, sub_update->get_column_infos(), sub_update->get_updated_column_infos()), new_row);
OZ(check_row_null(ctx, new_row, sub_update->get_column_infos()), new_row);
}
OZ(check_updated_value(*update_ctx, table_dml_info.assign_columns_, old_row, new_row, is_updated)); OZ(check_updated_value(*update_ctx, table_dml_info.assign_columns_, old_row, new_row, is_updated));
if (OB_SUCC(ret) && OB_INVALID_INDEX != stmt_id_idx_) { if (OB_SUCC(ret) && OB_INVALID_INDEX != stmt_id_idx_) {
OZ(merge_implicit_cursor( OZ(merge_implicit_cursor(
......
...@@ -156,7 +156,7 @@ int ObMultiPartUpdateOp::shuffle_update_row(bool& got_row) ...@@ -156,7 +156,7 @@ int ObMultiPartUpdateOp::shuffle_update_row(bool& got_row)
continue; continue;
} }
} }
OZ(check_row_null(table_dml_info.assign_columns_.new_row_, sub_update->column_infos_)); OZ(check_row_null(table_dml_info.assign_columns_.new_row_, sub_update->column_infos_, sub_update->updated_column_infos_));
OZ(check_updated_value(*this, OZ(check_updated_value(*this,
table_dml_info.assign_columns_.get_assign_columns(), table_dml_info.assign_columns_.get_assign_columns(),
table_dml_info.assign_columns_.old_row_, table_dml_info.assign_columns_.old_row_,
......
...@@ -163,12 +163,15 @@ int ObTableConflictRowFetcherOp::inner_open() ...@@ -163,12 +163,15 @@ int ObTableConflictRowFetcherOp::inner_open()
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObDMLBaseParam dml_param; ObDMLBaseParam dml_param;
dml_param.output_exprs_ = &MY_SPEC.access_exprs_;
dml_param.op_ = this;
dml_param.op_filters_ = NULL;
dml_param.row2exprs_projector_ = &row2exprs_projector_;
OZ(ObTableModify::init_dml_param_se(ctx_, MY_SPEC.index_tid_, MY_SPEC.only_data_table_, NULL, dml_param)); OZ(ObTableModify::init_dml_param_se(ctx_, MY_SPEC.index_tid_, MY_SPEC.only_data_table_, NULL, dml_param));
OZ(fetch_conflict_rows(dml_param)); OZ(fetch_conflict_rows(dml_param));
OZ(gen_cols_.init(MY_SPEC.access_exprs_.count()));
for (int64_t i = 0; OB_SUCC(ret) && i < MY_SPEC.access_exprs_.count(); i++) {
ObExpr *expr = MY_SPEC.access_exprs_.at(i);
if (expr->eval_func_ != nullptr) {
OZ(gen_cols_.push_back(expr));
}
} // for end
LOG_DEBUG("open conflict row fetcher"); LOG_DEBUG("open conflict row fetcher");
return ret; return ret;
} }
...@@ -218,22 +221,34 @@ int ObTableConflictRowFetcherOp::inner_get_next_row() ...@@ -218,22 +221,34 @@ int ObTableConflictRowFetcherOp::inner_get_next_row()
LOG_WARN("invalid argument", K(ret), KP(dup_row)); LOG_WARN("invalid argument", K(ret), KP(dup_row));
} else { } else {
for (int64_t i = 0; OB_SUCC(ret) && i < MY_SPEC.access_exprs_.count(); i++) { for (int64_t i = 0; OB_SUCC(ret) && i < MY_SPEC.access_exprs_.count(); i++) {
const ObObj& cell = dup_row->cells_[i]; const ObObj &cell = dup_row->cells_[i];
ObDatum& datum = MY_SPEC.access_exprs_.at(i)->locate_datum_for_write(eval_ctx_); ObDatum &datum = MY_SPEC.access_exprs_.at(i)->locate_datum_for_write(eval_ctx_);
ObExpr* expr = MY_SPEC.access_exprs_.at(i); ObExpr *expr = MY_SPEC.access_exprs_.at(i);
if (cell.is_null()) { if (OB_UNLIKELY(expr->eval_func_ != nullptr)) {
//generated column, do nothing
} else if (OB_UNLIKELY(cell.is_null())) {
datum.set_null(); datum.set_null();
} else if (cell.get_type() != expr->datum_meta_.type_) { expr->get_eval_info(eval_ctx_).evaluated_ = true;
} else if (OB_UNLIKELY(cell.get_type() != expr->datum_meta_.type_)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("type mismatch", K(ret), K(i), K(cell.get_type()), K(*expr)); LOG_WARN("type mismatch", K(ret), K(i), K(cell.get_type()), K(*expr));
} else if (OB_FAIL(datum.from_obj(cell, expr->obj_datum_map_))) { } else if (OB_FAIL(datum.from_obj(cell, expr->obj_datum_map_))) {
LOG_WARN("convert obj to datum failed", K(ret)); LOG_WARN("convert obj to datum failed", K(ret));
} else { } else {
MY_SPEC.access_exprs_.at(i)->get_eval_info(eval_ctx_).evaluated_ = true; expr->get_eval_info(eval_ctx_).evaluated_ = true;
}
} // for end
//calc generated column expr
for (int64_t i = 0; OB_SUCC(ret) && i < gen_cols_.count(); ++i) {
ObExpr *expr = gen_cols_.at(i);
ObDatum *datum = nullptr;
expr->get_eval_info(eval_ctx_).clear_evaluated_flag();
if (OB_FAIL(expr->eval(eval_ctx_, datum))) {
LOG_WARN("eval generated column failed", K(ret));
} }
} // for end }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
LOG_DEBUG("fetch dup row", "row", ROWEXPR2STR(eval_ctx_, MY_SPEC.access_exprs_), K(*dup_row)); LOG_DEBUG("fetch dup row", "row", ROWEXPR2STR(eval_ctx_, MY_SPEC.access_exprs_), KPC(dup_row));
} }
} }
} }
......
...@@ -116,12 +116,13 @@ private: ...@@ -116,12 +116,13 @@ private:
class ObTableConflictRowFetcherOp : public ObOperator { class ObTableConflictRowFetcherOp : public ObOperator {
public: public:
ObTableConflictRowFetcherOp(ObExecContext& ctx, const ObOpSpec& spec, ObOpInput* input) ObTableConflictRowFetcherOp(ObExecContext &ctx, const ObOpSpec &spec, ObOpInput *input)
: ObOperator(ctx, spec, input), : ObOperator(ctx, spec, input),
dup_row_iter_arr_(), dup_row_iter_arr_(),
row2exprs_projector_(ctx.get_allocator()), row2exprs_projector_(ctx.get_allocator()),
cur_row_idx_(0), gen_cols_(ctx.get_allocator()),
cur_rowkey_id_(0) cur_row_idx_(0),
cur_rowkey_id_(0)
{} {}
virtual int inner_open() override; virtual int inner_open() override;
...@@ -140,6 +141,7 @@ private: ...@@ -140,6 +141,7 @@ private:
common::ObSEArray<common::ObNewRowIterator*, 4> dup_row_iter_arr_; common::ObSEArray<common::ObNewRowIterator*, 4> dup_row_iter_arr_;
storage::ObRow2ExprsProjector row2exprs_projector_; storage::ObRow2ExprsProjector row2exprs_projector_;
ObFixedArray<ObExpr*, common::ObIAllocator> gen_cols_; //mark to save generated column exprs
int64_t cur_row_idx_; int64_t cur_row_idx_;
int64_t cur_rowkey_id_; int64_t cur_rowkey_id_;
}; };
......
...@@ -74,7 +74,7 @@ int ObTableDeleteReturningOp::get_next_row() ...@@ -74,7 +74,7 @@ int ObTableDeleteReturningOp::get_next_row()
} }
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
real_delete_row.cells_ = delete_row_ceils_; real_delete_row.count_ = MY_SPEC.column_ids_.count();
real_delete_row.count_ = child_row_count_; real_delete_row.count_ = child_row_count_;
if (OB_FAIL(partition_service_->delete_row(my_session->get_trans_desc(), if (OB_FAIL(partition_service_->delete_row(my_session->get_trans_desc(),
dml_param_, dml_param_,
......
...@@ -1088,6 +1088,53 @@ int ObTableModify::validate_row(ObExprCtx& expr_ctx, ObCastCtx& column_conv_ctx, ...@@ -1088,6 +1088,53 @@ int ObTableModify::validate_row(ObExprCtx& expr_ctx, ObCastCtx& column_conv_ctx,
return ret; return ret;
} }
int ObTableModify::check_row_null(ObExecContext &ctx, const ObNewRow &calc_row,
const ObIArray<ColumnContent> &column_infos, const ObIArray<ColumnContent> &update_col_infos) const
{
int ret = OB_SUCCESS;
if (GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_2220) {
//兼容oracle, 如果有instead of trigger,不检查NOT NULL约束
OV(calc_row.get_count() == column_infos.count(), OB_ERR_UNEXPECTED, calc_row, column_infos);
for (int i = 0; OB_SUCC(ret) && i < update_col_infos.count(); i++) {
int64_t col_idx = update_col_infos.at(i).projector_index_;
bool is_nullable = column_infos.at(col_idx).is_nullable_;
bool is_cell_null = calc_row.get_cell(col_idx).is_null() ||
(lib::is_oracle_mode() && calc_row.get_cell(col_idx).is_null_oracle());
if (!is_nullable && is_cell_null) {
if (is_ignore_) {
if (is_oracle_mode()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dml with ignore not supported in oracle mode");
} else if (OB_FAIL(ObObjCaster::get_zero_value(column_infos.at(col_idx).column_type_,
column_infos.at(col_idx).coll_type_,
const_cast<ObObj &>(calc_row.get_cell(col_idx))))) {
LOG_WARN("get column default zero value failed", K(ret), K(column_infos.at(col_idx)));
} else {
// output warning msg
ObString column_name = column_infos.at(col_idx).column_name_;
ObSQLUtils::copy_and_convert_string_charset(ctx.get_allocator(),
column_name,
column_name,
CS_TYPE_UTF8MB4_BIN,
ctx.get_my_session()->get_local_collation_connection());
LOG_USER_WARN(OB_BAD_NULL_ERROR, column_name.length(), column_name.ptr());
}
} else {
ObString column_name = column_infos.at(col_idx).column_name_;
ObSQLUtils::copy_and_convert_string_charset(ctx.get_allocator(),
column_name,
column_name,
CS_TYPE_UTF8MB4_BIN,
ctx.get_my_session()->get_local_collation_connection());
ret = OB_BAD_NULL_ERROR;
LOG_USER_ERROR(OB_BAD_NULL_ERROR, column_name.length(), column_name.ptr());
}
}
}
}
return ret;
}
int ObTableModify::check_row_null( int ObTableModify::check_row_null(
ObExecContext& ctx, const ObNewRow& calc_row, const ObIArray<ColumnContent>& column_infos) const ObExecContext& ctx, const ObNewRow& calc_row, const ObIArray<ColumnContent>& column_infos) const
{ {
......
...@@ -760,11 +760,14 @@ protected: ...@@ -760,11 +760,14 @@ protected:
int validate_row(common::ObExprCtx& expr_ctx, common::ObCastCtx& column_conv_ctx, common::ObNewRow& calc_row, int validate_row(common::ObExprCtx& expr_ctx, common::ObCastCtx& column_conv_ctx, common::ObNewRow& calc_row,
bool check_normal_column, bool check_virtual_column) const; bool check_normal_column, bool check_virtual_column) const;
int check_row_null( int check_row_null(
ObExecContext& ctx, const common::ObNewRow& calc_row, const common::ObIArray<ColumnContent>& column_infos) const; ObExecContext &ctx, const common::ObNewRow &calc_row, const common::ObIArray<ColumnContent> &column_infos) const;
int set_autoinc_param_pkey(ObExecContext& ctx, const common::ObPartitionKey& pkey) const; int check_row_null(ObExecContext &ctx, const common::ObNewRow &calc_row,
int get_part_location(ObExecContext& ctx, const ObPhyTableLocation& table_location, const common::ObIArray<ColumnContent> &column_infos,
const share::ObPartitionReplicaLocation*& out) const; const common::ObIArray<ColumnContent> &update_col_infos) const;
int get_part_location(ObExecContext& ctx, common::ObIArray<DMLPartInfo>& part_keys) const; int set_autoinc_param_pkey(ObExecContext &ctx, const common::ObPartitionKey &pkey) const;
int get_part_location(ObExecContext &ctx, const ObPhyTableLocation &table_location,
const share::ObPartitionReplicaLocation *&out) const;
int get_part_location(ObExecContext &ctx, common::ObIArray<DMLPartInfo> &part_keys) const;
// for checking the rowkey whether null, the head of the row must be rowkey // for checking the rowkey whether null, the head of the row must be rowkey
int check_rowkey_is_null(const ObNewRow& row, int64_t rowkey_cnt, bool& is_null) const; int check_rowkey_is_null(const ObNewRow& row, int64_t rowkey_cnt, bool& is_null) const;
int get_gi_task(ObExecContext& ctx) const; int get_gi_task(ObExecContext& ctx) const;
......
...@@ -658,7 +658,59 @@ int ObTableModifyOp::calc_part_id(const ObExpr* calc_part_id_expr, ObIArray<int6 ...@@ -658,7 +658,59 @@ int ObTableModifyOp::calc_part_id(const ObExpr* calc_part_id_expr, ObIArray<int6
return ret; return ret;
} }
int ObTableModifyOp::check_row_null(const ObExprPtrIArray& row, const ObIArray<ColumnContent>& column_infos) const int ObTableModifyOp::check_row_null(const ObExprPtrIArray &row,
const ObIArray<ColumnContent> &column_infos,
const ObIArray<ColumnContent> &update_col_infos) const
{
int ret = OB_SUCCESS;
if (GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_2220) {
//兼容oracle, 如果有instead of trigger,不检查NOT NULL约束
OV (row.count() == column_infos.count(), OB_ERR_UNEXPECTED, row, column_infos);
for (int i = 0; OB_SUCC(ret) && i < update_col_infos.count(); i++) {
int64_t col_idx = update_col_infos.at(i).projector_index_;
ObDatum *datum = NULL;
const bool is_nullable = column_infos.at(col_idx).is_nullable_;
if (OB_FAIL(row.at(col_idx)->eval(eval_ctx_, datum))) {
const ObTableInsertOp *insert_op = dynamic_cast<const ObTableInsertOp*>(this);
const ObTableUpdateOp *update_op = dynamic_cast<const ObTableUpdateOp*>(this);
if (nullptr != insert_op) {
//compatible with old code
log_user_error_inner(ret, col_idx, insert_op->curr_row_num_ + 1, MY_SPEC.column_infos_);
} else if (nullptr != update_op) {
//compatible with old code
log_user_error_inner(ret, col_idx, update_op->get_found_rows() + 1, MY_SPEC.column_infos_);
}
} else if (!is_nullable && datum->is_null()) {
if (MY_SPEC.is_ignore_) {
ObObj zero_obj;
if (is_oracle_mode()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dml with ignore not supported in oracle mode");
} else if (OB_FAIL(ObObjCaster::get_zero_value(
column_infos.at(col_idx).column_type_,
column_infos.at(col_idx).coll_type_,
zero_obj))) {
LOG_WARN("get column default zero value failed", K(ret), K(column_infos.at(col_idx)));
} else if (OB_FAIL(datum->from_obj(zero_obj))) {
LOG_WARN("assign zero obj to datum failed", K(ret), K(zero_obj));
} else {
//output warning msg
const ObString &column_name = column_infos.at(col_idx).column_name_;
LOG_USER_WARN(OB_BAD_NULL_ERROR, column_name.length(), column_name.ptr());
}
} else {
const ObString &column_name = column_infos.at(col_idx).column_name_;
ret = OB_BAD_NULL_ERROR;
LOG_USER_ERROR(OB_BAD_NULL_ERROR, column_name.length(), column_name.ptr());
}
}
}
}
return ret;
}
int ObTableModifyOp::check_row_null(const ObExprPtrIArray &row,
const ObIArray<ColumnContent> &column_infos) const
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_2220) { if (GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_2220) {
......
...@@ -375,10 +375,15 @@ protected: ...@@ -375,10 +375,15 @@ protected:
int mark_lock_row_flag(int64_t flag); int mark_lock_row_flag(int64_t flag);
int check_row_null(const ObExprPtrIArray& row, const common::ObIArray<ColumnContent>& column_infos) const; int check_row_null(const ObExprPtrIArray &row,
int set_autoinc_param_pkey(const common::ObPartitionKey& pkey) const; const common::ObIArray<ColumnContent> &column_infos,
int get_part_location(const ObPhyTableLocation& table_location, const share::ObPartitionReplicaLocation*& out); const common::ObIArray<ColumnContent> &update_col_infos) const;
int get_part_location(common::ObIArray<DMLPartInfo>& part_keys); int check_row_null(const ObExprPtrIArray &row,
const common::ObIArray<ColumnContent> &column_infos) const;
int set_autoinc_param_pkey(const common::ObPartitionKey &pkey) const;
int get_part_location(const ObPhyTableLocation &table_location,
const share::ObPartitionReplicaLocation *&out);
int get_part_location(common::ObIArray<DMLPartInfo> &part_keys);
int get_gi_task(); int get_gi_task();
// filtered if filter return false value. (move from ObPhyOperator). // filtered if filter return false value. (move from ObPhyOperator).
......
...@@ -263,9 +263,9 @@ int ObTableUpdate::get_next_row(ObExecContext& ctx, const ObNewRow*& row) const ...@@ -263,9 +263,9 @@ int ObTableUpdate::get_next_row(ObExecContext& ctx, const ObNewRow*& row) const
} }
} }
if (OB_SUCC(ret) && !from_multi_table_dml()) { if (OB_SUCC(ret) && !from_multi_table_dml()) {
ObNewRow& old_row = update_ctx->old_row_; ObNewRow &old_row = update_ctx->old_row_;
ObNewRow& new_row = update_ctx->new_row_; ObNewRow &new_row = update_ctx->new_row_;
OZ(check_row_null(ctx, new_row, column_infos_), new_row); OZ(check_row_null(ctx, new_row, column_infos_, updated_column_infos_), new_row);
} }
} }
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
......
...@@ -147,6 +147,8 @@ public: ...@@ -147,6 +147,8 @@ public:
{ {
return updated_column_infos_; return updated_column_infos_;
} }
const common::ObIArray<ColumnContent> &get_updated_column_infos() const
{ return updated_column_infos_; }
const common::ObIArray<uint64_t>* get_updated_column_ids() const const common::ObIArray<uint64_t>* get_updated_column_ids() const
{ {
......
...@@ -200,10 +200,7 @@ int ObTableUpdateOp::prepare_next_storage_row(const ObExprPtrIArray*& output) ...@@ -200,10 +200,7 @@ int ObTableUpdateOp::prepare_next_storage_row(const ObExprPtrIArray*& output)
while (OB_SUCC(ret) && !need_update_ && OB_SUCC(inner_get_next_row())) { while (OB_SUCC(ret) && !need_update_ && OB_SUCC(inner_get_next_row())) {
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
if (!MY_SPEC.from_multi_table_dml()) { if (!MY_SPEC.from_multi_table_dml()) {
// TODO : process trigger OZ(check_row_null(MY_SPEC.new_row_, MY_SPEC.column_infos_, MY_SPEC.updated_column_infos_));
// OZ (TriggerHandle::init_param_rows(*this, *update_ctx, old_row, new_row), old_row, new_row);
// OZ (TriggerHandle::do_handle_before_row(*this, *update_ctx, &new_row), old_row, new_row);
OZ(check_row_null(MY_SPEC.new_row_, MY_SPEC.column_infos_));
if (MY_SPEC.need_filter_null_row_) { if (MY_SPEC.need_filter_null_row_) {
bool is_null = false; bool is_null = false;
if (OB_FAIL(check_rowkey_is_null(MY_SPEC.old_row_, MY_SPEC.primary_key_ids_.count(), is_null))) { if (OB_FAIL(check_rowkey_is_null(MY_SPEC.old_row_, MY_SPEC.primary_key_ids_.count(), is_null))) {
......
...@@ -765,8 +765,8 @@ void ObMemtableIterRowReader::reset() ...@@ -765,8 +765,8 @@ void ObMemtableIterRowReader::reset()
} }
} }
int ObMemtableIterRowReader::init(common::ObArenaAllocator* allocator, const share::schema::ColumnMap* cols_map, int ObMemtableIterRowReader::init(common::ObIAllocator *allocator, const share::schema::ColumnMap *cols_map,
ObNopBitMap* bitmap, const storage::ObColDescArray& columns) ObNopBitMap *bitmap, const storage::ObColDescArray &columns)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (IS_INIT) { if (IS_INIT) {
......
...@@ -60,10 +60,10 @@ class ObMemtableIterRowReader { ...@@ -60,10 +60,10 @@ class ObMemtableIterRowReader {
public: public:
ObMemtableIterRowReader(); ObMemtableIterRowReader();
~ObMemtableIterRowReader(); ~ObMemtableIterRowReader();
int init(common::ObArenaAllocator* allocator, const share::schema::ColumnMap* cols_map, ObNopBitMap* bitmap, int init(common::ObIAllocator *allocator, const share::schema::ColumnMap *cols_map, ObNopBitMap *bitmap,
const storage::ObColDescArray& columns); const storage::ObColDescArray &columns);
int get_memtable_row(storage::ObStoreRow& row); int get_memtable_row(storage::ObStoreRow &row);
int set_buf(const char* buf, int64_t buf_size); int set_buf(const char *buf, int64_t buf_size);
void reset(); void reset();
void destory(); void destory();
bool is_iter_end(); bool is_iter_end();
......
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
#include "lib/container/ob_iarray.h" #include "lib/container/ob_iarray.h"
#include "share/ob_errno.h" #include "share/ob_errno.h"
#include "share/schema/ob_schema_struct.h" #include "share/schema/ob_schema_struct.h"
#include "share/schema/ob_table_param.h" #include "share/schema/ob_table_dml_param.h"
#include "sql/engine/expr/ob_expr.h"
namespace oceanbase { namespace oceanbase {
namespace storage { namespace storage {
...@@ -187,5 +186,28 @@ DEF_TO_STRING(ObRow2ExprsProjector::Item) ...@@ -187,5 +186,28 @@ DEF_TO_STRING(ObRow2ExprsProjector::Item)
return pos; return pos;
} }
DEF_TO_STRING(ObDMLBaseParam)
{
int64_t pos = 0;
J_OBJ_START();
J_KV(N_TIMEOUT,
timeout_,
N_SCHEMA_VERSION,
schema_version_,
N_SCAN_FLAG,
query_flag_,
N_SQL_MODE,
sql_mode_,
N_IS_TOTAL_QUANTITY_LOG,
is_total_quantity_log_,
K_(only_data_table),
KPC_(table_param),
K_(tenant_schema_version),
K_(is_ignore),
K_(duplicated_rows),
K_(prelock));
J_OBJ_END();
return pos;
}
} // namespace storage } // namespace storage
} // namespace oceanbase } // namespace oceanbase
...@@ -193,48 +193,41 @@ struct ObDMLBaseParam { ...@@ -193,48 +193,41 @@ struct ObDMLBaseParam {
schema_version_(-1), schema_version_(-1),
query_flag_(), query_flag_(),
sql_mode_(DEFAULT_OCEANBASE_MODE), sql_mode_(DEFAULT_OCEANBASE_MODE),
is_total_quantity_log_(false),
tz_info_(NULL), tz_info_(NULL),
only_data_table_(false),
table_param_(NULL), table_param_(NULL),
tenant_schema_version_(OB_INVALID_VERSION), tenant_schema_version_(OB_INVALID_VERSION),
is_total_quantity_log_(false),
only_data_table_(false),
is_ignore_(false), is_ignore_(false),
duplicated_rows_(0),
prelock_(false), prelock_(false),
output_exprs_(NULL), duplicated_rows_(0),
op_(NULL), dml_allocator_(nullptr)
op_filters_(NULL), {
row2exprs_projector_(NULL) query_flag_.read_latest_ = common::ObQueryFlag::OBSF_MASK_READ_LATEST;
}
~ObDMLBaseParam()
{} {}
int64_t timeout_; int64_t timeout_;
int64_t schema_version_; int64_t schema_version_;
common::ObQueryFlag query_flag_; common::ObQueryFlag query_flag_;
ObSQLMode sql_mode_; ObSQLMode sql_mode_;
bool is_total_quantity_log_; const common::ObTimeZoneInfo *tz_info_;
const common::ObTimeZoneInfo* tz_info_;
bool only_data_table_;
common::ObColumnExprArray virtual_columns_; common::ObColumnExprArray virtual_columns_;
common::ObExprCtx expr_ctx_; common::ObExprCtx expr_ctx_;
const share::schema::ObTableDMLParam* table_param_; const share::schema::ObTableDMLParam* table_param_;
int64_t tenant_schema_version_; int64_t tenant_schema_version_;
bool is_total_quantity_log_;
bool only_data_table_;
bool is_ignore_; bool is_ignore_;
mutable int64_t duplicated_rows_;
bool prelock_; bool prelock_;
mutable int64_t duplicated_rows_;
// output for sql static typing engine, NULL for old sql engine scan. common::ObIAllocator *dml_allocator_;
const sql::ObExprPtrIArray* output_exprs_;
sql::ObOperator* op_;
const sql::ObExprPtrIArray* op_filters_;
ObRow2ExprsProjector* row2exprs_projector_;
bool is_valid() const bool is_valid() const
{ {
return (timeout_ > 0 && schema_version_ >= 0); return (timeout_ > 0 && schema_version_ >= 0);
} }
TO_STRING_KV(N_TIMEOUT, timeout_, N_SCHEMA_VERSION, schema_version_, N_SCAN_FLAG, query_flag_, N_SQL_MODE, sql_mode_, DECLARE_TO_STRING;
N_IS_TOTAL_QUANTITY_LOG, is_total_quantity_log_, K_(only_data_table), KP_(table_param), K_(tenant_schema_version),
K_(is_ignore), K_(duplicated_rows), K_(prelock));
}; };
} // end namespace storage } // end namespace storage
......
...@@ -41,7 +41,7 @@ public: ...@@ -41,7 +41,7 @@ public:
} }
is_inited_ = false; is_inited_ = false;
} }
int init(const bool is_multi, const bool is_ordered, common::ObArenaAllocator& allocator) int init(const bool is_multi, const bool is_ordered, common::ObIAllocator &allocator)
{ {
int ret = common::OB_SUCCESS; int ret = common::OB_SUCCESS;
void* buf = NULL; void* buf = NULL;
......
...@@ -560,12 +560,14 @@ int ObTableAccessParam::init(const uint64_t table_id, const int64_t schema_versi ...@@ -560,12 +560,14 @@ int ObTableAccessParam::init(const uint64_t table_id, const int64_t schema_versi
iter_param_.full_out_cols_ = nullptr != full_out_cols_ && full_out_cols_->count() > 0 ? full_out_cols_ : nullptr; iter_param_.full_out_cols_ = nullptr != full_out_cols_ && full_out_cols_->count() > 0 ? full_out_cols_ : nullptr;
if (NULL != table_param) { if (NULL != table_param) {
iter_param_.cols_id_map_ = &table_param->get_column_map();
iter_param_.full_cols_id_map_ = &table_param->get_full_column_map(); iter_param_.full_cols_id_map_ = &table_param->get_full_column_map();
iter_param_.out_cols_project_ = &table_param->get_output_projector(); iter_param_.full_out_cols_ = &table_param->get_full_col_descs();
iter_param_.full_projector_ = &table_param->get_full_projector(); iter_param_.full_projector_ = &table_param->get_full_projector();
iter_param_.out_cols_param_ = &table_param->get_columns(); iter_param_.out_cols_param_ = &table_param->get_columns();
iter_param_.full_out_cols_param_ = &table_param->get_full_columns(); iter_param_.full_out_cols_param_ = &table_param->get_full_columns();
iter_param_.cols_id_map_ = &table_param->get_column_map();
iter_param_.out_cols_project_ = &table_param->get_output_projector();
iter_param_.projector_ = &table_param->get_projector();
out_cols_param_ = &table_param->get_columns(); out_cols_param_ = &table_param->get_columns();
enable_fast_skip_ = false; enable_fast_skip_ = false;
if (is_mv_right_table) { if (is_mv_right_table) {
...@@ -577,25 +579,46 @@ int ObTableAccessParam::init(const uint64_t table_id, const int64_t schema_versi ...@@ -577,25 +579,46 @@ int ObTableAccessParam::init(const uint64_t table_id, const int64_t schema_versi
return ret; return ret;
} }
int ObTableAccessParam::init_basic_param(const uint64_t table_id, const int64_t schema_version, int ObTableAccessParam::init_dml_access_param(const uint64_t table_id, const int64_t schema_version,
const int64_t rowkey_column_num, const ObIArray<share::schema::ObColDesc>& column_ids, const int64_t rowkey_column_num, share::schema::ObTableParam &table_param)
const ObIArray<int32_t>* out_cols_index)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (OB_FAIL(out_col_desc_param_.init(nullptr))) { iter_param_.table_id_ = table_id;
LOG_WARN("init out cols fail", K(ret)); iter_param_.schema_version_ = schema_version;
} else if (OB_FAIL(out_col_desc_param_.assign(column_ids))) { iter_param_.rowkey_cnt_ = rowkey_column_num;
LOG_WARN("assign out cols fail", K(ret), K(column_ids)); iter_param_.full_cols_id_map_ = &table_param.get_full_column_map();
} else { iter_param_.full_out_cols_ = &table_param.get_full_col_descs();
enable_fast_skip_ = false; iter_param_.full_projector_ = &table_param.get_full_projector();
iter_param_.reset(); iter_param_.cols_id_map_ = &table_param.get_column_map();
iter_param_.table_id_ = table_id; iter_param_.out_cols_param_ = &table_param.get_columns();
iter_param_.schema_version_ = schema_version; iter_param_.out_cols_ = &table_param.get_col_descs();
iter_param_.rowkey_cnt_ = rowkey_column_num; iter_param_.out_cols_project_ = &table_param.get_output_projector();
iter_param_.out_cols_project_ = out_cols_index; iter_param_.projector_ = &table_param.get_projector();
iter_param_.out_cols_ = &out_col_desc_param_.get_col_descs(); out_cols_param_ = &table_param.get_columns();
iter_param_.full_out_cols_ = nullptr; full_out_cols_ = &table_param.get_full_col_descs();
} OZ(out_col_desc_param_.init(&table_param.get_col_descs()));
return ret;
}
int ObTableAccessParam::init_dml_access_param(const uint64_t table_id, const int64_t schema_version,
const int64_t rowkey_column_num, const share::schema::ObTableSchemaParam &schema_param,
const ObIArray<int32_t> *out_cols_project)
{
int ret = OB_SUCCESS;
iter_param_.table_id_ = table_id;
iter_param_.schema_version_ = schema_version;
iter_param_.rowkey_cnt_ = rowkey_column_num;
iter_param_.full_cols_id_map_ = &schema_param.get_full_col_map();
iter_param_.full_out_cols_ = &schema_param.get_full_col_descs();
iter_param_.full_projector_ = &schema_param.get_full_projector();
iter_param_.cols_id_map_ = &schema_param.get_col_map();
iter_param_.out_cols_param_ = &schema_param.get_columns();
iter_param_.out_cols_ = &schema_param.get_col_descs();
iter_param_.out_cols_project_ = out_cols_project;
iter_param_.projector_ = &schema_param.get_projector();
out_cols_param_ = &schema_param.get_columns();
full_out_cols_ = &schema_param.get_full_col_descs();
OZ(out_col_desc_param_.init(&schema_param.get_col_descs()));
return ret; return ret;
} }
...@@ -1027,9 +1050,9 @@ int ObTableAccessContext::init(ObTableScanParam& scan_param, const ObStoreCtx& c ...@@ -1027,9 +1050,9 @@ int ObTableAccessContext::init(ObTableScanParam& scan_param, const ObStoreCtx& c
return ret; return ret;
} }
int ObTableAccessContext::init(const common::ObQueryFlag& query_flag, const ObStoreCtx& ctx, int ObTableAccessContext::init(const common::ObQueryFlag &query_flag, const ObStoreCtx &ctx, ObIAllocator &allocator,
ObArenaAllocator& allocator, ObArenaAllocator& stmt_allocator, blocksstable::ObBlockCacheWorkingSet& block_cache_ws, ObIAllocator &stmt_allocator, blocksstable::ObBlockCacheWorkingSet &block_cache_ws,
const ObVersionRange& trans_version_range) const ObVersionRange &trans_version_range)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (is_inited_) { if (is_inited_) {
...@@ -1048,8 +1071,8 @@ int ObTableAccessContext::init(const common::ObQueryFlag& query_flag, const ObSt ...@@ -1048,8 +1071,8 @@ int ObTableAccessContext::init(const common::ObQueryFlag& query_flag, const ObSt
} }
return ret; return ret;
} }
int ObTableAccessContext::init(const common::ObQueryFlag& query_flag, const ObStoreCtx& ctx, int ObTableAccessContext::init(const common::ObQueryFlag &query_flag, const ObStoreCtx &ctx,
common::ObArenaAllocator& allocator, const common::ObVersionRange& trans_version_range) common::ObIAllocator &allocator, const common::ObVersionRange &trans_version_range)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
......
...@@ -1216,8 +1216,10 @@ public: ...@@ -1216,8 +1216,10 @@ public:
const common::ObIArray<share::schema::ObColDesc>& column_ids, const bool is_multi_version_merge = false, const common::ObIArray<share::schema::ObColDesc>& column_ids, const bool is_multi_version_merge = false,
share::schema::ObTableParam* table_param = NULL, const bool is_mv_right_table = false); share::schema::ObTableParam* table_param = NULL, const bool is_mv_right_table = false);
// used for get unique index conflict row // used for get unique index conflict row
int init_basic_param(const uint64_t table_id, const int64_t schema_version, const int64_t rowkey_column_num, int init_dml_access_param(const uint64_t table_id, const int64_t schema_version, const int64_t rowkey_column_num,
const common::ObIArray<share::schema::ObColDesc>& column_ids, const common::ObIArray<int32_t>* out_cols_index); share::schema::ObTableParam &table_param);
int init_dml_access_param(const uint64_t table_id, const int64_t schema_version, const int64_t rowkey_column_num,
const share::schema::ObTableSchemaParam &schema_param, const common::ObIArray<int32_t> *out_cols_project);
// used for index back when query // used for index back when query
int init_index_back(ObTableScanParam& scan_param); int init_index_back(ObTableScanParam& scan_param);
// init need_fill_scale_ and search column which need fill scale // init need_fill_scale_ and search column which need fill scale
...@@ -1355,12 +1357,12 @@ struct ObTableAccessContext { ...@@ -1355,12 +1357,12 @@ struct ObTableAccessContext {
const common::ObVersionRange& trans_version_range, const ObIStoreRowFilter* row_filter, const common::ObVersionRange& trans_version_range, const ObIStoreRowFilter* row_filter,
const bool is_index_back = false); const bool is_index_back = false);
// used for merge // used for merge
int init(const common::ObQueryFlag& query_flag, const ObStoreCtx& ctx, common::ObArenaAllocator& allocator, int init(const common::ObQueryFlag &query_flag, const ObStoreCtx &ctx, common::ObIAllocator &allocator,
common::ObArenaAllocator& stmt_allocator, blocksstable::ObBlockCacheWorkingSet& block_cache_ws, common::ObIAllocator &stmt_allocator, blocksstable::ObBlockCacheWorkingSet &block_cache_ws,
const common::ObVersionRange& trans_version_range); const common::ObVersionRange &trans_version_range);
// used for exist or simple scan // used for exist or simple scan
int init(const common::ObQueryFlag& query_flag, const ObStoreCtx& ctx, common::ObArenaAllocator& allocator, int init(const common::ObQueryFlag &query_flag, const ObStoreCtx &ctx, common::ObIAllocator &allocator,
const common::ObVersionRange& trans_version_range); const common::ObVersionRange &trans_version_range);
TO_STRING_KV(K_(is_inited), K_(timeout), K_(pkey), K_(query_flag), K_(sql_mode), KP_(store_ctx), KP_(expr_ctx), TO_STRING_KV(K_(is_inited), K_(timeout), K_(pkey), K_(query_flag), K_(sql_mode), KP_(store_ctx), KP_(expr_ctx),
KP_(limit_param), KP_(stmt_allocator), KP_(allocator), KP_(table_scan_stat), KP_(limit_param), KP_(stmt_allocator), KP_(allocator), KP_(table_scan_stat),
KP_(block_cache_ws), K_(out_cnt), K_(is_end), K_(trans_version_range), KP_(row_filter), K_(merge_log_ts), KP_(block_cache_ws), K_(out_cnt), K_(is_end), K_(trans_version_range), KP_(row_filter), K_(merge_log_ts),
...@@ -1379,9 +1381,9 @@ public: ...@@ -1379,9 +1381,9 @@ public:
common::ObExprCtx* expr_ctx_; common::ObExprCtx* expr_ctx_;
common::ObLimitParam* limit_param_; common::ObLimitParam* limit_param_;
// sql statement level allocator, available before sql execute finish // sql statement level allocator, available before sql execute finish
common::ObArenaAllocator* stmt_allocator_; common::ObIAllocator *stmt_allocator_;
// storage scan/rescan interface level allocator, will be reclaimed in every scan/rescan call // storage scan/rescan interface level allocator, will be reclaimed in every scan/rescan call
common::ObArenaAllocator* allocator_; common::ObIAllocator *allocator_;
lib::MemoryContext stmt_mem_; // sql statement level memory entity, only for query lib::MemoryContext stmt_mem_; // sql statement level memory entity, only for query
lib::MemoryContext scan_mem_; // scan/rescan level memory entity, only for query lib::MemoryContext scan_mem_; // scan/rescan level memory entity, only for query
common::ObTableScanStatistic* table_scan_stat_; common::ObTableScanStatistic* table_scan_stat_;
......
...@@ -3784,6 +3784,18 @@ int ObPartitionService::delete_rows(const transaction::ObTransDesc& trans_desc, ...@@ -3784,6 +3784,18 @@ int ObPartitionService::delete_rows(const transaction::ObTransDesc& trans_desc,
} else if (OB_FAIL(check_query_allowed(pkey, trans_desc, ctx_guard, guard))) { } else if (OB_FAIL(check_query_allowed(pkey, trans_desc, ctx_guard, guard))) {
STORAGE_LOG(WARN, "fail to check query allowed", K(ret)); STORAGE_LOG(WARN, "fail to check query allowed", K(ret));
} else { } else {
//@NOTICE:(yuchen.wyc)为了规避外键自引用带来的防御检查不过的问题:
//由于目前delete语句的TableScan操作使用的快照点是语句级,无法看到本语句的最新修改,
//因此,对于外键自引用的级联删除时,同一行可能会被自己和外键级联操作多次删除,
//这个问题目前没有出现语义上的问题,但会导致delete的防御检查报错,详见:
// https://aone.alibaba-inc.com/issue/36022956
// DML的防御检查读使用的默认快照点是可以读到本语最新修改,因此对于该场景会出现两次读到的数据不一致的问题
//正确的做法是从外键的删除操作上规避掉多次删除同一行的情况,这要求delete的TableScan能够看到自己的最新修改
//由于担心这个修改的影响较大,3.2暂时从防御检查上规避掉这个问题,
// 4.0上delete改为读本语句的最新修改来避免同一行的多次删除
if (trans_desc.get_cur_stmt_desc().is_delete_stmt()) {
const_cast<ObDMLBaseParam &>(dml_param).query_flag_.read_latest_ = 0;
}
ctx_guard.get_store_ctx().trans_id_ = trans_desc.get_trans_id(); ctx_guard.get_store_ctx().trans_id_ = trans_desc.get_trans_id();
ret = guard.get_partition_group()->delete_rows( ret = guard.get_partition_group()->delete_rows(
ctx_guard.get_store_ctx(), dml_param, column_ids, row_iter, affected_rows); ctx_guard.get_store_ctx(), dml_param, column_ids, row_iter, affected_rows);
...@@ -3805,6 +3817,18 @@ int ObPartitionService::delete_row(const ObTransDesc& trans_desc, const ObDMLBas ...@@ -3805,6 +3817,18 @@ int ObPartitionService::delete_row(const ObTransDesc& trans_desc, const ObDMLBas
} else if (OB_FAIL(check_query_allowed(pkey, trans_desc, ctx_guard, guard))) { } else if (OB_FAIL(check_query_allowed(pkey, trans_desc, ctx_guard, guard))) {
STORAGE_LOG(WARN, "fail to check query allowed", K(ret)); STORAGE_LOG(WARN, "fail to check query allowed", K(ret));
} else { } else {
//@NOTICE:(yuchen.wyc)为了规避外键自引用带来的防御检查不过的问题:
//由于目前delete语句的TableScan操作使用的快照点是语句级,无法看到本语句的最新修改,
//因此,对于外键自引用的级联删除时,同一行可能会被自己和外键级联操作多次删除,
//这个问题目前没有出现语义上的问题,但会导致delete的防御检查报错,详见:
// https://aone.alibaba-inc.com/issue/36022956
// DML的防御检查读使用的默认快照点是可以读到本语最新修改,因此对于该场景会出现两次读到的数据不一致的问题
//正确的做法是从外键的删除操作上规避掉多次删除同一行的情况,这要求delete的TableScan能够看到自己的最新修改
//由于担心这个修改的影响较大,3.2暂时从防御检查上规避掉这个问题,
// 4.0上delete改为读本语句的最新修改来避免同一行的多次删除
if (trans_desc.get_cur_stmt_desc().is_delete_stmt()) {
const_cast<ObDMLBaseParam &>(dml_param).query_flag_.read_latest_ = 0;
}
ctx_guard.get_store_ctx().trans_id_ = trans_desc.get_trans_id(); ctx_guard.get_store_ctx().trans_id_ = trans_desc.get_trans_id();
ret = guard.get_partition_group()->delete_row(ctx_guard.get_store_ctx(), dml_param, column_ids, row); ret = guard.get_partition_group()->delete_row(ctx_guard.get_store_ctx(), dml_param, column_ids, row);
AUDIT_PARTITION_V2(ctx_guard.get_store_ctx().mem_ctx_, PART_AUDIT_DELETE_ROW, 1); AUDIT_PARTITION_V2(ctx_guard.get_store_ctx().mem_ctx_, PART_AUDIT_DELETE_ROW, 1);
......
...@@ -174,10 +174,12 @@ struct ObPartitionPrefixAccessStat { ...@@ -174,10 +174,12 @@ struct ObPartitionPrefixAccessStat {
AccessStat rowkey_prefix_[MAX_ROWKEY_PREFIX_NUM + 1]; AccessStat rowkey_prefix_[MAX_ROWKEY_PREFIX_NUM + 1];
}; };
class ObSingleRowGetter;
class ObPartitionStorage : public ObIPartitionStorage { class ObPartitionStorage : public ObIPartitionStorage {
template <typename T> template <typename T>
friend class oceanbase::storageperf::ObMultiBlockBench; friend class oceanbase::storageperf::ObMultiBlockBench;
friend class ObPGStorage; friend class ObPGStorage;
friend class ObSingleRowGetter;
public: public:
ObPartitionStorage(); ObPartitionStorage();
...@@ -488,6 +490,7 @@ private: ...@@ -488,6 +490,7 @@ private:
relative_tables_(allocator), relative_tables_(allocator),
col_map_(nullptr), col_map_(nullptr),
col_descs_(nullptr), col_descs_(nullptr),
column_ids_(nullptr),
idx_col_descs_(), idx_col_descs_(),
tbl_row_(), tbl_row_(),
idx_row_(NULL), idx_row_(NULL),
...@@ -515,8 +518,9 @@ private: ...@@ -515,8 +518,9 @@ private:
common::ObIAllocator& allocator_; common::ObIAllocator& allocator_;
const ObRowDml dml_type_; const ObRowDml dml_type_;
ObRelativeTables relative_tables_; ObRelativeTables relative_tables_;
const share::schema::ColumnMap* col_map_; const share::schema::ColumnMap *col_map_;
const ObColDescIArray* col_descs_; const ObColDescIArray *col_descs_;
const common::ObIArray<uint64_t> *column_ids_;
ObColDescArray idx_col_descs_; ObColDescArray idx_col_descs_;
ObStoreRow tbl_row_; ObStoreRow tbl_row_;
ObStoreRow* idx_row_; // not a must, allocate dynamically ObStoreRow* idx_row_; // not a must, allocate dynamically
...@@ -540,28 +544,24 @@ private: ...@@ -540,28 +544,24 @@ private:
const share::schema::ColumnMap* col_map, const common::ObIArray<uint64_t>& column_ids, const ObRowDml dml_type, const share::schema::ColumnMap* col_map, const common::ObIArray<uint64_t>& column_ids, const ObRowDml dml_type,
const common::ObIArray<uint64_t>& upd_column_ids, const ChangeType change_type, const bool is_total_quantity_log); const common::ObIArray<uint64_t>& upd_column_ids, const ChangeType change_type, const bool is_total_quantity_log);
int insert_table_row( int insert_table_row(
ObDMLRunningCtx& run_ctx, ObRelativeTable& relative_table, const ObColDescIArray& col_descs, ObStoreRow& row); ObDMLRunningCtx &run_ctx, ObRelativeTable &relative_table, const ObColDescIArray &col_descs, ObStoreRow &row);
int insert_table_rows(ObDMLRunningCtx& run_ctx, ObRelativeTable& relative_table, const ObColDescIArray& col_descs, int insert_table_rows(ObDMLRunningCtx &run_ctx, ObRelativeTable &relative_table, const ObColDescIArray &col_descs,
ObRowsInfo& rows_info); ObRowsInfo &rows_info);
int insert_index_rows(ObDMLRunningCtx& run_ctx, ObStoreRow* rows, int64_t row_count); int insert_index_rows(ObDMLRunningCtx &run_ctx, ObStoreRow *rows, int64_t row_count);
int direct_insert_row_and_index(ObDMLRunningCtx& run_ctx, const ObStoreRow& tbl_row); int direct_insert_row_and_index(ObDMLRunningCtx &run_ctx, const ObStoreRow &tbl_row);
int get_column_index(const ObColDescIArray& tbl_col_desc, const ObColDescIArray& idx_col_desc, int convert_row_to_rowkey(ObSingleRowGetter &index_row_getter, ObStoreRowkey &rowkey);
common::ObIArray<int32_t>& col_idx_array); int get_conflict_row(ObDMLRunningCtx &run_ctx, const common::ObIArray<uint64_t> &out_col_ids,
int convert_row_to_rowkey(common::ObNewRowIterator& iter, GetRowkeyArray& rowkeys); ObRelativeTable &relative_table, const ObStoreRowkey &rowkey, common::ObNewRowIterator *&duplicated_rows);
int get_conflict_row(ObDMLRunningCtx& run_ctx, const ObTableAccessParam& access_param, int get_index_conflict_row(ObDMLRunningCtx &run_ctx, const common::ObIArray<uint64_t> &out_col_ids,
ObTableAccessContext& access_ctx, ObRelativeTable& relative_table, const common::ObStoreRowkey& rowkey, ObRelativeTable &relative_table, bool need_index_back, const common::ObNewRow &row,
common::ObNewRowIterator*& duplicated_rows); common::ObNewRowIterator *&duplicated_rows);
int get_index_conflict_row(ObDMLRunningCtx& run_ctx, const ObTableAccessParam& table_access_param, int single_get_row(ObSingleRowGetter &row_getter,
ObTableAccessContext& table_access_ctx, ObRelativeTable& relative_table, bool need_index_back, const ObStoreRowkey &rowkey,
const common::ObNewRow& row, common::ObNewRowIterator*& duplicated_rows); common::ObNewRowIterator *&duplicated_rows,
int multi_get_rows(const ObStoreCtx& store_ctx, const ObTableAccessParam& access_param, int64_t data_table_rowkey_cnt);
ObTableAccessContext& access_ctx, ObRelativeTable& relative_table, const GetRowkeyArray& rowkeys, int get_conflict_rows(ObDMLRunningCtx &run_ctx, const ObInsertFlag flag,
common::ObNewRowIterator*& duplicated_rows, int64_t data_table_rowkey_cnt); const common::ObIArray<uint64_t> &dup_col_ids, const common::ObNewRow &row,
int get_conflict_rows(ObDMLRunningCtx& run_ctx, const ObInsertFlag flag, common::ObNewRowIterator *&duplicated_rows);
const common::ObIArray<uint64_t>& dup_col_ids, const common::ObNewRow& row,
common::ObNewRowIterator*& duplicated_rows);
int init_dml_access_ctx(ObDMLRunningCtx& run_ctx, common::ObArenaAllocator& allocator,
blocksstable::ObBlockCacheWorkingSet& block_cache_ws, ObTableAccessContext& table_access_ctx);
int get_change_type( int get_change_type(
const common::ObIArray<uint64_t>& update_ids, const ObRelativeTable& table, ChangeType& change_type); const common::ObIArray<uint64_t>& update_ids, const ObRelativeTable& table, ChangeType& change_type);
int check_rowkey_change(const common::ObIArray<uint64_t>& update_ids, const ObRelativeTables& relative_tables, int check_rowkey_change(const common::ObIArray<uint64_t>& update_ids, const ObRelativeTables& relative_tables,
...@@ -691,8 +691,21 @@ private: ...@@ -691,8 +691,21 @@ private:
int lock_rows_( int lock_rows_(
const ObStoreCtx& ctx, const ObTableScanParam& scan_param, const common::ObNewRow& row, RowReshape*& row_reshape); const ObStoreCtx& ctx, const ObTableScanParam& scan_param, const common::ObNewRow& row, RowReshape*& row_reshape);
int check_useless_index_mini_merge(const storage::ObSSTableMergeCtx &ctx); int check_useless_index_mini_merge(const storage::ObSSTableMergeCtx &ctx);
int dump_error_info(ObSSTable& main_sstable, ObSSTable& index_sstable);
void check_leader_changed_for_sql_recheck_(ObDMLRunningCtx &run_ctx, int &ret); void check_leader_changed_for_sql_recheck_(ObDMLRunningCtx &run_ctx, int &ret);
int dump_error_info(ObSSTable &main_sstable, ObSSTable &index_sstable);
//////////////////
/// do write row strict check
int check_old_row_legitimacy(ObDMLRunningCtx &run_ctx, const common::ObNewRow &row);
int check_delete_index_legitimacy(
ObDMLRunningCtx &run_ctx, ObRelativeTable &index_table, const common::ObNewRow &row);
int check_new_row_legitimacy(ObDMLRunningCtx &run_ctx, const common::ObNewRow &row);
int check_new_row_nullable_value(
const common::ObIArray<uint64_t> &column_ids, ObRelativeTable &data_table, const common::ObNewRow &new_row);
int check_new_row_nullable_value(const common::ObIArray<share::schema::ObColDesc> &col_descs,
ObRelativeTable &relative_table, const common::ObNewRow &new_row);
int check_new_row_shadow_pk(
const common::ObIArray<uint64_t> &column_ids, ObRelativeTable &data_table, const common::ObNewRow &new_row);
// disallow copy; // disallow copy;
DISALLOW_COPY_AND_ASSIGN(ObPartitionStorage); DISALLOW_COPY_AND_ASSIGN(ObPartitionStorage);
......
...@@ -197,7 +197,27 @@ int ObRelativeTable::get_rowkey_column_ids(ObIArray<ObColDesc>& column_ids) cons ...@@ -197,7 +197,27 @@ int ObRelativeTable::get_rowkey_column_ids(ObIArray<ObColDesc>& column_ids) cons
return ret; return ret;
} }
int ObRelativeTable::get_column_data_length(const uint64_t column_id, int32_t& len) const int ObRelativeTable::get_rowkey_column_ids(ObIArray<uint64_t> &column_ids) const
{
int ret = OB_SUCCESS;
if (!is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("relative table is invalid", K(ret), KPC(this));
} else {
if (!use_schema_param_) {
if (OB_FAIL(schema_->get_rowkey_column_ids(column_ids))) {
LOG_WARN("get rowkey column ids from schema fail", K(ret));
}
} else {
if (OB_FAIL(schema_param_->get_rowkey_column_ids(column_ids))) {
LOG_WARN("get rowkey column ids from param fail", K(ret));
}
}
}
return ret;
}
int ObRelativeTable::get_column_data_length(const uint64_t column_id, int32_t &len) const
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (!is_valid()) { if (!is_valid()) {
...@@ -250,7 +270,7 @@ int ObRelativeTable::is_rowkey_column_id(const uint64_t column_id, bool& is_rowk ...@@ -250,7 +270,7 @@ int ObRelativeTable::is_rowkey_column_id(const uint64_t column_id, bool& is_rowk
return ret; return ret;
} }
int ObRelativeTable::is_column_nullable(const uint64_t column_id, bool& is_nullable) const int ObRelativeTable::is_column_nullable_for_write(const uint64_t column_id, bool& is_nullable) const
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
is_nullable = false; is_nullable = false;
...@@ -276,6 +296,121 @@ int ObRelativeTable::is_column_nullable(const uint64_t column_id, bool& is_nulla ...@@ -276,6 +296,121 @@ int ObRelativeTable::is_column_nullable(const uint64_t column_id, bool& is_nulla
return ret; return ret;
} }
int ObRelativeTable::is_column_nullable_for_read(const uint64_t column_id, bool &is_nullable_for_read) const
{
int ret = OB_SUCCESS;
is_nullable_for_read = false;
if (!is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("relative table is invalid", K(ret), K(*this));
} else if (OB_INVALID_ID == column_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid column id", K(ret), K(column_id));
} else if (!use_schema_param_) {
const ObColumnSchemaV2 *col = NULL;
if (nullptr == (col = schema_->get_column_schema(column_id))) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column schema is null", K(ret), K(column_id), K(*schema_));
} else {
is_nullable_for_read = col->is_nullable();
}
} else {
const ObColumnParam *col = schema_param_->get_column(column_id);
if (OB_ISNULL(col)) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column schema is null", K(ret), K(column_id), K(*schema_));
} else {
is_nullable_for_read = col->is_nullable();
}
}
return ret;
}
int ObRelativeTable::is_nop_default_value(const uint64_t column_id, bool &is_nop) const
{
int ret = OB_SUCCESS;
is_nop = false;
if (!is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("relative table is invalid", K(ret), K(*this));
} else if (OB_HIDDEN_ROWID_COLUMN_ID == column_id) {
// rowid column need to compute on fly
is_nop = true;
} else if (!use_schema_param_) {
const ObColumnSchemaV2 *column = NULL;
if (OB_ISNULL(column = schema_->get_column_schema(column_id))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("wrong column id", K(ret), K(column_id));
} else if (column->is_generated_column()) {
// generated column need to compute on fly
is_nop = true;
}
} else {
const ObColumnParam *param = NULL;
if (OB_ISNULL(param = schema_param_->get_column(column_id))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("wrong column id", K(ret), K(column_id), K(*schema_param_));
} else if (param->get_cur_default_value().is_nop_value()) {
is_nop = true;
}
}
return ret;
}
int ObRelativeTable::is_hidden_column(const uint64_t column_id, bool &is_hidden) const
{
int ret = OB_SUCCESS;
is_hidden = false;
if (!is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("relative table is invalid", K(ret), K(*this));
} else if (!use_schema_param_) {
const ObColumnSchemaV2 *col = NULL;
if (nullptr == (col = schema_->get_column_schema(column_id))) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column schema is null", K(ret), K(column_id), K(*schema_));
} else {
is_hidden = col->is_hidden();
}
} else {
const ObColumnParam *col = schema_param_->get_column(column_id);
if (OB_ISNULL(col)) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column schema is null", K(ret), K(column_id), K(*schema_));
} else {
is_hidden = col->is_hidden();
}
}
return ret;
}
int ObRelativeTable::is_gen_column(const uint64_t column_id, bool &is_gen_col) const
{
int ret = OB_SUCCESS;
is_gen_col = false;
if (!is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("relative table is invalid", K(ret), K(*this));
} else if (!use_schema_param_) {
const ObColumnSchemaV2 *col = NULL;
if (nullptr == (col = schema_->get_column_schema(column_id))) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column schema is null", K(ret), K(column_id), K(*schema_));
} else {
is_gen_col = col->is_generated_column();
}
} else {
const ObColumnParam *col = schema_param_->get_column(column_id);
if (OB_ISNULL(col)) {
ret = OB_SCHEMA_ERROR;
LOG_WARN("column schema is null", K(ret), K(column_id), K(*schema_));
} else {
is_gen_col = col->is_gen_col();
}
}
return ret;
}
int64_t ObRelativeTable::get_rowkey_column_num() const int64_t ObRelativeTable::get_rowkey_column_num() const
{ {
return use_schema_param_ ? schema_param_->get_rowkey_column_num() : schema_->get_rowkey_column_num(); return use_schema_param_ ? schema_param_->get_rowkey_column_num() : schema_->get_rowkey_column_num();
...@@ -513,33 +648,8 @@ int ObRelativeTable::check_index_column_in_map(const ColumnMap& col_map, const i ...@@ -513,33 +648,8 @@ int ObRelativeTable::check_index_column_in_map(const ColumnMap& col_map, const i
return ret; return ret;
} }
int ObRelativeTable::build_table_param( int ObRelativeTable::build_index_row(const ObNewRow &table_row, const ColumnMap &col_map, const bool only_rowkey,
const common::ObIArray<uint64_t>& out_col_ids, share::schema::ObTableParam& table_param) const ObNewRow &index_row, bool &null_idx_val, ObIArray<ObColDesc> *idx_columns)
{
int ret = OB_SUCCESS;
if (!is_valid()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("relative table is invalid", K(ret), K(*this));
} else if (0 == out_col_ids.count()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("output column ids count is 0", K(ret));
} else {
table_param.reset();
if (!use_schema_param_) {
if (OB_FAIL(table_param.convert(*schema_, *schema_, out_col_ids, false))) {
LOG_WARN("build table param from schema fail", K(ret), K(*schema_));
}
} else {
if (OB_FAIL(table_param.convert_schema_param(*schema_param_, out_col_ids))) {
LOG_WARN("build table param from param fail", K(ret), K(*schema_param_));
}
}
}
return ret;
}
int ObRelativeTable::build_index_row(const ObNewRow& table_row, const ColumnMap& col_map, const bool only_rowkey,
ObNewRow& index_row, bool& null_idx_val, ObIArray<ObColDesc>* idx_columns)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (!is_valid()) { if (!is_valid()) {
...@@ -669,7 +779,11 @@ int ObRelativeTable::set_index_value(const ObNewRow& table_row, const ColumnMap& ...@@ -669,7 +779,11 @@ int ObRelativeTable::set_index_value(const ObNewRow& table_row, const ColumnMap&
// ------ ObRelativeTables ------ // // ------ ObRelativeTables ------ //
bool ObRelativeTables::set_table_param(const ObTableDMLParam* param) bool ObRelativeTables::set_table_param(const ObTableDMLParam* param)
{ {
if (OB_ISNULL(param) || !param->is_valid()) { if (OB_ISNULL(param) || !param->is_valid() || param->get_data_table().get_full_col_descs().empty()) {
// only when the full column descs in table_dml_param is not empty,
// we will use table_dml_param to generate dml running context
// otherwise we will generate dml running context from ObTableSchema
// because the full column descs maybe empty during the observer upgrade
use_table_param_ = false; use_table_param_ = false;
table_param_ = NULL; table_param_ = NULL;
} else { } else {
......
...@@ -33,13 +33,18 @@ public: ...@@ -33,13 +33,18 @@ public:
bool set_schema_param(const share::schema::ObTableSchemaParam* param); bool set_schema_param(const share::schema::ObTableSchemaParam* param);
uint64_t get_table_id() const; uint64_t get_table_id() const;
int64_t get_schema_version() const; int64_t get_schema_version() const;
int get_col_desc(const uint64_t column_id, share::schema::ObColDesc& col_desc) const; int get_col_desc(const uint64_t column_id, share::schema::ObColDesc &col_desc) const;
int get_col_desc_by_idx(const int64_t idx, share::schema::ObColDesc& col_desc) const; int get_col_desc_by_idx(const int64_t idx, share::schema::ObColDesc &col_desc) const;
int get_rowkey_col_id_by_idx(const int64_t idx, uint64_t& col_id) const; int get_rowkey_col_id_by_idx(const int64_t idx, uint64_t &col_id) const;
int get_rowkey_column_ids(common::ObIArray<share::schema::ObColDesc>& column_ids) const; int get_rowkey_column_ids(common::ObIArray<share::schema::ObColDesc> &column_ids) const;
int get_column_data_length(const uint64_t column_id, int32_t& len) const; int get_rowkey_column_ids(common::ObIArray<uint64_t> &column_ids) const;
int is_rowkey_column_id(const uint64_t column_id, bool& is_rowkey) const; int get_column_data_length(const uint64_t column_id, int32_t &len) const;
int is_column_nullable(const uint64_t column_id, bool& is_nullable) const; int is_rowkey_column_id(const uint64_t column_id, bool &is_rowkey) const;
int is_column_nullable_for_write(const uint64_t column_id, bool &is_nullable_for_write) const;
int is_column_nullable_for_read(const uint64_t column_id, bool &is_nullable_for_read) const;
int is_nop_default_value(const uint64_t column_id, bool &is_nop) const;
int is_hidden_column(const uint64_t column_id, bool &is_hidden) const;
int is_gen_column(const uint64_t column_id, bool &is_gen_col) const;
OB_INLINE bool allow_not_ready() const OB_INLINE bool allow_not_ready() const
{ {
return allow_not_ready_; return allow_not_ready_;
...@@ -59,13 +64,12 @@ public: ...@@ -59,13 +64,12 @@ public:
bool can_read_index() const; bool can_read_index() const;
bool is_unique_index() const; bool is_unique_index() const;
bool is_domain_index() const; bool is_domain_index() const;
int check_rowkey_in_column_ids(const common::ObIArray<uint64_t>& column_ids, const bool has_other_column) const; int check_rowkey_in_column_ids(const common::ObIArray<uint64_t> &column_ids, const bool has_other_column) const;
int check_column_in_map(const share::schema::ColumnMap& col_map) const; int check_column_in_map(const share::schema::ColumnMap &col_map) const;
int check_index_column_in_map(const share::schema::ColumnMap& col_map, const int64_t data_table_rowkey_cnt) const; int check_index_column_in_map(const share::schema::ColumnMap &col_map, const int64_t data_table_rowkey_cnt) const;
int build_table_param(const common::ObIArray<uint64_t>& out_col_ids, share::schema::ObTableParam& table_param) const; int build_index_row(const common::ObNewRow &table_row, const share::schema::ColumnMap &col_map,
int build_index_row(const common::ObNewRow& table_row, const share::schema::ColumnMap& col_map, const bool only_rowkey, common::ObNewRow &index_row, bool &null_idx_val,
const bool only_rowkey, common::ObNewRow& index_row, bool& null_idx_val, common::ObIArray<share::schema::ObColDesc> *idx_columns);
common::ObIArray<share::schema::ObColDesc>* idx_columns);
OB_INLINE bool use_schema_param() const OB_INLINE bool use_schema_param() const
{ {
return use_schema_param_; return use_schema_param_;
...@@ -78,8 +82,11 @@ public: ...@@ -78,8 +82,11 @@ public:
{ {
return schema_param_; return schema_param_;
} }
TO_STRING_KV("index_id", NULL == schema_ ? 0 : schema_->get_table_id(), KPC(schema_), K_(allow_not_ready), OB_INLINE const share::schema::ObTableSchema *get_schema() const
K_(use_schema_param), KPC(schema_param_)); {
return schema_;
}
TO_STRING_KV(K_(allow_not_ready), K_(use_schema_param), KPC_(schema), KPC_(schema_param));
private: private:
int get_rowkey_col_desc_by_idx(const int64_t idx, share::schema::ObColDesc& col_desc) const; int get_rowkey_col_desc_by_idx(const int64_t idx, share::schema::ObColDesc& col_desc) const;
......
...@@ -23,7 +23,9 @@ ObSingleMerge::ObSingleMerge() : rowkey_(NULL), fuse_row_cache_fetcher_() ...@@ -23,7 +23,9 @@ ObSingleMerge::ObSingleMerge() : rowkey_(NULL), fuse_row_cache_fetcher_()
{} {}
ObSingleMerge::~ObSingleMerge() ObSingleMerge::~ObSingleMerge()
{} {
reset();
}
int ObSingleMerge::open(const ObExtStoreRowkey& rowkey) int ObSingleMerge::open(const ObExtStoreRowkey& rowkey)
{ {
...@@ -151,7 +153,10 @@ int ObSingleMerge::inner_get_next_row(ObStoreRow& row) ...@@ -151,7 +153,10 @@ int ObSingleMerge::inner_get_next_row(ObStoreRow& row)
bool final_result = false; bool final_result = false;
bool is_fuse_row_empty = false; bool is_fuse_row_empty = false;
int64_t sstable_end_log_ts = 0; int64_t sstable_end_log_ts = 0;
ObStoreRow& fuse_row = full_row_; ObStoreRow &fuse_row = full_row_;
int64_t column_cnt = access_param_->iter_param_.projector_ != nullptr
? access_param_->iter_param_.projector_->count()
: access_param_->iter_param_.out_cols_->count();
nop_pos_.reset(); nop_pos_.reset();
fuse_row.row_val_.count_ = 0; fuse_row.row_val_.count_ = 0;
fuse_row.flag_ = ObActionFlag::OP_ROW_DOES_NOT_EXIST; fuse_row.flag_ = ObActionFlag::OP_ROW_DOES_NOT_EXIST;
...@@ -221,8 +226,7 @@ int ObSingleMerge::inner_get_next_row(ObStoreRow& row) ...@@ -221,8 +226,7 @@ int ObSingleMerge::inner_get_next_row(ObStoreRow& row)
cache_row.flag_ = handle_.value_->get_flag(); cache_row.flag_ = handle_.value_->get_flag();
// cache_row.snapshot_version_ = handle_.value_->get_snapshot_version(); // cache_row.snapshot_version_ = handle_.value_->get_snapshot_version();
if (is_fuse_row_empty) { if (is_fuse_row_empty) {
row.row_val_.count_ = row.row_val_.count_ = ObActionFlag::OP_ROW_EXIST == cache_row.flag_ ? column_cnt : 0;
ObActionFlag::OP_ROW_EXIST == cache_row.flag_ ? access_param_->iter_param_.projector_->count() : 0;
row.flag_ = ObActionFlag::OP_ROW_DOES_NOT_EXIST; row.flag_ = ObActionFlag::OP_ROW_DOES_NOT_EXIST;
row.from_base_ = false; row.from_base_ = false;
row.snapshot_version_ = 0L; row.snapshot_version_ = 0L;
...@@ -258,20 +262,19 @@ int ObSingleMerge::inner_get_next_row(ObStoreRow& row) ...@@ -258,20 +262,19 @@ int ObSingleMerge::inner_get_next_row(ObStoreRow& row)
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
STORAGE_LOG(DEBUG, "row before project", K(fuse_row)); STORAGE_LOG(DEBUG, "row before project", K(fuse_row));
if (!is_fuse_row_empty) { if (!is_fuse_row_empty) {
row.row_val_.count_ = row.row_val_.count_ = ObActionFlag::OP_ROW_EXIST == fuse_row.flag_ ? column_cnt : 0;
ObActionFlag::OP_ROW_EXIST == fuse_row.flag_ ? access_param_->iter_param_.projector_->count() : 0;
} }
if (enable_fuse_row_cache) { if (enable_fuse_row_cache) {
if (!is_fuse_row_empty) { if (!is_fuse_row_empty) {
if (ObActionFlag::OP_ROW_EXIST == fuse_row.flag_) { if (ObActionFlag::OP_ROW_EXIST == fuse_row.flag_) {
if (OB_FAIL(project_row(fuse_row, access_param_->iter_param_.projector_, 0 /*range idx delta*/, row))) { if (OB_FAIL(project_row(fuse_row, access_param_->iter_param_.projector_, 0 /*range idx delta*/, row))) {
STORAGE_LOG(WARN, "fail to project row", K(ret), K(fuse_row), K(*access_param_->iter_param_.projector_)); STORAGE_LOG(WARN, "fail to project row", K(ret), K(fuse_row), KPC(access_param_->iter_param_.projector_));
} else { } else {
STORAGE_LOG(DEBUG, STORAGE_LOG(DEBUG,
"after project row", "after project row",
K(fuse_row), K(fuse_row),
K(row), K(row),
K(*access_param_->iter_param_.projector_), KPC(access_param_->iter_param_.projector_),
K(access_param_->iter_param_.table_id_)); K(access_param_->iter_param_.table_id_));
} }
} else { } else {
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
namespace oceanbase { namespace oceanbase {
namespace storage { namespace storage {
class ObSingleMerge : public ObMultipleMerge { class ObSingleMerge : public ObMultipleMerge {
public: public:
ObSingleMerge(); ObSingleMerge();
...@@ -50,7 +49,6 @@ private: ...@@ -50,7 +49,6 @@ private:
// disallow copy // disallow copy
DISALLOW_COPY_AND_ASSIGN(ObSingleMerge); DISALLOW_COPY_AND_ASSIGN(ObSingleMerge);
}; };
} /* namespace storage */ } /* namespace storage */
} /* namespace oceanbase */ } /* namespace oceanbase */
......
...@@ -68,7 +68,7 @@ void ObSSTableMultiVersionRowIterator::reuse() ...@@ -68,7 +68,7 @@ void ObSSTableMultiVersionRowIterator::reuse()
} }
template <typename T> template <typename T>
int ObSSTableMultiVersionRowIterator::new_iterator(ObArenaAllocator& allocator) int ObSSTableMultiVersionRowIterator::new_iterator(ObIAllocator &allocator)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (NULL == iter_) { if (NULL == iter_) {
......
...@@ -33,8 +33,8 @@ protected: ...@@ -33,8 +33,8 @@ protected:
const void* query_range) = 0; const void* query_range) = 0;
virtual int inner_get_next_row(const ObStoreRow*& row) = 0; virtual int inner_get_next_row(const ObStoreRow*& row) = 0;
template <typename T> template <typename T>
int new_iterator(common::ObArenaAllocator& allocator); int new_iterator(common::ObIAllocator &allocator);
int get_not_exist_row(const common::ObStoreRowkey& rowkey, const ObStoreRow*& row); int get_not_exist_row(const common::ObStoreRowkey &rowkey, const ObStoreRow *&row);
protected: protected:
const ObTableIterParam* iter_param_; const ObTableIterParam* iter_param_;
......
...@@ -250,7 +250,7 @@ public: ...@@ -250,7 +250,7 @@ public:
array_ = nullptr; array_ = nullptr;
capacity_ = 0; capacity_ = 0;
} }
int reserve(common::ObArenaAllocator& allocator, const int64_t count) int reserve(common::ObIAllocator &allocator, const int64_t count)
{ {
int ret = common::OB_SUCCESS; int ret = common::OB_SUCCESS;
if (capacity_ < count) { if (capacity_ < count) {
......
...@@ -10,12 +10,14 @@ ...@@ -10,12 +10,14 @@
* See the Mulan PubL v2 for more details. * See the Mulan PubL v2 for more details.
*/ */
#define USING_LOG_PREFIX STORAGE
#include "ob_value_row_iterator.h" #include "ob_value_row_iterator.h"
#include "ob_partition_storage.h"
#include "ob_single_merge.h"
namespace oceanbase { namespace oceanbase {
using namespace oceanbase::common; using namespace oceanbase::common;
namespace storage { namespace storage {
ObValueRowIterator::ObValueRowIterator() ObValueRowIterator::ObValueRowIterator()
: ObNewRowIterator(), : ObNewRowIterator(),
is_inited_(false), is_inited_(false),
...@@ -130,5 +132,159 @@ void ObValueRowIterator::reset() ...@@ -130,5 +132,159 @@ void ObValueRowIterator::reset()
cur_idx_ = 0; cur_idx_ = 0;
} }
ObSingleRowGetter::ObSingleRowGetter(ObIAllocator &allocator, ObPartitionStore &store)
: store_(store),
single_merge_(nullptr),
store_ctx_(nullptr),
output_projector_(allocator),
relative_table_(nullptr),
table_param_(nullptr),
allocator_(allocator)
{}
ObSingleRowGetter::~ObSingleRowGetter()
{
if (single_merge_ != nullptr) {
single_merge_->~ObSingleMerge();
allocator_.free(single_merge_);
single_merge_ = nullptr;
}
if (table_param_ != nullptr) {
table_param_->~ObTableParam();
allocator_.free(table_param_);
table_param_ = nullptr;
}
}
int ObSingleRowGetter::init_dml_access_ctx(const ObStoreCtx &store_ctx, const ObDMLBaseParam &dml_param)
{
int ret = OB_SUCCESS;
common::ObVersionRange trans_version_range;
// TODO (muwei) trans_version_range值后续由上层传入
trans_version_range.snapshot_version_ = store_ctx.mem_ctx_->get_read_snapshot();
trans_version_range.base_version_ = 0;
trans_version_range.multi_version_start_ = 0;
store_ctx_ = &store_ctx;
if (OB_FAIL(access_ctx_.init(dml_param.query_flag_, store_ctx, allocator_, trans_version_range))) {
LOG_WARN("failed to init table access ctx", K(ret));
} else {
access_ctx_.expr_ctx_ = const_cast<ObExprCtx *>(&dml_param.expr_ctx_);
}
return ret;
}
int ObSingleRowGetter::init_dml_access_param(
ObRelativeTable &relative_table, const ObDMLBaseParam &dml_param, const ObIArray<uint64_t> &out_col_ids)
{
int ret = OB_SUCCESS;
relative_table_ = &relative_table;
get_table_param_.tables_handle_ = &(relative_table.tables_handle_);
if (!dml_param.virtual_columns_.empty() && !relative_table.is_index_table()) {
//The index table does not contain virtual columns, no need to set virtual_columns
access_param_.virtual_column_exprs_ = &(dml_param.virtual_columns_);
}
if (OB_UNLIKELY(!relative_table.use_schema_param())) {
const share::schema::ObTableSchema *schema = relative_table.get_schema();
if (OB_FAIL(create_table_param())) {
LOG_WARN("create table param failed", K(ret));
} else if (OB_FAIL(table_param_->convert(*schema, *schema, out_col_ids, false))) {
LOG_WARN("build table param from schema fail", K(ret), KPC(schema));
} else if (OB_FAIL(access_param_.init_dml_access_param(relative_table.get_table_id(),
relative_table.get_schema_version(),
relative_table.get_rowkey_column_num(),
*table_param_))) {
LOG_WARN("init dml access param failed", K(ret));
}
} else {
const share::schema::ObTableSchemaParam *schema_param = relative_table.get_schema_param();
output_projector_.set_capacity(out_col_ids.count());
for (int32_t i = 0; OB_SUCC(ret) && i < out_col_ids.count(); ++i) {
int idx = OB_INVALID_INDEX;
if (OB_FAIL(schema_param->get_col_map().get(out_col_ids.at(i), idx))) {
LOG_WARN("get column index from column map failed", K(ret), K(out_col_ids.at(i)));
} else if (OB_FAIL(output_projector_.push_back(idx))) {
LOG_WARN("store output projector failed", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(access_param_.init_dml_access_param(relative_table.get_table_id(),
relative_table.get_schema_version(),
relative_table.get_rowkey_column_num(),
*schema_param,
&output_projector_))) {
LOG_WARN("init dml access param failed", K(ret));
}
}
}
LOG_DEBUG("init dml access param", K(ret), K(out_col_ids), K(relative_table), K(dml_param), K_(access_param));
return ret;
}
int ObSingleRowGetter::create_table_param()
{
int ret = OB_SUCCESS;
void *buf = nullptr;
if (table_param_ != nullptr) {
ret = OB_INIT_TWICE;
LOG_WARN("init table param twice", K(ret));
} else if (OB_ISNULL(buf = allocator_.alloc(sizeof(share::schema::ObTableParam)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate table param failed", K(ret), K(sizeof(share::schema::ObTableParam)));
} else {
table_param_ = new (buf) share::schema::ObTableParam(allocator_);
}
return ret;
}
int ObSingleRowGetter::open(const ObStoreRowkey &rowkey, bool use_fuse_row_cache)
{
int ret = OB_SUCCESS;
void *buf = nullptr;
new (&ext_rowkey_) ObExtStoreRowkey(rowkey);
if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObSingleMerge)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("Fail to allocate memory for multi get merge ", K(ret));
} else {
{
ObStorageWriterGuard guard(store_, *store_ctx_, false);
if (OB_FAIL(guard.refresh_and_protect_table(*relative_table_))) {
STORAGE_LOG(WARN, "fail to protect table", K(ret));
}
}
single_merge_ = new (buf) ObSingleMerge();
}
if (OB_SUCC(ret)) {
if (OB_FAIL(single_merge_->init(access_param_, access_ctx_, get_table_param_))) {
STORAGE_LOG(WARN, "Fail to init ObSingleMerge, ", K(ret));
} else if (OB_FAIL(single_merge_->open(ext_rowkey_))) {
STORAGE_LOG(WARN, "Fail to open iter, ", K(ret));
}
if (use_fuse_row_cache) {
access_ctx_.use_fuse_row_cache_ = true;
access_ctx_.fuse_row_cache_hit_rate_ = 100L;
}
}
return ret;
}
int ObSingleRowGetter::get_next_row(ObNewRow *&row)
{
int ret = OB_SUCCESS;
row = nullptr;
while (OB_SUCC(ret)) {
ObStoreRow *store_row = NULL;
if (OB_FAIL(single_merge_->get_next_row(store_row))) {
if (OB_ITER_END != ret) {
STORAGE_LOG(WARN, "failed to get next row", K(ret));
}
} else if (ObActionFlag::OP_ROW_EXIST == store_row->flag_) {
row = &store_row->row_val_;
break;
}
}
return ret;
}
} // end namespace storage } // end namespace storage
} // end namespace oceanbase } // end namespace oceanbase
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "common/row/ob_row_iterator.h" #include "common/row/ob_row_iterator.h"
#include "common/rowkey/ob_rowkey.h" #include "common/rowkey/ob_rowkey.h"
#include "storage/ob_i_store.h" #include "storage/ob_i_store.h"
#include "storage/ob_dml_param.h"
namespace oceanbase { namespace oceanbase {
namespace storage { namespace storage {
class ObValueRowIterator : public common::ObNewRowIterator { class ObValueRowIterator : public common::ObNewRowIterator {
...@@ -47,6 +48,50 @@ private: ...@@ -47,6 +48,50 @@ private:
DISALLOW_COPY_AND_ASSIGN(ObValueRowIterator); DISALLOW_COPY_AND_ASSIGN(ObValueRowIterator);
}; };
class ObSingleMerge;
class ObSingleRowGetter {
typedef common::ObFixedArray<int32_t, common::ObIAllocator> Projector;
public:
ObSingleRowGetter(common::ObIAllocator &allocator, ObPartitionStore &store);
~ObSingleRowGetter();
int init_dml_access_ctx(const ObStoreCtx &store_ctx, const ObDMLBaseParam &dml_param);
int init_dml_access_param(
ObRelativeTable &data_table, const ObDMLBaseParam &dml_param, const common::ObIArray<uint64_t> &out_col_ids);
ObTableAccessParam &get_access_param()
{
return access_param_;
}
ObTableAccessContext &get_access_ctx()
{
return access_ctx_;
}
void set_relative_table(ObRelativeTable *relative_table)
{
relative_table_ = relative_table;
}
int open(const ObStoreRowkey &rowkey, bool use_fuse_row_cache = false);
int get_next_row(common::ObNewRow *&row);
private:
int create_table_param();
private:
ObPartitionStore &store_;
ObSingleMerge *single_merge_;
const ObStoreCtx *store_ctx_;
Projector output_projector_;
ObTableAccessParam access_param_;
ObTableAccessContext access_ctx_;
ObGetTableParam get_table_param_;
ObRelativeTable *relative_table_;
share::schema::ObTableParam *table_param_;
union {
ObExtStoreRowkey ext_rowkey_;
};
common::ObIAllocator &allocator_;
};
} // end namespace storage } // end namespace storage
} // end namespace oceanbase } // end namespace oceanbase
......
...@@ -773,7 +773,11 @@ public: ...@@ -773,7 +773,11 @@ public:
{ {
return stmt_type_; return stmt_type_;
} }
const char* get_sql_id() const inline bool is_delete_stmt() const
{
return sql::stmt::T_DELETE == stmt_type_;
}
const char *get_sql_id() const
{ {
return sql_id_.ptr(); return sql_id_.ptr();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册