Skip to content

Commit d06c642

Browse files
fix bug replace into with timestamp type datum_memory use after free
1 parent 0d4f96a commit d06c642

File tree

1 file changed

+45
-31
lines changed

1 file changed

+45
-31
lines changed

src/sql/engine/dml/ob_table_replace_op.cpp

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -499,56 +499,70 @@ int ObTableReplaceOp::replace_conflict_row_cache()
499499
ObReplaceRtDef &replace_rtdef = replace_rtdefs_.at(0);
500500
ObInsRtDef &ins_rtdef = replace_rtdef.ins_rtdef_;
501501
ObDelRtDef &del_rtdef = replace_rtdef.del_rtdef_;
502+
const ObChunkDatumStore::StoredRow *replace_row = NULL;
502503

503504
NG_TRACE_TIMES(2, replace_start_shuff);
504-
OZ(replace_row_store_.begin(replace_row_iter));
505-
const ObChunkDatumStore::StoredRow *replace_row = NULL;
505+
if (OB_FAIL(replace_row_store_.begin(replace_row_iter))) {
506+
LOG_WARN("begin replace_row_store failed", K(ret), K(replace_row_store_.get_row_cnt()));
507+
}
506508
// 构建冲突的hash map的时候也使用的是column_ref, 回表也是使用的column_ref expr来读取scan的结果
507509
// 因为constarain_info中使用的column_ref expr,所以此处需要使用table_column_old_exprs (column_ref exprs)
508-
while (OB_SUCC(ret) && OB_SUCC(replace_row_iter.get_next_row(get_primary_table_new_row(),
509-
eval_ctx_,
510-
&replace_row))) {
510+
while (OB_SUCC(ret) && OB_SUCC(replace_row_iter.get_next_row(replace_row))) {
511511
constraint_values.reuse();
512512
ObChunkDatumStore::StoredRow *insert_new_row = NULL;
513-
OZ(conflict_checker_.check_duplicate_rowkey(replace_row,
514-
constraint_values,
515-
false));
513+
if (OB_ISNULL(replace_row)) {
514+
ret = OB_ERR_UNEXPECTED;
515+
LOG_WARN("replace_row is null", K(ret));
516+
} else if (OB_FAIL(conflict_checker_.check_duplicate_rowkey(replace_row,
517+
constraint_values,
518+
false))) {
519+
LOG_WARN("check rowkey from conflict_checker failed", K(ret), KPC(replace_row));
520+
}
521+
516522
for (int64_t i = 0; OB_SUCC(ret) && i < constraint_values.count(); ++i) {
517523
//delete duplicated row
518524
const ObChunkDatumStore::StoredRow *delete_row = constraint_values.at(i).current_datum_row_;
519525
bool same_row = false;
520-
CK(OB_NOT_NULL(delete_row));
521-
// dup checker依赖table column exprs
522-
OZ(delete_row->to_expr_skip_const(get_primary_table_old_row(), eval_ctx_));
523-
524-
// 外键的检查已经下方到dml_service逻辑中了
525-
OZ(ObDMLService::process_delete_row(del_ctdef, del_rtdef, skip_delete, *this));
526-
OZ(conflict_checker_.delete_old_row(delete_row, ObNewRowSource::FROM_INSERT));
527-
if (OB_SUCC(ret) && OB_LIKELY(MY_SPEC.only_one_unique_key_)) {
528-
OZ(check_values(same_row, replace_row, delete_row));
526+
if (OB_ISNULL(delete_row)) {
527+
ret = OB_ERR_UNEXPECTED;
528+
LOG_WARN("delete row failed", K(ret));
529+
} else if (OB_FAIL(delete_row->to_expr_skip_const(get_primary_table_old_row(), eval_ctx_))) {
530+
// dup checker依赖table column exprs
531+
LOG_WARN("flush delete_row to old_row failed", K(ret), KPC(delete_row), K(get_primary_table_old_row()));
532+
} else if (OB_FAIL(ObDMLService::process_delete_row(del_ctdef, del_rtdef, skip_delete, *this))) {
533+
LOG_WARN("process delete row failed", K(ret), KPC(delete_row), K(get_primary_table_old_row()));
534+
} else if (OB_FAIL(conflict_checker_.delete_old_row(delete_row, ObNewRowSource::FROM_INSERT))) {
535+
LOG_WARN("delete old_row from conflict checker failed", K(ret), KPC(delete_row));
536+
} else if (MY_SPEC.only_one_unique_key_) {
537+
if (OB_FAIL(check_values(same_row, replace_row, delete_row))) {
538+
LOG_WARN("check value failed", K(ret), KPC(replace_row), KPC(delete_row));
539+
}
529540
}
530541
if (OB_SUCC(ret) && !same_row) {
531542
delete_rows_++;
532543
}
533544
}
534545

535-
OZ(replace_row->to_expr_skip_const(get_primary_table_new_row(), eval_ctx_));
536-
OZ(ObDMLService::process_insert_row(ins_ctdef, ins_rtdef, *this, is_skipped));
537-
// TODO(yikang): fix trigger related for heap table
538-
if (OB_SUCC(ret) && ins_ctdef.is_primary_index_ && OB_FAIL(TriggerHandle::do_handle_after_row(*this,
539-
ins_ctdef.trig_ctdef_,
540-
ins_rtdef.trig_rtdef_,
541-
ObTriggerEvents::get_insert_event()))) {
546+
if (OB_FAIL(ret)) {
547+
// do nothing
548+
} else if (OB_FAIL(replace_row->to_expr_skip_const(get_primary_table_new_row(), eval_ctx_))) {
549+
LOG_WARN("flush replace_row to exprs failed", K(ret), KPC(replace_row));
550+
} else if (OB_FAIL(ObDMLService::process_insert_row(ins_ctdef, ins_rtdef, *this, is_skipped))) {
551+
LOG_WARN("convert exprs to stored_row failed", K(ret), KPC(insert_new_row));
552+
} else if (ins_ctdef.is_primary_index_ &&
553+
OB_FAIL(TriggerHandle::do_handle_after_row(*this,
554+
ins_ctdef.trig_ctdef_,
555+
ins_rtdef.trig_rtdef_,
556+
ObTriggerEvents::get_insert_event()))) {
542557
LOG_WARN("failed to handle before trigger", K(ret));
543-
}
544-
if (OB_SUCC(ret) && OB_UNLIKELY(is_skipped)) {
558+
} else if (OB_UNLIKELY(is_skipped)) {
545559
continue;
560+
} else if (OB_FAIL(conflict_checker_.convert_exprs_to_stored_row(get_primary_table_new_row(),
561+
insert_new_row))) {
562+
LOG_WARN("convert exprs to stored_row failed", K(ret), KPC(insert_new_row));
563+
} else if (OB_FAIL(conflict_checker_.insert_new_row(insert_new_row, ObNewRowSource::FROM_INSERT))) {
564+
LOG_WARN("insert new to conflict_checker failed", K(ret), KPC(insert_new_row));
546565
}
547-
OZ(conflict_checker_.convert_exprs_to_stored_row(get_primary_table_new_row(),
548-
insert_new_row));
549-
// add new row to conflict_checker map
550-
// 在insert_new_row 函数内部,会把replace_row to_expr到table_column_exprs<column_ref type>中
551-
OZ(conflict_checker_.insert_new_row(insert_new_row, ObNewRowSource::FROM_INSERT));
552566
} // while row store end
553567
ret = OB_ITER_END == ret ? OB_SUCCESS : ret;
554568
return ret;

0 commit comments

Comments
 (0)