Files
oceanbase/src/sql/resolver/dml/ob_del_upd_stmt.cpp
obdev 17abf2818a [FEAT MERGE] OB Support XMLType
Co-authored-by: simonjoylet <simonjoylet@gmail.com>
2023-04-28 03:45:10 +00:00

740 lines
29 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX SQL_RESV
#include "ob_del_upd_stmt.h"
#include "sql/rewrite/ob_transform_utils.h"
#include "sql/resolver/expr/ob_raw_expr_util.h"
#include "common/ob_smart_call.h"
#include "sql/optimizer/ob_optimizer_util.h"
using namespace oceanbase;
using namespace sql;
using namespace oceanbase::common;
int ObAssignment::deep_copy(ObIRawExprCopier &expr_copier,
const ObAssignment &other)
{
int ret = OB_SUCCESS;
ObRawExpr *new_col = NULL;
is_duplicated_ = other.is_duplicated_;
is_implicit_ = other.is_implicit_;
is_predicate_column_ = other.is_predicate_column_;
if (OB_FAIL(expr_copier.copy(other.column_expr_, new_col))) {
LOG_WARN("failed to copy column expr", K(ret));
} else if (OB_ISNULL(new_col) || OB_UNLIKELY(!new_col->is_column_ref_expr())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid new column expr", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.expr_, expr_))) {
LOG_WARN("failed to copy assign expr", K(ret));
} else {
column_expr_ = static_cast<ObColumnRefRawExpr *>(new_col);
}
return ret;
}
int ObAssignment::assign(const ObAssignment &other)
{
int ret = OB_SUCCESS;
column_expr_ = other.column_expr_;
expr_ = other.expr_;
is_duplicated_ = other.is_duplicated_;
is_implicit_ = other.is_implicit_;
is_predicate_column_ = other.is_predicate_column_;
return ret;
}
int ObDmlTableInfo::assign(const ObDmlTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(column_exprs_.assign(other.column_exprs_))) {
LOG_WARN("failed to copy expr", K(ret));
} else if (OB_FAIL(check_constraint_exprs_.assign(other.check_constraint_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(view_check_exprs_.assign(other.view_check_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(part_ids_.assign(other.part_ids_))) {
LOG_WARN("failed to assign part ids", K(ret));
} else {
table_id_ = other.table_id_;
loc_table_id_ = other.loc_table_id_;
ref_table_id_ = other.ref_table_id_;
table_name_ = other.table_name_;
table_type_ = other.table_type_;
is_link_table_ = other.is_link_table_;
need_filter_null_ = other.need_filter_null_;
}
return ret;
}
int ObDmlTableInfo::deep_copy(ObIRawExprCopier &expr_copier, const ObDmlTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(expr_copier.copy(other.column_exprs_, column_exprs_))) {
LOG_WARN("failed to copy expr", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.check_constraint_exprs_, check_constraint_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.view_check_exprs_, view_check_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(part_ids_.assign(other.part_ids_))) {
LOG_WARN("failed to assign part ids", K(ret));
} else {
table_id_ = other.table_id_;
loc_table_id_ = other.loc_table_id_;
ref_table_id_ = other.ref_table_id_;
table_name_ = other.table_name_;
table_type_ = other.table_type_;
is_link_table_ = other.is_link_table_;
need_filter_null_ = other.need_filter_null_;
}
return ret;
}
int ObDmlTableInfo::iterate_stmt_expr(ObStmtExprVisitor &visitor)
{
int ret = OB_SUCCESS;
if (OB_FAIL(visitor.visit(check_constraint_exprs_, SCOPE_DML_CONSTRAINT))) {
LOG_WARN("failed to visit check constraint exprs", K(ret));
} else if (OB_FAIL(visitor.visit(view_check_exprs_, SCOPE_DML_CONSTRAINT))) {
LOG_WARN("failed to visit view check constraint exprs", K(ret));
} else if (OB_FAIL(visitor.visit(column_exprs_, SCOPE_DML_COLUMN))) {
LOG_WARN("failed to visit dml column exprs", K(ret));
}
return ret;
}
int ObUpdateTableInfo::assign(const ObUpdateTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObDmlTableInfo::assign(other))) {
LOG_WARN("failed to assign base table info", K(ret));
} else if (OB_FAIL(assignments_.assign(other.assignments_))){
LOG_WARN("failed to assign assignments", K(ret));
} else { /*do nothing*/ }
return ret;
}
int ObUpdateTableInfo::deep_copy(ObIRawExprCopier &expr_copier,
const ObUpdateTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObDmlTableInfo::deep_copy(expr_copier, other))) {
LOG_WARN("failed to deep copy base table info", K(ret));
} else if (OB_FAIL(assignments_.prepare_allocate(other.assignments_.count()))) {
LOG_WARN("failed to do propare allocate array", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < assignments_.count(); i++) {
if (OB_FAIL(assignments_.at(i).deep_copy(expr_copier, other.assignments_.at(i)))) {
LOG_WARN("failed to deep copy expr", K(ret));
} else { /*do nothing*/ }
}
}
return ret;
}
int ObUpdateTableInfo::iterate_stmt_expr(ObStmtExprVisitor &visitor)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObDmlTableInfo::iterate_stmt_expr(visitor))) {
LOG_WARN("failed to iterate stmt expr", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < assignments_.count(); ++i) {
ObAssignment &assign = assignments_.at(i);
if (OB_FAIL(visitor.visit(assign.column_expr_, SCOPE_DML_COLUMN))) {
LOG_WARN("failed to visit assign column expr", K(ret));
} else if (OB_FAIL(visitor.visit(assign.expr_, SCOPE_DML_VALUE))) {
LOG_WARN("failed to visit assign new value", K(ret));
}
}
return ret;
}
int ObInsertTableInfo::assign(const ObInsertTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObDmlTableInfo::assign(other))) {
LOG_WARN("failed to assign table info", K(ret));
} else if (OB_FAIL(values_desc_.assign(other.values_desc_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(values_vector_.assign(other.values_vector_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(column_conv_exprs_.assign(other.column_conv_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(part_generated_col_dep_cols_.assign(other.part_generated_col_dep_cols_))) {
LOG_WARN("failed to assign part generated col dep cols", K(ret));
} else if (OB_FAIL(assignments_.assign(other.assignments_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else {
is_replace_ = other.is_replace_;
}
return ret;
}
int ObInsertTableInfo::deep_copy(ObIRawExprCopier &expr_copier,
const ObInsertTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObDmlTableInfo::deep_copy(expr_copier, other))) {
LOG_WARN("failed to deep copy table info", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.values_desc_, values_desc_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.values_vector_, values_vector_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.column_conv_exprs_, column_conv_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.part_generated_col_dep_cols_,
part_generated_col_dep_cols_))) {
LOG_WARN("failed to copy other.part_generated_col_dep_cols_", K(ret));
} else if (OB_FAIL(assignments_.prepare_allocate(other.assignments_.count()))) {
LOG_WARN("failed to do propare allocate array", K(ret));
} else {
is_replace_ = other.is_replace_;
for (int64_t i = 0; OB_SUCC(ret) && i < assignments_.count(); i++) {
if (OB_FAIL(assignments_.at(i).deep_copy(expr_copier, other.assignments_.at(i)))) {
LOG_WARN("failed to deep copy expr", K(ret));
} else { /*do nothing*/}
}
}
return ret;
}
int ObInsertTableInfo::iterate_stmt_expr(ObStmtExprVisitor &visitor)
{
int ret = OB_SUCCESS;
int64_t value_desc_cnt = values_desc_.count();
if (OB_FAIL(ObDmlTableInfo::iterate_stmt_expr(visitor))) {
LOG_WARN("failed to iterate dml table info", K(ret));
} else if (OB_FAIL(visitor.visit(values_desc_, SCOPE_INSERT_DESC))) {
LOG_WARN("failed to iterate valeus desc exprs", K(ret));
} else if (OB_FAIL(visitor.visit(column_conv_exprs_, SCOPE_DML_VALUE))) {
LOG_WARN("failed to iterate column conv exprs", K(ret));
} else if (OB_FAIL(visitor.visit(part_generated_col_dep_cols_, SCOPE_DICT_FIELDS))) {
LOG_WARN("failed to iterate part generated col dep cols", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < value_desc_cnt; ++i) {
const ObColumnRefRawExpr *col_expr = values_desc_.at(i);
if (OB_ISNULL(col_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column expr is null", K(ret));
} else if (col_expr->is_table_part_key_column()) {
for (int64_t j = i; OB_SUCC(ret) && j < values_vector_.count(); j += value_desc_cnt) {
if (OB_FAIL(visitor.visit(values_vector_.at(j), SCOPE_INSERT_VECTOR))) {
LOG_WARN("add expr to expr checker failed", K(ret), K(i), K(j));
}
}
}
}
// !value_from_select() && !subquery_exprs_.empty()
for (int64_t i = 0; OB_SUCC(ret) && i < values_vector_.count(); ++i) {
if (OB_ISNULL(values_vector_.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if ((values_vector_.at(i)->has_flag(CNT_SUB_QUERY) ||
values_vector_.at(i)->has_flag(CNT_ONETIME)) &&
OB_FAIL(visitor.visit(values_vector_.at(i), SCOPE_INSERT_VECTOR))) {
LOG_WARN("failed to add expr to expr checker", K(ret));
} else { /*do nothing*/ }
}
for (int64_t i = 0; OB_SUCC(ret) && i < assignments_.count(); ++i) {
ObAssignment &assign = assignments_.at(i);
if (OB_FAIL(visitor.visit(assign.column_expr_, SCOPE_DML_COLUMN))) {
LOG_WARN("failed to visit assign column expr", K(ret));
} else if (OB_FAIL(visitor.visit(assign.expr_, SCOPE_DML_VALUE))) {
LOG_WARN("failed to visit assign new value", K(ret));
}
}
return ret;
}
int ObMergeTableInfo::assign(const ObMergeTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObInsertTableInfo::assign(other))) {
LOG_WARN("failed to assign table info", K(ret));
} else if (OB_FAIL(match_condition_exprs_.assign(other.match_condition_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(insert_condition_exprs_.assign(other.insert_condition_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(update_condition_exprs_.assign(other.update_condition_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else if (OB_FAIL(delete_condition_exprs_.assign(other.delete_condition_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else {
source_table_id_ = other.source_table_id_;
target_table_id_ = other.target_table_id_;
}
return ret;
}
int ObMergeTableInfo::deep_copy(ObIRawExprCopier &expr_copier,
const ObMergeTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObInsertTableInfo::deep_copy(expr_copier, other))) {
LOG_WARN("failed to deep copy table info", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.match_condition_exprs_, match_condition_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.insert_condition_exprs_, insert_condition_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.update_condition_exprs_, update_condition_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.delete_condition_exprs_, delete_condition_exprs_))) {
LOG_WARN("failed to copy exprs", K(ret));
} else {
source_table_id_ = other.source_table_id_;
target_table_id_ = other.target_table_id_;
}
return ret;
}
int ObMergeTableInfo::iterate_stmt_expr(ObStmtExprVisitor &visitor)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObInsertTableInfo::iterate_stmt_expr(visitor))) {
LOG_WARN("failed to iterate stmt expr", K(ret));
} else if (OB_FAIL(visitor.visit(match_condition_exprs_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit match condition exprs", K(ret));
} else if (OB_FAIL(visitor.visit(update_condition_exprs_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit update condition exprs", K(ret));
} else if (OB_FAIL(visitor.visit(insert_condition_exprs_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit insert condition exprs", K(ret));
} else if (OB_FAIL(visitor.visit(delete_condition_exprs_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit delete condition exprs", K(ret));
} else if (OB_FAIL(visitor.visit(values_vector_, SCOPE_INSERT_VECTOR))) {
LOG_WARN("failed to add expr to expr checker", K(ret));
}
return ret;
}
int ObInsertAllTableInfo::assign(const ObInsertAllTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObInsertTableInfo::assign(other))) {
LOG_WARN("failed to assign table info", K(ret));
} else if (OB_FAIL(when_cond_exprs_.assign(other.when_cond_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else {
when_cond_idx_ = other.when_cond_idx_;
}
return ret;
}
int ObInsertAllTableInfo::deep_copy(ObIRawExprCopier &expr_copier,
const ObInsertAllTableInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObInsertTableInfo::deep_copy(expr_copier, other))) {
LOG_WARN("failed to deep copy table info", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.when_cond_exprs_, when_cond_exprs_))) {
LOG_WARN("failed to copy when condition exprs", K(ret));
} else {
when_cond_idx_ = other.when_cond_idx_;
}
return ret;
}
int ObInsertAllTableInfo::iterate_stmt_expr(ObStmtExprVisitor &visitor)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObInsertTableInfo::iterate_stmt_expr(visitor))) {
LOG_WARN("failed to iterate stmt expr", K(ret));
} else if (OB_FAIL(visitor.visit(when_cond_exprs_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to iterate stmt expr", K(ret));
}
return ret;
}
int ObErrLogInfo::assign(const ObErrLogInfo &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(error_log_exprs_.assign(other.error_log_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else {
is_error_log_ = other.is_error_log_;
table_id_ = other.table_id_;
table_name_ = other.table_name_;
database_name_ = other.database_name_;
reject_limit_ = other.reject_limit_;
}
return ret;
}
int ObErrLogInfo::deep_copy(const ObErrLogInfo &other,
ObRawExprCopier &expr_copier)
{
int ret = OB_SUCCESS;
if (OB_FAIL(expr_copier.copy(other.error_log_exprs_, error_log_exprs_))) {
LOG_WARN("failed to assign exprs", K(ret));
} else {
is_error_log_ = other.is_error_log_;
table_id_ = other.table_id_;
table_name_ = other.table_name_;
database_name_ = other.database_name_;
reject_limit_ = other.reject_limit_;
}
return ret;
}
int ObDelUpdStmt::deep_copy_stmt_struct(ObIAllocator &allocator,
ObRawExprCopier &expr_copier,
const ObDMLStmt &input)
{
int ret = OB_SUCCESS;
const ObDelUpdStmt &other = static_cast<const ObDelUpdStmt &>(input);
if (OB_UNLIKELY(input.get_stmt_type() != get_stmt_type())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt type does not match", K(ret), K(input.get_stmt_type()), K(get_stmt_type()));
} else if (OB_FAIL(ObDMLStmt::deep_copy_stmt_struct(allocator, expr_copier, other))) {
LOG_WARN("failed to deep copy stmt structure", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.returning_exprs_,
returning_exprs_))) {
LOG_WARN("failed to deep copy returning fileds", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.returning_into_exprs_,
returning_into_exprs_))) {
LOG_WARN("failed to deep copy returning into fields", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.returning_agg_items_,
returning_agg_items_))) {
LOG_WARN("failed to deep copy returning aggregation exprs", K(ret));
} else if (OB_FAIL(deep_copy_stmt_objects<OrderItem>(expr_copier,
other.order_items_,
order_items_))) {
LOG_WARN("deep copy order items failed", K(ret));
} else if (OB_FAIL(returning_strs_.assign(other.returning_strs_))) {
LOG_WARN("failed to assign returning strings", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.sharding_conditions_, sharding_conditions_))) {
LOG_WARN("failed to copy sharding conditions", K(ret));
} else if (OB_FAIL(expr_copier.copy(other.ab_stmt_id_expr_, ab_stmt_id_expr_))) {
LOG_WARN("copy ab_stmt_id_expr_ failed", K(ret));
} else if (OB_FAIL(error_log_info_.deep_copy(other.error_log_info_, expr_copier))) {
LOG_WARN("failed to deep copy error log info", K(ret));
} else {
ignore_ = other.ignore_;
has_global_index_ = other.has_global_index_;
has_instead_of_trigger_ = other.has_instead_of_trigger_;
}
return ret;
}
int ObDelUpdStmt::assign(const ObDelUpdStmt &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObDMLStmt::assign(other))) {
LOG_WARN("failed to copy stmt", K(ret));
} else if (OB_FAIL(returning_strs_.assign(other.returning_strs_))) {
LOG_WARN("failed to assign returning strs", K(ret));
} else if (OB_FAIL(returning_agg_items_.assign(other.returning_agg_items_))) {
LOG_WARN("failed to assign returning agg items", K(ret));
} else if (OB_FAIL(returning_into_exprs_.assign(other.returning_into_exprs_))) {
LOG_WARN("failed to assign returning into exprs", K(ret));
} else if (OB_FAIL(error_log_info_.assign(other.error_log_info_))) {
LOG_WARN("failed to assign error log info", K(ret));
} else if (OB_FAIL(sharding_conditions_.assign(other.sharding_conditions_))) {
LOG_WARN("failed to assign sharding conditions", K(ret));
} else {
ignore_ = other.ignore_;
has_global_index_ = other.has_global_index_;
has_instead_of_trigger_ = other.has_instead_of_trigger_;
ab_stmt_id_expr_ = other.ab_stmt_id_expr_;
}
return ret;
}
bool ObDelUpdStmt::is_dml_table_from_join() const
{
const TableItem *table_item = NULL;
return get_from_item_size() > 1 ||
(NULL != (table_item = get_table_item(get_from_item(0))) &&
!table_item->is_basic_table());
}
int64_t ObDelUpdStmt::get_instead_of_trigger_column_count() const
{
return 0;
}
int ObDelUpdStmt::iterate_stmt_expr(ObStmtExprVisitor &visitor)
{
int ret = OB_SUCCESS;
ObSEArray<ObDmlTableInfo *, 4> dml_table_infos;
if (OB_FAIL(ObDMLStmt::iterate_stmt_expr(visitor))) {
LOG_WARN("failed to visit DMLStmt expr", K(ret));
} else if (OB_FAIL(visitor.visit(returning_exprs_, SCOPE_RETURNING))) {
LOG_WARN("failed to visit returning exprs", K(ret));
} else if (OB_FAIL(visitor.visit(returning_into_exprs_, SCOPE_RETURNING))) {
LOG_WARN("failed to visit returning into exprs", K(ret));
} else if (OB_FAIL(visitor.visit(returning_agg_items_, SCOPE_DICT_FIELDS))) {
LOG_WARN("failed to visit returning agg items", K(ret));
} else if (ab_stmt_id_expr_ != NULL &&
OB_FAIL(visitor.visit(ab_stmt_id_expr_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit ab stmt id expr", K(ret));
} else if (OB_FAIL(visitor.visit(error_log_info_.error_log_exprs_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit errlog exprs", K(ret));
} else if (OB_FAIL(visitor.visit(sharding_conditions_, SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit sharding conditions", K(ret));
} else if (OB_FAIL(get_dml_table_infos(dml_table_infos))) {
LOG_WARN("failed to get dml table infos", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < dml_table_infos.count(); ++i) {
if (OB_ISNULL(dml_table_infos.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dml table info is null", K(ret));
} else if (OB_FAIL(dml_table_infos.at(i)->iterate_stmt_expr(visitor))) {
LOG_WARN("failed to itearte dml table infos", K(ret));
} else if (dml_table_infos.at(i)->table_id_ != OB_INVALID_ID &&
dml_table_infos.at(i)->table_id_ != dml_table_infos.at(i)->loc_table_id_) {
// handle updatable view in a speical way
for (int64_t j = 0; OB_SUCC(ret) && j < part_expr_items_.count(); ++j) {
if (part_expr_items_.at(j).table_id_ == dml_table_infos.at(i)->loc_table_id_) {
if (OB_FAIL(visitor.visit(part_expr_items_.at(j).part_expr_,
SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit part expr items", K(ret));
} else if (OB_FAIL(visitor.visit(part_expr_items_.at(j).subpart_expr_,
SCOPE_DMLINFOS))) {
LOG_WARN("failed to visit subpart exprs", K(ret));
}
}
}
}
}
return ret;
}
int ObDelUpdStmt::update_base_tid_cid()
{
int ret = OB_SUCCESS;
ObSEArray<ObDmlTableInfo*, 2> table_info;
if (OB_FAIL(get_dml_table_infos(table_info))) {
LOG_WARN("failed to get dml table info", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < table_info.count(); i++) {
ObDmlTableInfo *dml_table = NULL;
ObIArray<ObAssignment> *table_assignments = NULL;
if (OB_ISNULL(dml_table = table_info.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else {
uint64_t base_tid = OB_INVALID_ID;
for (int64_t j = 0; OB_SUCC(ret) && j < dml_table->column_exprs_.count(); j++) {
ObColumnRefRawExpr *col = dml_table->column_exprs_.at(j);
ColumnItem *col_item = NULL;
if (OB_ISNULL(col)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column expr is null", K(ret), K(col));
} else if (IS_SHADOW_COLUMN(col->get_column_id())) {
// do nothing
} else if (OB_ISNULL(
col_item = get_column_item_by_id(col->get_table_id(), col->get_column_id()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column item is not found", K(ret), K(*col), K(col_item));
} else if (OB_FAIL(ObTransformUtils::get_base_column(this, col))) {
LOG_WARN("failed to get column base info", K(ret));
} else if (OB_ISNULL(col)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(col), K(ret));
} else {
col_item->base_tid_ = col->get_table_id();
col_item->base_cid_ = col->get_column_id();
if (OB_UNLIKELY(col_item->base_tid_ == OB_INVALID_ID) ||
OB_UNLIKELY(j != 0 && col_item->base_tid_ != base_tid)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("base table id is invalid", K(ret), K(col_item->base_tid_), K(base_tid));
} else if (j == 0) {
base_tid = col_item->base_tid_;
}
}
}
if (OB_FAIL(ret)) {
/*do nothing*/
} else if (dml_table->is_update_table()) {
table_assignments = &static_cast<ObUpdateTableInfo*>(dml_table)->assignments_;
} else if (dml_table->is_insert_table() || dml_table->is_merge_table()) {
table_assignments = &static_cast<ObInsertTableInfo*>(dml_table)->assignments_;
} else { /*do nothing*/ }
if (OB_SUCC(ret) && dml_table->loc_table_id_ != base_tid) {
for (int64_t k = 0; OB_SUCC(ret) && k < part_expr_items_.count(); ++k) {
if (part_expr_items_.at(k).table_id_ == dml_table->loc_table_id_ &&
part_expr_items_.at(k).index_tid_ == dml_table->ref_table_id_) {
part_expr_items_.at(k).table_id_ = base_tid;
}
}
dml_table->loc_table_id_ = base_tid;
}
}
}
}
return ret;
}
int ObDelUpdStmt::check_part_key_is_updated(const ObIArray<ObAssignment> &assigns,
bool &is_updated) const
{
int ret = OB_SUCCESS;
is_updated = false;
for (int64_t i = 0; OB_SUCC(ret) && !is_updated && i < assigns.count(); i++) {
ObColumnRefRawExpr *col_expr = assigns.at(i).column_expr_;
if (OB_ISNULL(col_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (IS_SHADOW_COLUMN(col_expr->get_column_id())) {
// do nothing
} else if (OB_FAIL(ObTransformUtils::get_base_column(this, col_expr))) {
LOG_WARN("failed to get base column", K(ret));
} else if (OB_ISNULL(col_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (col_expr->is_table_part_key_column() || col_expr->is_table_part_key_org_column()) {
is_updated = true;
} else { /*do nothing*/ }
}
return ret;
}
int ObDelUpdStmt::get_assignments_exprs(ObIArray<ObRawExpr*> &exprs) const
{
UNUSED(exprs);
return false;
}
int ObDelUpdStmt::get_dml_table_infos(ObIArray<ObDmlTableInfo*>& dml_table_info)
{
UNUSED(dml_table_info);
return OB_SUCCESS;
}
int ObDelUpdStmt::get_dml_table_infos(ObIArray<const ObDmlTableInfo*>& dml_table_info) const
{
UNUSED(dml_table_info);
return OB_SUCCESS;
}
int ObDelUpdStmt::get_view_check_exprs(ObIArray<ObRawExpr*>& view_check_exprs) const
{
UNUSED(view_check_exprs);
return OB_SUCCESS;
}
int ObDelUpdStmt::get_value_exprs(ObIArray<ObRawExpr *> &value_exprs) const
{
UNUSED(value_exprs);
return OB_SUCCESS;
}
int ObDelUpdStmt::remove_table_item_dml_info(const TableItem* table)
{
int ret = OB_ERR_UNEXPECTED;
LOG_WARN("can not remove all dml table", K(ret));
return ret;
}
int ObDelUpdStmt::has_dml_table_info(const uint64_t table_id, bool &has) const
{
int ret = OB_SUCCESS;
ObSEArray<const ObDmlTableInfo *, 2> table_infos;
has = false;
if (OB_FAIL(get_dml_table_infos(table_infos))) {
LOG_WARN("failed to get dml table infos", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < table_infos.count(); ++i) {
if (OB_ISNULL(table_infos.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table info is null", K(ret));
} else if (table_infos.at(i)->table_id_ == table_id) {
has = true;
break;
}
}
return ret;
}
int ObDelUpdStmt::check_dml_need_filter_null()
{
int ret = OB_SUCCESS;
ObSEArray<uint64_t, 4> table_ids;
ObSEArray<ObDmlTableInfo*, 4> dml_table_infos;
for (int64_t i = 0; OB_SUCC(ret) && i < joined_tables_.count(); ++i) {
if (OB_FAIL(extract_need_filter_null_table(joined_tables_.at(i), table_ids))) {
LOG_WARN("recursively check filter null failed", K(ret), K(joined_tables_));
}
}
if (OB_SUCC(ret) && !table_ids.empty()) {
if (OB_FAIL(get_dml_table_infos(dml_table_infos))) {
LOG_WARN("failed to get dml talbe infos", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < dml_table_infos.count(); ++i) {
if (OB_ISNULL(dml_table_infos.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get null dml table info", K(ret), K(i), K(dml_table_infos));
} else if (ObOptimizerUtil::find_item(table_ids, dml_table_infos.at(i)->table_id_)) {
dml_table_infos.at(i)->need_filter_null_ = true;
}
}
}
return ret;
}
int ObDelUpdStmt::extract_need_filter_null_table(const JoinedTable *cur_table,
ObIArray<uint64_t> &table_ids)
{
int ret = OB_SUCCESS;
bool need_check_left = false;
bool need_check_right = false;
if (OB_ISNULL(cur_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get null joined table", K(ret), K(cur_table));
} else if (FULL_OUTER_JOIN == cur_table->joined_type_) {
if (OB_FAIL(append(table_ids, cur_table->single_table_ids_))) {
LOG_WARN("failed to append table ids", K(ret));
}
} else if (LEFT_OUTER_JOIN == cur_table->joined_type_ ||
RIGHT_OUTER_JOIN == cur_table->joined_type_) {
const TableItem *child_table = NULL;
if (LEFT_OUTER_JOIN == cur_table->joined_type_) {
need_check_left = true;
child_table = cur_table->right_table_;
} else {
need_check_right = true;
child_table = cur_table->left_table_;
}
if (OB_ISNULL(child_table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("child table is null", K(ret));
} else if (child_table->is_joined_table()) {
const JoinedTable *join_table = static_cast<const JoinedTable*>(child_table);
if (OB_FAIL(append(table_ids, join_table->single_table_ids_))) {
LOG_WARN("failed to append table ids", K(ret));
}
} else if (OB_FAIL(table_ids.push_back(child_table->table_id_))) {
LOG_WARN("failed to push back table id", K(ret));
}
} else {
need_check_left = true;
need_check_right = true;
}
if (OB_SUCC(ret) && need_check_left && OB_NOT_NULL(cur_table->left_table_) &&
cur_table->left_table_->is_joined_table()) {
const JoinedTable *left_table = static_cast<const JoinedTable*>(cur_table->left_table_);
if (OB_FAIL(SMART_CALL(extract_need_filter_null_table(left_table, table_ids)))) {
LOG_WARN("failed to extract need filter null table", K(ret));
}
}
if (OB_SUCC(ret) && need_check_right && OB_NOT_NULL(cur_table->right_table_) &&
cur_table->right_table_->is_joined_table()) {
const JoinedTable *right_table = static_cast<const JoinedTable*>(cur_table->right_table_);
if (OB_FAIL(SMART_CALL(extract_need_filter_null_table(right_table, table_ids)))) {
LOG_WARN("failed to extract need filter null table", K(ret));
}
}
return ret;
}