patch 4.0
This commit is contained in:
@ -17,82 +17,87 @@
|
||||
#include "sql/optimizer/ob_opt_est_cost.h"
|
||||
#include "sql/optimizer/ob_log_plan.h"
|
||||
#include "sql/engine/expr/ob_expr_column_conv.h"
|
||||
#include "sql/optimizer/ob_del_upd_log_plan.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
/**
|
||||
* Print log info with expressions
|
||||
*/
|
||||
#define EXPLAIN_PRINT_INSERT_VALUES(values, column_count, type) \
|
||||
{ \
|
||||
if (OB_ISNULL(values)) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
} else if (OB_FAIL(BUF_PRINTF(#values "("))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} else { \
|
||||
int64_t N = values->count(); \
|
||||
int64_t M = column_count; \
|
||||
if (N == 0) { \
|
||||
if (OB_FAIL(BUF_PRINTF("nil"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} else if (OB_UNLIKELY(0 != N % M)) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
LOG_WARN("invalid value count", K(ret), "value_count", N, "row_count", M); \
|
||||
} else { \
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < N / M; i++) { \
|
||||
if (OB_FAIL(BUF_PRINTF("{"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < M; j++) { \
|
||||
int64_t expr_idx = i * M + j; \
|
||||
#define EXPLAIN_PRINT_INSERT_VALUES(values, column_count, type) \
|
||||
{ \
|
||||
if (OB_ISNULL(values)) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
} else if (OB_FAIL(BUF_PRINTF(#values"("))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} else { \
|
||||
int64_t N = values->count(); \
|
||||
int64_t M = column_count; \
|
||||
if (N == 0 || M == 0) { \
|
||||
if (OB_FAIL(BUF_PRINTF("nil"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} else if (OB_UNLIKELY(0 != N % M)) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
LOG_WARN("invalid value count", K(ret), "value_count", N, "row_count", M); \
|
||||
} else { \
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < N / M; i++) { \
|
||||
if (OB_FAIL(BUF_PRINTF("{"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < M; j++) { \
|
||||
int64_t expr_idx = i * M + j; \
|
||||
if (OB_UNLIKELY(expr_idx >= values->count()) || OB_UNLIKELY(expr_idx < 0)) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
} else if (OB_ISNULL(values->at(expr_idx))) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
} else { \
|
||||
if (OB_FAIL(values->at(expr_idx)->get_name(buf, buf_len, pos, type))) { \
|
||||
} else { \
|
||||
if (j < M - 1) { \
|
||||
if (OB_FAIL(BUF_PRINTF(", "))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (OB_FAIL(BUF_PRINTF("}"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} else if (i < N / M - 1) { \
|
||||
if (OB_FAIL(BUF_PRINTF(", "))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (OB_SUCC(ret)) { \
|
||||
if (OB_FAIL(BUF_PRINTF(")"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
} else if (OB_ISNULL(values->at(expr_idx))) { \
|
||||
ret = OB_ERR_UNEXPECTED; \
|
||||
} else { \
|
||||
if (OB_FAIL(values->at(expr_idx)->get_name(buf, buf_len, pos, type))) { \
|
||||
} else { \
|
||||
if (j < M - 1) { \
|
||||
if (OB_FAIL(BUF_PRINTF(", "))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (OB_FAIL(BUF_PRINTF("}"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} else if (i < N / M - 1) { \
|
||||
if (OB_FAIL(BUF_PRINTF(", "))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (OB_SUCC(ret)) { \
|
||||
if (OB_FAIL(BUF_PRINTF(")"))) { \
|
||||
LOG_WARN("fail to print to buf", K(ret)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
int ObLogExprValues::allocate_exchange_post(AllocExchContext* ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(ctx);
|
||||
sharding_info_.set_location_type(OB_TBL_LOCATION_ALL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::add_values_expr(const common::ObIArray<ObRawExpr*>& value_exprs)
|
||||
int ObLogExprValues::add_values_expr(const common::ObIArray<ObRawExpr *> &value_exprs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(append(value_exprs_, value_exprs))) {
|
||||
LOG_WARN("failed to append expr", K(ret));
|
||||
} else if (get_stmt()->is_insert_stmt() && is_ins_values_batch_opt()) {
|
||||
const ObInsertStmt *insert_stmt = static_cast<const ObInsertStmt*>(get_stmt());
|
||||
ObRawExpr *stmt_id_expr = NULL;
|
||||
if (OB_ISNULL(stmt_id_expr = insert_stmt->get_ab_stmt_id_expr())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("stmt_id_expr is null", K(ret));
|
||||
} else if (OB_FAIL(value_exprs_.push_back(stmt_id_expr))) {
|
||||
LOG_WARN("fail to push stmt_id_expr", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -100,47 +105,52 @@ int ObLogExprValues::add_values_expr(const common::ObIArray<ObRawExpr*>& value_e
|
||||
int ObLogExprValues::compute_fd_item_set()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObRawExpr*, 8> select_exprs;
|
||||
int32_t stmt_level = -1;
|
||||
ObFdItemSet* fd_item_set = NULL;
|
||||
if (OB_ISNULL(my_plan_) || OB_ISNULL(get_stmt()) || OB_UNLIKELY(!get_stmt()->is_select_stmt())) {
|
||||
if (OB_ISNULL(my_plan_) || OB_ISNULL(get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpect parameter", K(my_plan_), K(get_stmt()));
|
||||
} else if (OB_FAIL(static_cast<ObSelectStmt*>(get_stmt())->get_select_exprs(select_exprs))) {
|
||||
LOG_WARN("failed to get select exprs", K(ret));
|
||||
} else if (OB_FAIL(my_plan_->get_fd_item_factory().create_fd_item_set(fd_item_set))) {
|
||||
LOG_WARN("failed to create fd item set", K(ret));
|
||||
} else if (!get_stmt()->is_select_stmt()) {
|
||||
set_fd_item_set(&empty_fd_item_set_);
|
||||
} else {
|
||||
stmt_level = get_stmt()->get_current_level();
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < select_exprs.count(); ++i) {
|
||||
ObSEArray<ObRawExpr*, 1> value_exprs;
|
||||
ObExprFdItem* fd_item = NULL;
|
||||
if (OB_FAIL(value_exprs.push_back(select_exprs.at(i)))) {
|
||||
LOG_WARN("failed to push back expr", K(ret));
|
||||
} else if (OB_FAIL(my_plan_->get_fd_item_factory().create_expr_fd_item(
|
||||
fd_item, true, value_exprs, stmt_level, select_exprs))) {
|
||||
LOG_WARN("failed to create fd item", K(ret));
|
||||
} else if (OB_FAIL(fd_item_set->push_back(fd_item))) {
|
||||
LOG_WARN("failed to push back fd item", K(ret));
|
||||
int32_t stmt_level = -1;
|
||||
ObFdItemSet *fd_item_set = NULL;
|
||||
ObSEArray<ObRawExpr*, 8> select_exprs;
|
||||
if (OB_FAIL(static_cast<const ObSelectStmt *>(get_stmt())->get_select_exprs(select_exprs))) {
|
||||
LOG_WARN("failed to get select exprs", K(ret));
|
||||
} else if (OB_FAIL(my_plan_->get_fd_item_factory().create_fd_item_set(fd_item_set))) {
|
||||
LOG_WARN("failed to create fd item set", K(ret));
|
||||
} else {
|
||||
stmt_level = get_stmt()->get_current_level();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < select_exprs.count(); ++i) {
|
||||
ObSEArray<ObRawExpr *, 1> value_exprs;
|
||||
ObExprFdItem *fd_item = NULL;
|
||||
if (OB_FAIL(value_exprs.push_back(select_exprs.at(i)))) {
|
||||
LOG_WARN("failed to push back expr", K(ret));
|
||||
} else if (OB_FAIL(my_plan_->get_fd_item_factory().create_expr_fd_item(fd_item,
|
||||
true,
|
||||
value_exprs,
|
||||
stmt_level,
|
||||
select_exprs))) {
|
||||
LOG_WARN("failed to create fd item", K(ret));
|
||||
} else if (OB_FAIL(fd_item_set->push_back(fd_item))) {
|
||||
LOG_WARN("failed to push back fd item", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
/*do nothing*/
|
||||
} else if (OB_FAIL(deduce_const_exprs_and_ft_item_set(*fd_item_set))) {
|
||||
LOG_WARN("falied to deduce fd item set", K(ret));
|
||||
} else {
|
||||
set_fd_item_set(fd_item_set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
/*do nothing*/
|
||||
} else if (OB_FAIL(deduce_const_exprs_and_ft_item_set(*fd_item_set))) {
|
||||
LOG_WARN("falied to deduce fd item set", K(ret));
|
||||
} else {
|
||||
set_fd_item_set(fd_item_set);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::compute_equal_set()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
set_ordering_output_equal_sets(&empty_expr_sets_);
|
||||
set_sharding_output_equal_sets(&empty_expr_sets_);
|
||||
set_output_equal_sets(&empty_expr_sets_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -154,14 +164,19 @@ int ObLogExprValues::compute_table_set()
|
||||
int ObLogExprValues::compute_op_ordering()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObArray<ObRawExpr*> select_exprs;
|
||||
if (OB_ISNULL(get_stmt()) || OB_UNLIKELY(!get_stmt()->is_select_stmt())) {
|
||||
if (OB_ISNULL(get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("stmt is invalid", K(ret));
|
||||
} else if (OB_FAIL(static_cast<ObSelectStmt*>(get_stmt())->get_select_exprs(select_exprs))) {
|
||||
LOG_WARN("failed to get select exprs", K(ret));
|
||||
} else if (OB_FAIL(ObOptimizerUtil::copy_sort_keys(select_exprs, op_ordering_))) {
|
||||
LOG_WARN("failed to copy sort keys", K(ret));
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (!get_stmt()->is_select_stmt()) {
|
||||
/*do nothing*/
|
||||
} else {
|
||||
ObSEArray<ObRawExpr*, 4> select_exprs;
|
||||
if (OB_FAIL(static_cast<const ObSelectStmt *>(get_stmt())->get_select_exprs(select_exprs))) {
|
||||
LOG_WARN("failed to get select exprs", K(ret));
|
||||
} else if (OB_FAIL(ObOptimizerUtil::make_sort_keys(select_exprs,
|
||||
op_ordering_))) {
|
||||
LOG_WARN("failed to copy sort keys", K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -169,13 +184,34 @@ int ObLogExprValues::compute_op_ordering()
|
||||
int ObLogExprValues::est_cost()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// set cost and card
|
||||
set_card(1.0);
|
||||
set_cost(ObOptEstCost::get_cost_params().CPU_OPERATOR_COST *
|
||||
static_cast<double>(get_stmt()->get_condition_exprs().count()) +
|
||||
ObOptEstCost::get_cost_params().CPU_TUPLE_COST);
|
||||
set_op_cost(get_cost());
|
||||
// TODO
|
||||
if (OB_ISNULL(get_plan()) ||
|
||||
OB_ISNULL(get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (get_stmt()->is_insert_stmt()) {
|
||||
ObOptimizerContext &opt_ctx = get_plan()->get_optimizer_context();
|
||||
const ObInsertStmt *insert_stmt = static_cast<const ObInsertStmt*>(get_stmt());
|
||||
set_card(insert_stmt->get_insert_row_count());
|
||||
set_op_cost(ObOptEstCost::cost_get_rows(get_card(), opt_ctx.get_cost_model_type()));
|
||||
set_cost(get_op_cost());
|
||||
} else {
|
||||
ObOptimizerContext &opt_ctx = get_plan()->get_optimizer_context();
|
||||
set_card(1.0);
|
||||
set_op_cost(ObOptEstCost::cost_filter_rows(get_card(), filter_exprs_, opt_ctx.get_cost_model_type()));
|
||||
set_cost(get_op_cost());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::compute_sharding_info()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_plan())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else {
|
||||
strong_sharding_ = get_plan()->get_optimizer_context().get_match_all_sharding();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -187,59 +223,107 @@ int ObLogExprValues::compute_one_row_info()
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (!get_stmt()->is_insert_stmt()) {
|
||||
is_at_most_one_row_ = true;
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
} else { /*do nothing*/ }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::allocate_dummy_output()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObLogicalOperator::allocate_dummy_output())) {
|
||||
LOG_WARN("fail to allocate dummy output", K(ret));
|
||||
} else if (OB_FAIL(append(value_exprs_, output_exprs_))) {
|
||||
LOG_WARN("failed to append exprs", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::allocate_expr_post(ObAllocExprContext& ctx)
|
||||
int ObLogExprValues::get_op_exprs(ObIArray<ObRawExpr*> &all_exprs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_stmt())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("stmt is null");
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(ObLogicalOperator::get_op_exprs(all_exprs))) {
|
||||
LOG_WARN("failed to get op exprs", K(ret));
|
||||
} else if (OB_FAIL(append(all_exprs, value_exprs_))) {
|
||||
LOG_WARN("failed to append exprs", K(ret));
|
||||
} else if (get_stmt()->is_insert_stmt()) {
|
||||
ObInsertStmt* insert_stmt = static_cast<ObInsertStmt*>(get_stmt());
|
||||
ObIArray<ObColumnRefRawExpr*>& values_desc = insert_stmt->get_values_desc();
|
||||
const ObInsertStmt *insert_stmt = static_cast<const ObInsertStmt*>(get_stmt());
|
||||
if (OB_FAIL(append(all_exprs, insert_stmt->get_values_desc()))) {
|
||||
LOG_WARN("failed to append exprs", K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
} else { /*do nothing*/ }
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::allocate_expr_post(ObAllocExprContext &ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(get_stmt()), K(ret));
|
||||
} else if (get_stmt()->is_insert_stmt()) {
|
||||
const ObInsertStmt *insert_stmt = static_cast<const ObInsertStmt*>(get_stmt());
|
||||
const ObIArray<ObColumnRefRawExpr*> &values_desc = insert_stmt->get_values_desc();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < values_desc.count(); ++i) {
|
||||
ObColumnRefRawExpr* value_col = values_desc.at(i);
|
||||
bool expr_is_required = false;
|
||||
if (OB_FAIL(mark_expr_produced(value_col, branch_id_, id_, ctx, expr_is_required))) {
|
||||
ObColumnRefRawExpr *value_col = values_desc.at(i);
|
||||
if (OB_FAIL(mark_expr_produced(value_col, branch_id_, id_, ctx))) {
|
||||
LOG_WARN("makr expr produced failed", K(ret));
|
||||
} else if (!is_plan_root() && expr_is_required) {
|
||||
if (OB_FAIL(add_var_to_array_no_dup(output_exprs_, static_cast<ObRawExpr*>(value_col)))) {
|
||||
LOG_WARN("add expr no duplicate key failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (!is_plan_root() && OB_FAIL(output_exprs_.push_back(value_col))) {
|
||||
LOG_WARN("failed to push back exprs", K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
/*do nothing*/
|
||||
} else if (OB_FAIL(ObLogicalOperator::allocate_expr_post(ctx))) {
|
||||
LOG_WARN("failed to allocate expr post", K(ret));
|
||||
} else if (contain_array_binding_param() && OB_FAIL(construct_array_binding_values())) {
|
||||
LOG_WARN("construct array binding values failed", K(ret));
|
||||
} else if (value_exprs_.empty() && OB_FAIL(append(value_exprs_, get_output_exprs()))) {
|
||||
LOG_WARN("failed to append exprs", K(ret));
|
||||
} else if (value_exprs_.empty() && OB_FAIL(allocate_dummy_output())) {
|
||||
LOG_WARN("failed to allocate dummy output", K(ret));
|
||||
} else if (OB_FAIL(construct_sequence_values())) {
|
||||
LOG_WARN("failed to construct sequence values", K(ret));
|
||||
} else if (OB_FAIL(mark_probably_local_exprs())) {
|
||||
LOG_WARN("failed to mark local exprs", K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(ObLogicalOperator::allocate_expr_post(ctx))) {
|
||||
LOG_WARN("failed to allocate expr post", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < output_exprs_.count(); i++) {
|
||||
ObRawExpr* raw_expr = NULL;
|
||||
if (OB_ISNULL(raw_expr = output_exprs_.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (raw_expr->has_flag(CNT_COLUMN)) {
|
||||
/*do nothing*/
|
||||
} else if (OB_FAIL(value_exprs_.push_back(raw_expr))) {
|
||||
LOG_WARN("failed to add expr", K(ret));
|
||||
} else { /*do nothing*/
|
||||
int ObLogExprValues::construct_sequence_values()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("stmt is null", K(ret));
|
||||
} else if (get_stmt()->is_insert_stmt() && !value_exprs_.empty() && output_exprs_.count() >= 2) {
|
||||
int64_t seq_expr_idx = -1;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < output_exprs_.count(); ++i) {
|
||||
if (OB_ISNULL(output_exprs_.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("output expr is null", K(ret));
|
||||
} else if (T_FUN_SYS_SEQ_NEXTVAL == output_exprs_.at(i)->get_expr_type()) {
|
||||
seq_expr_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && -1 != seq_expr_idx) {
|
||||
ObRawExpr *seq_expr = output_exprs_.at(seq_expr_idx);
|
||||
const int64_t value_count = value_exprs_.count();
|
||||
const int64_t output_count = output_exprs_.count();
|
||||
if (OB_UNLIKELY((0 != value_count % (output_count - 1)) || (0 == seq_expr_idx))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected value count", K(value_count), K(output_count), K(seq_expr_idx));
|
||||
} else {
|
||||
const int64_t group_num = value_count / (output_count - 1);
|
||||
ObSEArray<ObRawExpr*, 8> new_value_exprs;
|
||||
if (OB_FAIL(new_value_exprs.reserve(group_num * output_count))) {
|
||||
LOG_WARN("failed to reserve array", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < value_exprs_.count(); ++i) {
|
||||
if (OB_FAIL(new_value_exprs.push_back(value_exprs_.at(i)))) {
|
||||
LOG_WARN("failed to push back expr", K(ret));
|
||||
} else if (((i + 1) % seq_expr_idx == 0) &&
|
||||
OB_FAIL(new_value_exprs.push_back(seq_expr))) {
|
||||
LOG_WARN("failed to push back sequence expr", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(value_exprs_.assign(new_value_exprs))) {
|
||||
LOG_WARN("failed to assign new value exprs", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -247,9 +331,67 @@ int ObLogExprValues::allocate_expr_post(ObAllocExprContext& ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::print_my_plan_annotation(char* buf, int64_t& buf_len, int64_t& pos, ExplainType type)
|
||||
int ObLogExprValues::construct_array_binding_values()
|
||||
{
|
||||
const ObIArray<ObRawExpr*>* values = &get_value_exprs();
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_stmt()) ||
|
||||
OB_ISNULL(get_plan()) ||
|
||||
OB_UNLIKELY(!get_stmt()->is_select_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("array binding param only in select stmt", K(ret), KPC(get_stmt()));
|
||||
} else {
|
||||
const ObSelectStmt *select_stmt = static_cast<const ObSelectStmt*>(get_stmt());
|
||||
if (OB_FAIL(value_exprs_.assign(select_stmt->get_query_ctx()->ab_param_exprs_))) {
|
||||
LOG_WARN("assign ab param exprs to value exprs failed", K(ret));
|
||||
} else if (OB_FAIL(get_plan()->get_optimizer_context().get_all_exprs().append(value_exprs_))) {
|
||||
LOG_WARN("fail to append ab param exprs", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < output_exprs_.count(); ++i) {
|
||||
ObRawExpr *raw_expr = NULL;
|
||||
if (OB_ISNULL(raw_expr = output_exprs_.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (raw_expr->get_expr_type() == T_PSEUDO_STMT_ID) {
|
||||
if (OB_FAIL(value_exprs_.push_back(raw_expr))) {
|
||||
LOG_WARN("failed to add expr", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::extract_err_log_info()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (!get_stmt()->is_insert_stmt()) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObLogDelUpd::generate_errlog_info(
|
||||
static_cast<const ObDelUpdStmt&>(*get_stmt()),
|
||||
get_err_log_define()))) {
|
||||
LOG_WARN("failed to generate errlog info", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < get_err_log_define().err_log_value_exprs_.count(); ++i) {
|
||||
ObRawExpr *&expr = get_err_log_define().err_log_value_exprs_.at(i);
|
||||
if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("expr is null", K(ret));
|
||||
} else if (expr->get_expr_type() == T_FUN_COLUMN_CONV) {
|
||||
expr = expr->get_param_expr(ObExprColumnConv::VALUE_EXPR);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::print_my_plan_annotation(char *buf,
|
||||
int64_t &buf_len,
|
||||
int64_t &pos,
|
||||
ExplainType type)
|
||||
{
|
||||
const ObIArray<ObRawExpr*> *values = &get_value_exprs();
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t tmp_pos = pos;
|
||||
if (OB_ISNULL(buf)) {
|
||||
@ -269,92 +411,68 @@ int ObLogExprValues::print_my_plan_annotation(char* buf, int64_t& buf_len, int64
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t ObLogExprValues::hash(uint64_t seed) const
|
||||
{
|
||||
seed = do_hash(need_columnlized_, seed);
|
||||
seed = ObOptimizerUtil::hash_exprs(seed, value_exprs_);
|
||||
seed = ObLogicalOperator::hash(seed);
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
int ObLogExprValues::inner_append_not_produced_exprs(ObRawExprUniqueSet& raw_exprs) const
|
||||
int ObLogExprValues::mark_probably_local_exprs()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_stmt())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("stmt is null", K(ret));
|
||||
} else if (get_stmt()->is_insert_stmt()) {
|
||||
const ObInsertStmt* insert_stmt = static_cast<const ObInsertStmt*>(get_stmt());
|
||||
const ObIArray<ObColumnRefRawExpr*>& values_desc = insert_stmt->get_values_desc();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < values_desc.count(); i++) {
|
||||
OZ(raw_exprs.append(static_cast<ObRawExpr*>(values_desc.at(i))));
|
||||
}
|
||||
FOREACH_CNT_X(e, value_exprs_, OB_SUCC(ret)) {
|
||||
CK(NULL != *e);
|
||||
OZ((*e)->add_flag(IS_PROBABLY_LOCAL));
|
||||
}
|
||||
OZ(raw_exprs.append(value_exprs_));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::check_range_param_continuous(bool& use_range_param) const
|
||||
int ObLogExprValues::allocate_dummy_output()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t column_cnt = get_output_exprs().count();
|
||||
int64_t last_param_index = OB_INVALID_INDEX;
|
||||
if (column_cnt > 1 && GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_2230) {
|
||||
use_range_param = true;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && use_range_param && i <= value_exprs_.count() - column_cnt; i += column_cnt) {
|
||||
last_param_index = OB_INVALID_INDEX;
|
||||
for (int64_t j = i; OB_SUCC(ret) && use_range_param && j < i + column_cnt; ++j) {
|
||||
if (OB_ISNULL(value_exprs_.at(j))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("value expr is null", K(ret), K(value_exprs_), K(i), K(j));
|
||||
} else if (!value_exprs_.at(j)->is_const_expr()) {
|
||||
use_range_param = false;
|
||||
} else {
|
||||
const ObConstRawExpr* param_expr = static_cast<const ObConstRawExpr*>(value_exprs_.at(j));
|
||||
if (!param_expr->get_value().is_unknown()) {
|
||||
use_range_param = false;
|
||||
} else if (param_expr->get_result_type().get_param().is_ext()) {
|
||||
use_range_param = false;
|
||||
} else if (param_expr->get_value().get_unknown() != last_param_index + 1 &&
|
||||
OB_INVALID_INDEX != last_param_index) {
|
||||
use_range_param = false;
|
||||
} else {
|
||||
last_param_index = param_expr->get_value().get_unknown();
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("check range param continuous", K(use_range_param), K(last_param_index));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
use_range_param = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogExprValues::get_value_param_range(int64_t row_index, int64_t& param_idx_start, int64_t& param_idx_end) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t column_cnt = get_output_exprs().count();
|
||||
int64_t value_idx_start = row_index * column_cnt;
|
||||
if (OB_UNLIKELY(value_idx_start < 0) || OB_UNLIKELY(value_idx_start >= value_exprs_.count())) {
|
||||
ObConstRawExpr *dummy_expr = NULL;
|
||||
if (OB_ISNULL(get_plan())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("value index is invalid", K(row_index), K(column_cnt), K(value_idx_start), K(ret));
|
||||
} else if (!value_exprs_.at(value_idx_start)->is_const_expr()) {
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (is_oracle_mode() && ObRawExprUtils::build_const_number_expr(
|
||||
get_plan()->get_optimizer_context().get_expr_factory(),
|
||||
ObNumberType, number::ObNumber::get_positive_one(),
|
||||
dummy_expr)) {
|
||||
LOG_WARN("failed to build const expr", K(ret));
|
||||
} else if (!is_oracle_mode() && ObRawExprUtils::build_const_int_expr(
|
||||
get_plan()->get_optimizer_context().get_expr_factory(),
|
||||
ObIntType,
|
||||
1,
|
||||
dummy_expr)) {
|
||||
LOG_WARN("failed to build const expr", K(ret));
|
||||
} else if (OB_ISNULL(dummy_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("value expr is invalid", K(ret), KPC(value_exprs_.at(value_idx_start)));
|
||||
} else {
|
||||
const ObConstRawExpr* param_expr = static_cast<const ObConstRawExpr*>(value_exprs_.at(value_idx_start));
|
||||
if (OB_FAIL(param_expr->get_value().get_unknown(param_idx_start))) {
|
||||
LOG_WARN("get param index start value failed", K(ret), K(param_expr->get_value()));
|
||||
} else {
|
||||
param_idx_end = param_idx_start + column_cnt - 1;
|
||||
LOG_DEBUG("get value param range", K(row_index), K(param_idx_start), K(param_idx_end));
|
||||
}
|
||||
}
|
||||
LOG_WARN("get unexpected null", K(ret));
|
||||
} else if (OB_FAIL(dummy_expr->extract_info())) {
|
||||
LOG_WARN("failed to extract info for dummy expr", K(ret));
|
||||
} else if (OB_FAIL(value_exprs_.push_back(dummy_expr))) {
|
||||
LOG_WARN("failed to push back expr", K(ret));
|
||||
} else if (OB_FAIL(output_exprs_.push_back(dummy_expr))) {
|
||||
LOG_WARN("failed to push back expr", K(ret));
|
||||
} else if (OB_FAIL(get_plan()->get_optimizer_context().get_all_exprs().append(dummy_expr))) {
|
||||
LOG_WARN("failed to append exprs", K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
bool ObLogExprValues::is_ins_values_batch_opt() const
|
||||
{
|
||||
bool bret = false;
|
||||
if (get_stmt() != nullptr && get_stmt()->is_insert_stmt()) {
|
||||
bret = get_stmt()->get_query_ctx()->ins_values_batch_opt_;
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
bool ObLogExprValues::contain_array_binding_param() const
|
||||
{
|
||||
bool bret = false;
|
||||
if (get_stmt() != nullptr && get_stmt()->is_select_stmt()) {
|
||||
const ObSelectStmt *select_stmt = static_cast<const ObSelectStmt*>(get_stmt());
|
||||
bret = select_stmt->contain_ab_param();
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
}// namespace oceanbase
|
||||
|
||||
Reference in New Issue
Block a user