patch 4.0
This commit is contained in:
@ -14,265 +14,152 @@
|
||||
#define OCEANBASE_SQL_ENGINE_DML_OB_TABLE_MODIFY_OP_
|
||||
|
||||
#include "sql/engine/ob_operator.h"
|
||||
#include "sql/engine/dml/ob_table_modify.h"
|
||||
#include "sql/engine/dml/ob_dml_ctx_define.h"
|
||||
#include "observer/ob_inner_sql_connection.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
class ForeignKeyHandle
|
||||
{
|
||||
public:
|
||||
struct ObFkRowResInfo
|
||||
{
|
||||
ObExpr* rt_expr_;
|
||||
ObDatum ori_datum_;
|
||||
TO_STRING_KV(K_(rt_expr), K_(ori_datum));
|
||||
};
|
||||
static int do_handle(ObTableModifyOp &op,
|
||||
const ObDMLBaseCtDef &dml_ctdef,
|
||||
ObDMLBaseRtDef &dml_rtdef);
|
||||
private:
|
||||
static int value_changed(ObTableModifyOp &op,
|
||||
const common::ObIArray<ObForeignKeyColumn> &columns,
|
||||
const ObExprPtrIArray &old_row,
|
||||
const ObExprPtrIArray &new_row,
|
||||
bool &has_changed);
|
||||
static int check_exist(ObTableModifyOp &modify_op, const ObForeignKeyArg &fk_arg,
|
||||
const ObExprPtrIArray &row, bool expect_zero);
|
||||
static int cascade(ObTableModifyOp &modify_op, const ObForeignKeyArg &fk_arg,
|
||||
const ObExprPtrIArray &old_row, const ObExprPtrIArray &new_row);
|
||||
static int gen_set(ObEvalCtx &eval_ctx, char *&buf, int64_t &len, int64_t &pos,
|
||||
const common::ObIArray<ObForeignKeyColumn> &columns,
|
||||
const ObExprPtrIArray &row, common::ObIAllocator &alloc,
|
||||
const common::ObObjPrintParams &print_params);
|
||||
static int gen_where(ObEvalCtx &eval_ctx, char *&buf, int64_t &len, int64_t &pos,
|
||||
const common::ObIArray<ObForeignKeyColumn> &columns,
|
||||
const ObExprPtrIArray &row, common::ObIAllocator &alloc,
|
||||
const common::ObObjPrintParams &print_params);
|
||||
static int gen_column_value(ObEvalCtx &ctx, char *&buf, int64_t &len, int64_t &pos,
|
||||
const common::ObIArray<ObForeignKeyColumn> &columns,
|
||||
const ObExprPtrIArray &row, const char *delimiter,
|
||||
common::ObIAllocator &alloc,
|
||||
const common::ObObjPrintParams &print_params, bool forbid_null);
|
||||
static int is_self_ref_row(ObEvalCtx &ctx, const ObExprPtrIArray &row,
|
||||
const ObForeignKeyArg &fk_arg, bool &is_self_ref);
|
||||
};
|
||||
|
||||
class ObTableModifyOp;
|
||||
class ObTableModifySpec : public ObOpSpec {
|
||||
class ObTableModifySpec : public ObOpSpec
|
||||
{
|
||||
OB_UNIS_VERSION_V(1);
|
||||
|
||||
public:
|
||||
ObTableModifySpec(common::ObIAllocator& alloc, const ObPhyOperatorType type);
|
||||
virtual ~ObTableModifySpec()
|
||||
{}
|
||||
ObTableModifySpec(common::ObIAllocator &alloc, const ObPhyOperatorType type);
|
||||
virtual ~ObTableModifySpec() {}
|
||||
|
||||
inline void set_from_multi_table_dml(bool from_multi_table_dml)
|
||||
virtual bool is_dml_operator() const override { return true; }
|
||||
//This interface is only allowed to be used in a single-table DML operator,
|
||||
//it is invalid when multiple tables are modified in one DML operator
|
||||
int get_single_table_loc_id(common::ObTableID &table_loc_id,
|
||||
common::ObTableID &ref_table_id) const
|
||||
{
|
||||
from_multi_table_dml_ = from_multi_table_dml;
|
||||
const ObDMLBaseCtDef *dml_ctdef = nullptr;
|
||||
int ret = get_single_dml_ctdef(dml_ctdef);
|
||||
if (common::OB_SUCCESS == ret) {
|
||||
table_loc_id = dml_ctdef->das_base_ctdef_.table_id_;
|
||||
ref_table_id = dml_ctdef->das_base_ctdef_.index_tid_;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
inline bool from_multi_table_dml() const
|
||||
//This interface is only allowed to be used in a single-table DML operator,
|
||||
//it is invalid when multiple tables are modified in one DML operator
|
||||
virtual int get_single_dml_ctdef(const ObDMLBaseCtDef *&dml_ctdef) const
|
||||
{
|
||||
return from_multi_table_dml_;
|
||||
UNUSED(dml_ctdef);
|
||||
return common::OB_NOT_IMPLEMENT;
|
||||
}
|
||||
|
||||
virtual bool is_dml_operator() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int init_column_ids_count(int64_t count)
|
||||
{
|
||||
return column_ids_.init(count);
|
||||
}
|
||||
|
||||
int init_primary_key_ids(int64_t rowkey_cnt)
|
||||
{
|
||||
return primary_key_ids_.init(rowkey_cnt);
|
||||
}
|
||||
int add_primary_key_id(uint64_t rowkey_id)
|
||||
{
|
||||
return primary_key_ids_.push_back(rowkey_id);
|
||||
}
|
||||
int set_primary_key_ids(const ObIArray<uint64_t>& pri_col_ids)
|
||||
{
|
||||
return primary_key_ids_.assign(pri_col_ids);
|
||||
}
|
||||
int primary_key_count() const
|
||||
{
|
||||
return primary_key_ids_.count();
|
||||
}
|
||||
|
||||
int init_column_infos_count(int64_t count)
|
||||
{
|
||||
return column_infos_.init(count);
|
||||
}
|
||||
int add_column_info(const ColumnContent& column);
|
||||
|
||||
int init_column_conv_info_count(int64_t count)
|
||||
{
|
||||
return column_conv_infos_.init(count);
|
||||
}
|
||||
|
||||
int add_column_conv_info(const ObExprResType& res_type, const uint64_t column_flags, common::ObIAllocator& allocator,
|
||||
const common::ObIArray<common::ObString>* str_values = NULL);
|
||||
int init_foreign_key_args(int64_t fk_count);
|
||||
int add_foreign_key_arg(const ObForeignKeyArg& fk_arg);
|
||||
|
||||
const ObForeignKeyArgArray& get_fk_args() const
|
||||
{
|
||||
return fk_args_;
|
||||
}
|
||||
|
||||
int32_t get_column_idx(uint64_t column_id);
|
||||
int add_column_id(uint64_t column_id);
|
||||
|
||||
uint64_t get_table_id() const
|
||||
{
|
||||
return table_id_;
|
||||
}
|
||||
uint64_t get_index_tid() const
|
||||
{
|
||||
return index_tid_;
|
||||
}
|
||||
share::schema::ObTableDMLParam& get_table_param()
|
||||
{
|
||||
return table_param_;
|
||||
}
|
||||
const common::ObIArray<uint64_t>& get_column_ids()
|
||||
{
|
||||
return column_ids_;
|
||||
}
|
||||
|
||||
bool need_skip_log_user_error() const
|
||||
{
|
||||
return need_skip_log_user_error_;
|
||||
}
|
||||
void set_need_skip_log_user_error(bool need_skip_log_user_error)
|
||||
{
|
||||
need_skip_log_user_error_ = need_skip_log_user_error;
|
||||
}
|
||||
void set_table_location_uncertain(bool v)
|
||||
{
|
||||
table_location_uncertain_ = v;
|
||||
}
|
||||
bool is_table_location_uncertain() const
|
||||
{
|
||||
return table_location_uncertain_;
|
||||
}
|
||||
virtual bool is_multi_dml() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_table_location_uncertain(bool v) { table_location_uncertain_ = v; }
|
||||
bool is_table_location_uncertain() const { return table_location_uncertain_; }
|
||||
inline bool use_dist_das() const { return use_dist_das_; }
|
||||
inline bool has_instead_of_trigger() const { return has_instead_of_trigger_; }
|
||||
public:
|
||||
virtual bool has_foreign_key() const;
|
||||
|
||||
public:
|
||||
uint64_t table_id_;
|
||||
uint64_t index_tid_;
|
||||
bool is_ignore_;
|
||||
bool from_multi_table_dml_;
|
||||
common::ObFixedArray<uint64_t, common::ObIAllocator> column_ids_;
|
||||
common::ObFixedArray<uint64_t, common::ObIAllocator> primary_key_ids_;
|
||||
common::ObFixedArray<ColumnContent, common::ObIAllocator> column_infos_;
|
||||
common::ObFixedArray<ObColumnConvInfo, common::ObIAllocator> column_conv_infos_;
|
||||
// output row for storage process, for prepare_next_storage_row() interface.
|
||||
ExprFixedArray storage_row_output_;
|
||||
ExprFixedArray returning_exprs_;
|
||||
ExprFixedArray check_constraint_exprs_;
|
||||
ObForeignKeyArgArray fk_args_;
|
||||
uint64_t tg_event_;
|
||||
share::schema::ObTableDMLParam table_param_;
|
||||
bool need_filter_null_row_;
|
||||
DistinctType distinct_algo_;
|
||||
bool gi_above_;
|
||||
bool is_returning_;
|
||||
ObExpr* lock_row_flag_expr_;
|
||||
bool is_pdml_index_maintain_;
|
||||
bool need_skip_log_user_error_;
|
||||
bool table_location_uncertain_;
|
||||
|
||||
// Expr frame info for partial expr serialization. (serialize is not need for it self)
|
||||
ObExprFrameInfo *expr_frame_info_;
|
||||
ObExpr *ab_stmt_id_; //mark the stmt id for array binding batch execution
|
||||
union {
|
||||
uint64_t flags_;
|
||||
struct {
|
||||
uint64_t is_ignore_ : 1;
|
||||
uint64_t gi_above_ : 1;
|
||||
uint64_t is_returning_ : 1;
|
||||
uint64_t is_pdml_index_maintain_ : 1; // 表示当前dml算子是否是pdml中用于维护索引操作的算子(index maintain)
|
||||
uint64_t table_location_uncertain_ : 1; // 目标访问分区位置不确定,需要全表访问
|
||||
uint64_t use_dist_das_ : 1;
|
||||
uint64_t has_instead_of_trigger_ : 1;
|
||||
uint64_t is_pdml_update_split_ : 1; // 标记delete, insert op是否由update拆分而来
|
||||
uint64_t reserved_ : 56;
|
||||
};
|
||||
};
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObTableModifySpec);
|
||||
};
|
||||
|
||||
class ObTableModifyOpInput : public ObOpInput {
|
||||
class ObTableModifyOpInput : public ObOpInput
|
||||
{
|
||||
public:
|
||||
friend class ObTableModifyOp;
|
||||
OB_UNIS_VERSION_V(1);
|
||||
|
||||
public:
|
||||
ObTableModifyOpInput(ObExecContext& ctx, const ObOpSpec& spec)
|
||||
: ObOpInput(ctx, spec), location_idx_(common::OB_INVALID_INDEX), part_infos_()
|
||||
{}
|
||||
virtual ~ObTableModifyOpInput()
|
||||
{}
|
||||
virtual void reset() override
|
||||
ObTableModifyOpInput(ObExecContext &ctx, const ObOpSpec &spec)
|
||||
: ObOpInput(ctx, spec),
|
||||
table_loc_(nullptr),
|
||||
tablet_loc_(nullptr)
|
||||
{ }
|
||||
virtual ~ObTableModifyOpInput() { }
|
||||
virtual int init(ObTaskInfo &task_info) override { UNUSED(task_info); return common::OB_SUCCESS; }
|
||||
virtual void reset()
|
||||
{
|
||||
location_idx_ = common::OB_INVALID_INDEX;
|
||||
part_infos_.reset();
|
||||
table_loc_ = nullptr;
|
||||
tablet_loc_ = nullptr;
|
||||
}
|
||||
virtual int init(ObTaskInfo& task_info) override;
|
||||
inline int64_t get_location_idx() const
|
||||
inline void set_tablet_loc(ObDASTabletLoc *tablet_loc) { tablet_loc_ = tablet_loc; }
|
||||
inline ObDASTabletLoc *get_tablet_loc() { return tablet_loc_; }
|
||||
inline ObDASTableLoc *get_table_loc() { return table_loc_; }
|
||||
const ObTableModifySpec &get_spec() const
|
||||
{
|
||||
return location_idx_;
|
||||
return static_cast<const ObTableModifySpec &>(spec_);
|
||||
}
|
||||
inline void set_location_idx(int64_t location_idx)
|
||||
{
|
||||
location_idx_ = location_idx;
|
||||
}
|
||||
/**
|
||||
* @brief set allocator which is used for deserialize, but not all objects will use allocator
|
||||
* while deserializing, so you can override it if you need.
|
||||
*/
|
||||
virtual void set_deserialize_allocator(common::ObIAllocator* allocator) override
|
||||
{
|
||||
part_infos_.set_allocator(allocator);
|
||||
}
|
||||
const ObTableModifySpec& get_spec() const
|
||||
{
|
||||
return static_cast<const ObTableModifySpec&>(spec_);
|
||||
}
|
||||
TO_STRING_KV(K_(location_idx), K_(part_infos));
|
||||
|
||||
private:
|
||||
int64_t location_idx_;
|
||||
common::ObFixedArray<DMLPartInfo, common::ObIAllocator> part_infos_;
|
||||
|
||||
TO_STRING_KV(KPC_(table_loc), KPC_(tablet_loc));
|
||||
protected:
|
||||
ObDASTableLoc *table_loc_;
|
||||
ObDASTabletLoc *tablet_loc_; //for single table modify op
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObTableModifyOpInput);
|
||||
};
|
||||
|
||||
class ObTableModifyOp : public ObOperator {
|
||||
class ObTableModifyOp: public ObOperator
|
||||
{
|
||||
public:
|
||||
class DMLRowIterator : public common::ObNewRowIterator {
|
||||
public:
|
||||
DMLRowIterator(ObExecContext& ctx, ObTableModifyOp& op) : ctx_(ctx), op_(op)
|
||||
{}
|
||||
virtual ~DMLRowIterator()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
int init();
|
||||
int get_next_row(common::ObNewRow*& row);
|
||||
virtual int get_next_rows(common::ObNewRow*& row, int64_t& row_count);
|
||||
virtual void reset();
|
||||
ObTableModifyOp(ObExecContext &ctx, const ObOpSpec &spec, ObOpInput *input);
|
||||
virtual ~ObTableModifyOp() {}
|
||||
|
||||
// create project_row_ cells.
|
||||
int setup_project_row(const int64_t cnt);
|
||||
|
||||
protected:
|
||||
ObExecContext& ctx_;
|
||||
ObTableModifyOp& op_;
|
||||
common::ObNewRow project_row_;
|
||||
};
|
||||
|
||||
class ForeignKeyHandle {
|
||||
public:
|
||||
struct ObFkRowResInfo {
|
||||
ObExpr* rt_expr_;
|
||||
ObDatum ori_datum_;
|
||||
TO_STRING_KV(K_(rt_expr), K_(ori_datum));
|
||||
};
|
||||
static int do_handle_old_row(
|
||||
ObTableModifyOp& modify_op, const ObForeignKeyArgArray& fk_args, const ObExprPtrIArray& old_row);
|
||||
static int do_handle_new_row(
|
||||
ObTableModifyOp& modify_op, const ObForeignKeyArgArray& fk_args, const ObExprPtrIArray& new_row);
|
||||
static int do_handle(ObTableModifyOp& modify_op, const ObForeignKeyArgArray& fk_args,
|
||||
const ObExprPtrIArray& old_row, const ObExprPtrIArray& new_row);
|
||||
|
||||
private:
|
||||
static int value_changed(ObTableModifyOp& op, const common::ObIArray<ObForeignKeyColumn>& columns,
|
||||
const ObExprPtrIArray& old_row, const ObExprPtrIArray& new_row, bool& has_changed);
|
||||
static int check_exist(
|
||||
ObTableModifyOp& modify_op, const ObForeignKeyArg& fk_arg, const ObExprPtrIArray& row, bool expect_zero);
|
||||
static int cascade(ObTableModifyOp& modify_op, const ObForeignKeyArg& fk_arg, const ObExprPtrIArray& old_row,
|
||||
const ObExprPtrIArray& new_row);
|
||||
static int gen_set(ObEvalCtx& eval_ctx, char* buf, int64_t len, int64_t& pos,
|
||||
const common::ObIArray<ObForeignKeyColumn>& columns, const ObExprPtrIArray& row,
|
||||
const common::ObObjPrintParams& print_params);
|
||||
static int gen_where(ObEvalCtx& eval_ctx, char* buf, int64_t len, int64_t& pos,
|
||||
const common::ObIArray<ObForeignKeyColumn>& columns, const ObExprPtrIArray& row,
|
||||
const common::ObObjPrintParams& print_params);
|
||||
static int gen_column_value(ObEvalCtx& ctx, char* buf, int64_t len, int64_t& pos,
|
||||
const common::ObIArray<ObForeignKeyColumn>& columns, const ObExprPtrIArray& row, const char* delimiter,
|
||||
const common::ObObjPrintParams& print_params, bool forbid_null);
|
||||
static int is_self_ref_row(
|
||||
ObEvalCtx& ctx, const ObExprPtrIArray& row, const ObForeignKeyArg& fk_arg, bool& is_self_ref);
|
||||
};
|
||||
|
||||
public:
|
||||
ObTableModifyOp(ObExecContext& ctx, const ObOpSpec& spec, ObOpInput* input);
|
||||
virtual ~ObTableModifyOp()
|
||||
{}
|
||||
|
||||
virtual int switch_iterator() override;
|
||||
virtual int inner_switch_iterator() override;
|
||||
|
||||
int is_valid();
|
||||
|
||||
sql::ObSQLSessionInfo::StmtSavedValue& get_saved_session()
|
||||
sql::ObSQLSessionInfo::StmtSavedValue &get_saved_session()
|
||||
{
|
||||
if (NULL == saved_session_) {
|
||||
saved_session_ = new (saved_session_buf_) sql::ObSQLSessionInfo::StmtSavedValue();
|
||||
@ -280,23 +167,19 @@ public:
|
||||
return *saved_session_;
|
||||
}
|
||||
|
||||
const ObTableModifySpec& get_spec() const
|
||||
const ObTableModifySpec &get_spec() const
|
||||
{
|
||||
return static_cast<const ObTableModifySpec&>(spec_);
|
||||
return static_cast<const ObTableModifySpec &>(spec_);
|
||||
}
|
||||
ObTableModifyOpInput* get_input() const
|
||||
ObTableModifyOpInput *get_input() const
|
||||
{
|
||||
return static_cast<ObTableModifyOpInput*>(input_);
|
||||
return static_cast<ObTableModifyOpInput *>(input_);
|
||||
}
|
||||
|
||||
virtual void destroy() override
|
||||
{
|
||||
if (rowkey_dist_ctx_ != nullptr) {
|
||||
rowkey_dist_ctx_->~SeRowkeyDistCtx();
|
||||
rowkey_dist_ctx_ = nullptr;
|
||||
}
|
||||
returning_datum_iter_.reset();
|
||||
returning_datum_store_.reset();
|
||||
dml_rtctx_.cleanup();
|
||||
trigger_clear_exprs_.reset();
|
||||
ObOperator::destroy();
|
||||
}
|
||||
|
||||
@ -306,170 +189,67 @@ public:
|
||||
int begin_nested_session(bool skip_cur_stmt_tables);
|
||||
int end_nested_session();
|
||||
int set_foreign_key_cascade(bool is_cascade);
|
||||
int get_foreign_key_cascade(bool& is_cascade) const;
|
||||
int get_foreign_key_cascade(bool &is_cascade) const;
|
||||
int set_foreign_key_check_exist(bool is_check_exist);
|
||||
int get_foreign_key_check_exist(bool& is_check_exist) const;
|
||||
int execute_write(const char* sql);
|
||||
int execute_read(const char* sql, common::ObMySQLProxy::MySQLResult& res);
|
||||
int get_foreign_key_check_exist(bool &is_check_exist) const;
|
||||
int execute_write(const char *sql);
|
||||
int execute_read(const char *sql, common::ObMySQLProxy::MySQLResult &res);
|
||||
int check_stack();
|
||||
bool is_nested_session()
|
||||
{
|
||||
return is_nested_session_;
|
||||
}
|
||||
void set_foreign_key_checks()
|
||||
{
|
||||
foreign_key_checks_ = true;
|
||||
}
|
||||
bool need_foreign_key_checks()
|
||||
{
|
||||
return foreign_key_checks_;
|
||||
}
|
||||
const ObObjPrintParams get_obj_print_params()
|
||||
{
|
||||
ObObjPrintParams print_params = CREATE_OBJ_PRINT_PARAM(ctx_.get_my_session());
|
||||
print_params.need_cast_expr_ = true;
|
||||
// bugfix:https://work.aone.alibaba-inc.com/issue/36658497
|
||||
// in NO_BACKSLASH_ESCAPES, obj_print_sql<ObVarcharType> won't escape.
|
||||
// We use skip_escape_ to indicate this case. It will finally be passed to ObHexEscapeSqlStr.
|
||||
GET_SQL_MODE_BIT(IS_NO_BACKSLASH_ESCAPES, ctx_.get_my_session()->get_sql_mode(), print_params.skip_escape_);
|
||||
return print_params;
|
||||
}
|
||||
bool is_nested_session() { return is_nested_session_; }
|
||||
void set_foreign_key_checks() { foreign_key_checks_ = true; }
|
||||
bool need_foreign_key_checks() { return foreign_key_checks_; }
|
||||
const ObObjPrintParams &get_obj_print_params() { return obj_print_params_; }
|
||||
int init_foreign_key_operation();
|
||||
int check_rowkey_is_null(const ObExprPtrIArray& row, int64_t rowkey_cnt, bool& is_null) const;
|
||||
void log_user_error_inner(
|
||||
int ret, int64_t col_idx, int64_t row_num, const ObIArray<ColumnContent>& column_infos) const;
|
||||
// first pk count cell of %row is pk.
|
||||
int check_rowkey_whether_distinct(const ObExprPtrIArray& row, int64_t rowkey_cnt, DistinctType distinct_algo,
|
||||
SeRowkeyDistCtx*& rowkey_dist_ctx, bool& is_dist);
|
||||
|
||||
int calc_part_id(const ObExpr* calc_part_id_expr, ObIArray<int64_t>& part_ids, int64_t& part_idx);
|
||||
// Prepare next row for storage process, used in DMLRowIterator to supply rows for storage.
|
||||
// The old engine get rows from operator get_next_row() interface, but the operator has no
|
||||
// output expressions, we can not do this in static typing engine.
|
||||
//
|
||||
// %output may point to MY_SPEC.storage_row_output_ or not.
|
||||
// Update operator need output old row and new row here, %output changes.
|
||||
virtual int prepare_next_storage_row(const ObExprPtrIArray*& output)
|
||||
{
|
||||
// the default implement same with get_next_row()
|
||||
output = &get_spec().storage_row_output_;
|
||||
return ObOperator::get_next_row();
|
||||
}
|
||||
|
||||
void log_user_error_inner(int ret, int64_t col_idx, int64_t row_num,
|
||||
const ObIArray<ColumnContent> &column_infos) const;
|
||||
void log_user_error_inner(int ret, int64_t row_num, const ColumnContent &column_info) const;
|
||||
void clear_dml_evaluated_flag();
|
||||
void clear_dml_evaluated_flag(int64_t parent_cnt, ObExpr **parent_exprs);
|
||||
void clear_dml_evaluated_flag(ObExpr *clear_expr);
|
||||
protected:
|
||||
OperatorOpenOrder get_operator_open_order() const override;
|
||||
virtual int inner_open() override;
|
||||
virtual int inner_close() override;
|
||||
|
||||
// project expressions to old style row, allocate cells from ctx_.get_allocator() if needed.
|
||||
int project_row(ObExpr* const* exprs, const int64_t cnt, common::ObNewRow& row) const;
|
||||
int project_row(const ObExprPtrIArray& expr_row, common::ObNewRow& row) const
|
||||
{
|
||||
return project_row(expr_row.get_data(), expr_row.count(), row);
|
||||
}
|
||||
// project datum to old style row.
|
||||
int project_row(const ObDatum* datums, ObExpr* const* exprs, const int64_t cnt, common::ObNewRow& row) const;
|
||||
int lock_row(
|
||||
const ObExprPtrIArray& row, storage::ObDMLBaseParam& dml_param, const common::ObPartitionKey& pkey) const;
|
||||
|
||||
template <class UpdateOp>
|
||||
int check_updated_value(UpdateOp& update_op, const common::ObIArrayWrap<ColumnContent>& assign_columns,
|
||||
const ObExprPtrIArray& old_row, const ObExprPtrIArray& new_row, bool& is_updated);
|
||||
|
||||
int check_row_value(bool& updated, const common::ObIArrayWrap<ColumnContent>& update_column_infos,
|
||||
const ObExprPtrIArray& old_row, const ObExprPtrIArray& new_row);
|
||||
|
||||
int mark_lock_row_flag(int64_t flag);
|
||||
|
||||
int check_row_null(const ObExprPtrIArray &row,
|
||||
const common::ObIArray<ColumnContent> &column_infos,
|
||||
const common::ObIArray<ColumnContent> &update_col_infos) const;
|
||||
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);
|
||||
OperatorOpenOrder get_operator_open_order() const;
|
||||
virtual int inner_open();
|
||||
virtual int inner_close();
|
||||
|
||||
int get_gi_task();
|
||||
// filtered if filter return false value. (move from ObPhyOperator).
|
||||
// eval all exprs in [%beg_idx, %end_idx) of %check_constraint_exprs,
|
||||
// if both %beg_idx and %end_idx are OB_INVALID_ID, eval all exprs in
|
||||
// %check_constraint_exprs.
|
||||
int filter_row_for_check_cst(const ExprFixedArray& check_constraint_exprs, bool& filtered,
|
||||
int64_t beg_idx = OB_INVALID_ID, int64_t end_idx = OB_INVALID_ID) const;
|
||||
//It is used for the execution without routing through DAS.
|
||||
//In this case, the DML operator only allows to modify a single table,
|
||||
//and the table location is specified by the scheduling framework.
|
||||
int calc_single_table_loc();
|
||||
|
||||
// datum will be resotred according to %fk_self_ref_row_res_infos_.
|
||||
// resotre is necessary when there are forgien key self reference.
|
||||
// see ObTableModifyOp::ForgienKeyHandle::do_handle().
|
||||
// for now, this func is only needed in update/multi update operator.
|
||||
int restore_and_reset_fk_res_info();
|
||||
|
||||
bool init_returning_store();
|
||||
virtual int inner_rescan() override;
|
||||
|
||||
int submit_all_dml_task();
|
||||
int init_das_dml_ctx();
|
||||
//to merge array binding cusor info when array binding is executed in batch mode
|
||||
int merge_implict_cursor(int64_t insert_rows,
|
||||
int64_t update_rows,
|
||||
int64_t delete_rows,
|
||||
int64_t found_rows);
|
||||
public:
|
||||
common::ObMySQLProxy* sql_proxy_;
|
||||
observer::ObInnerSQLConnection* inner_conn_;
|
||||
common::ObMySQLProxy *sql_proxy_;
|
||||
observer::ObInnerSQLConnection *inner_conn_;
|
||||
uint64_t tenant_id_;
|
||||
observer::ObInnerSQLConnection::SavedValue saved_conn_;
|
||||
bool is_nested_session_;
|
||||
bool foreign_key_checks_;
|
||||
bool need_close_conn_;
|
||||
SeRowkeyDistCtx* rowkey_dist_ctx_;
|
||||
|
||||
// trigger
|
||||
ObNewRow tg_old_row_;
|
||||
ObNewRow tg_new_row_;
|
||||
common::ObArrayHelper<common::ObObjParam> tg_when_point_params_;
|
||||
common::ObArrayHelper<common::ObObjParam> tg_stmt_point_params_;
|
||||
common::ObArrayHelper<common::ObObjParam> tg_row_point_params_;
|
||||
common::ObObjParam* tg_all_params_;
|
||||
|
||||
// row for locking, used in lock_row() to convert ObExpr array to old style row.
|
||||
mutable common::ObNewRow lock_row_;
|
||||
ObObjPrintParams obj_print_params_;
|
||||
bool iter_end_;
|
||||
|
||||
ObChunkDatumStore returning_datum_store_;
|
||||
ObChunkDatumStore::Iterator returning_datum_iter_;
|
||||
|
||||
ObDMLRtCtx dml_rtctx_;
|
||||
bool is_error_logging_;
|
||||
ObErrLogRtDef err_log_rt_def_;
|
||||
ObSEArray<ObExpr *, 4> trigger_clear_exprs_;
|
||||
private:
|
||||
ObSQLSessionInfo::StmtSavedValue* saved_session_;
|
||||
char* saved_session_buf_[sizeof(ObSQLSessionInfo::StmtSavedValue)];
|
||||
// when got forgien key self reference, need to change row.
|
||||
// see ObTableModifyOp::ForeignKeyHandle::do_handle()
|
||||
ObSEArray<ForeignKeyHandle::ObFkRowResInfo, 32> fk_self_ref_row_res_infos_;
|
||||
ObSQLSessionInfo::StmtSavedValue *saved_session_;
|
||||
char saved_session_buf_[sizeof(ObSQLSessionInfo::StmtSavedValue)] __attribute__((aligned (16)));;
|
||||
|
||||
// trigger
|
||||
static const int64_t ALL_PARAM_COUNT;
|
||||
static const int64_t PARAM_OLD_IDX;
|
||||
static const int64_t PARAM_NEW_IDX;
|
||||
static const int64_t PARAM_EVENT_IDX;
|
||||
static const int64_t WHEN_POINT_PARAM_OFFSET;
|
||||
static const int64_t WHEN_POINT_PARAM_COUNT;
|
||||
static const int64_t STMT_POINT_PARAM_OFFSET;
|
||||
static const int64_t STMT_POINT_PARAM_COUNT;
|
||||
static const int64_t ROW_POINT_PARAM_OFFSET;
|
||||
static const int64_t ROW_POINT_PARAM_COUNT;
|
||||
// used by check_rowkey_whether_distinct
|
||||
static const int64_t MIN_ROWKEY_DISTINCT_BUCKET_NUM = 1 * 1024;
|
||||
static const int64_t MAX_ROWKEY_DISTINCT_BUCKET_NUM = 1 * 1024 * 1024;
|
||||
};
|
||||
|
||||
template <class UpdateOp>
|
||||
int ObTableModifyOp::check_updated_value(UpdateOp& update_op, const common::ObIArrayWrap<ColumnContent>& assign_columns,
|
||||
const ObExprPtrIArray& old_row, const ObExprPtrIArray& new_row, bool& is_updated)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_FAIL(check_row_value(is_updated, assign_columns, old_row, new_row))) {
|
||||
SQL_ENG_LOG(WARN, "check row value failed", K(ret));
|
||||
} else if (is_updated) {
|
||||
update_op.inc_changed_rows();
|
||||
update_op.inc_affected_rows();
|
||||
}
|
||||
update_op.inc_found_rows();
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user