fix some sql logical plan bug
This commit is contained in:
@ -73,7 +73,8 @@ namespace sql
|
||||
{
|
||||
|
||||
ObSqlPlan::ObSqlPlan(common::ObIAllocator &allocator)
|
||||
:allocator_(allocator)
|
||||
:allocator_(allocator),
|
||||
session_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -151,13 +152,10 @@ int ObSqlPlan::store_sql_plan_for_explain(ObExecContext *ctx,
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (allocate_mem_failed) {
|
||||
if (allocate_mem_failed || plan_strs.empty()) {
|
||||
if (OB_FAIL(plan_strs.push_back("Plan truncated due to insufficient memory!"))) {
|
||||
LOG_WARN("failed to push back string", K(ret));
|
||||
}
|
||||
} else if (plan_strs.empty()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to generate plan", K(ret));
|
||||
}
|
||||
}
|
||||
destroy_buffer(plan_text);
|
||||
@ -229,6 +227,39 @@ int ObSqlPlan::get_plan_outline_info_one_line(PlanText &plan_text,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSqlPlan::get_plan_used_hint_info_one_line(PlanText &plan_text,
|
||||
ObLogPlan* plan)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObQueryCtx *query_ctx = NULL;
|
||||
if (OB_ISNULL(plan) ||
|
||||
OB_ISNULL(query_ctx = plan->get_optimizer_context().get_query_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected NULL", K(ret), K(plan), K(query_ctx));
|
||||
} else {
|
||||
const ObQueryHint &query_hint = query_ctx->get_query_hint();
|
||||
plan_text.is_used_hint_ = true;
|
||||
plan_text.is_oneline_ = true;
|
||||
plan_text.pos_ = 0;
|
||||
BUF_PRINT_CONST_STR("/*+ ", plan_text);
|
||||
if (OB_FAIL(get_plan_tree_used_hint(plan_text, plan->get_plan_root()))) {
|
||||
LOG_WARN("failed to get plan tree used hint", K(ret));
|
||||
} else if (OB_FAIL(query_hint.print_qb_name_hints(plan_text))) {
|
||||
LOG_WARN("failed to print qb name hints", K(ret));
|
||||
} else if (OB_FAIL(query_hint.print_transform_hints(plan_text))) {
|
||||
LOG_WARN("failed to print all transform hints", K(ret));
|
||||
} else if (OB_FAIL(query_hint.get_global_hint().print_global_hint(plan_text))) {
|
||||
LOG_WARN("failed to print global hint", K(ret));
|
||||
} else {
|
||||
BUF_PRINT_CONST_STR(" */", plan_text);
|
||||
}
|
||||
if (OB_SIZE_OVERFLOW == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSqlPlan::get_global_hint_outline(PlanText &plan_text, ObLogPlan &plan)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -1046,10 +1077,12 @@ int ObSqlPlan::print_constraint_info(char *buf,
|
||||
int ObSqlPlan::format_sql_plan(ObIArray<ObSqlPlanItem*> &sql_plan_infos,
|
||||
ExplainType type,
|
||||
const ObExplainDisplayOpt& option,
|
||||
PlanText &plan_text)
|
||||
PlanText &plan_text,
|
||||
const bool alloc_buffer)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(init_buffer(plan_text))) {
|
||||
if (alloc_buffer &&
|
||||
OB_FAIL(init_buffer(plan_text))) {
|
||||
LOG_WARN("failed to init buffer", K(ret));
|
||||
} else if (sql_plan_infos.empty()) {
|
||||
//do nothing
|
||||
@ -1168,7 +1201,11 @@ int ObSqlPlan::get_plan_table_formatter(ObIArray<ObSqlPlanItem*> &sql_plan_infos
|
||||
}
|
||||
//EST ROWS
|
||||
if (OB_SUCC(ret)) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cardinality_);
|
||||
if (plan_item->cardinality_ >= 0) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cardinality_);
|
||||
} else {
|
||||
snprintf(buffer, sizeof(buffer), "%s", "more than 1.0e19");
|
||||
}
|
||||
length = (int32_t) strlen(buffer);
|
||||
if (length > format_helper.column_len_.at(EstRows)) {
|
||||
format_helper.column_len_.at(EstRows) = length;
|
||||
@ -1176,7 +1213,11 @@ int ObSqlPlan::get_plan_table_formatter(ObIArray<ObSqlPlanItem*> &sql_plan_infos
|
||||
}
|
||||
//EST COST
|
||||
if (OB_SUCC(ret)) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cost_);
|
||||
if (plan_item->cost_ >= 0) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cost_);
|
||||
} else {
|
||||
snprintf(buffer, sizeof(buffer), "%s", "more than 1.0e19");
|
||||
}
|
||||
length = (int32_t) strlen(buffer);
|
||||
if (length > format_helper.column_len_.at(EstCost)) {
|
||||
format_helper.column_len_.at(EstCost) = length;
|
||||
@ -1230,7 +1271,11 @@ int ObSqlPlan::get_real_plan_table_formatter(ObIArray<ObSqlPlanItem*> &sql_plan_
|
||||
}
|
||||
//EST ROWS
|
||||
if (OB_SUCC(ret)) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cardinality_);
|
||||
if (plan_item->cardinality_ >= 0) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cardinality_);
|
||||
} else {
|
||||
snprintf(buffer, sizeof(buffer), "%s", "more than 1.0e19");
|
||||
}
|
||||
length = (int32_t) strlen(buffer);
|
||||
if (length > format_helper.column_len_.at(EstRows)) {
|
||||
format_helper.column_len_.at(EstRows) = length;
|
||||
@ -1238,7 +1283,11 @@ int ObSqlPlan::get_real_plan_table_formatter(ObIArray<ObSqlPlanItem*> &sql_plan_
|
||||
}
|
||||
//EST COST
|
||||
if (OB_SUCC(ret)) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cost_);
|
||||
if (plan_item->cost_ >= 0) {
|
||||
snprintf(buffer, sizeof(buffer), "%ld", plan_item->cost_);
|
||||
} else {
|
||||
snprintf(buffer, sizeof(buffer), "%s", "more than 1.0e19");
|
||||
}
|
||||
length = (int32_t) strlen(buffer);
|
||||
if (length > format_helper.column_len_.at(EstCost)) {
|
||||
format_helper.column_len_.at(EstCost) = length;
|
||||
@ -1431,13 +1480,13 @@ int ObSqlPlan::get_operator_prefix(ObIArray<ObSqlPlanItem*> &sql_plan_infos,
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpect idx", K(ret));
|
||||
} else if (prefix_helper.with_line_.at(j)) {
|
||||
const char *txt = "│ ";
|
||||
const char *txt = get_tree_line(0);
|
||||
if (plan_item->parent_id_ == parent_item->id_) {
|
||||
if (plan_item->is_last_child_) {
|
||||
txt = "└─";
|
||||
txt = get_tree_line(1);
|
||||
prefix_helper.with_line_.at(j) = false;
|
||||
} else {
|
||||
txt = "├─";
|
||||
txt = get_tree_line(2);
|
||||
}
|
||||
}
|
||||
if (prefix_helper.color_idxs_.at(j) >= 0) {
|
||||
@ -1664,16 +1713,28 @@ int ObSqlPlan::format_plan_table(ObIArray<ObSqlPlanItem*> &sql_plan_infos,
|
||||
//ROWS
|
||||
if (OB_SUCC(ret)) {
|
||||
ret = BUF_PRINTF(COLUMN_SEPARATOR);
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
if (plan_item->cardinality_ >= 0) {
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
format_helper.column_len_.at(EstRows),
|
||||
plan_item->cardinality_);
|
||||
} else {
|
||||
ret = BUF_PRINTF("%-*s",
|
||||
format_helper.column_len_.at(EstRows),
|
||||
"more than 1.0e19");
|
||||
}
|
||||
}
|
||||
//COST
|
||||
if (OB_SUCC(ret)) {
|
||||
ret = BUF_PRINTF(COLUMN_SEPARATOR);
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
if (plan_item->cost_ >= 0) {
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
format_helper.column_len_.at(EstCost),
|
||||
plan_item->cost_);
|
||||
} else {
|
||||
ret = BUF_PRINTF("%-*s",
|
||||
format_helper.column_len_.at(EstCost),
|
||||
"more than 1.0e19");
|
||||
}
|
||||
ret = BUF_PRINTF(COLUMN_SEPARATOR);
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -1781,16 +1842,28 @@ int ObSqlPlan::format_real_plan_table(ObIArray<ObSqlPlanItem*> &sql_plan_infos,
|
||||
//EST ROWS
|
||||
if (OB_SUCC(ret)) {
|
||||
ret = BUF_PRINTF(COLUMN_SEPARATOR);
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
if (plan_item->cardinality_ >= 0) {
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
format_helper.column_len_.at(EstRows),
|
||||
plan_item->cardinality_);
|
||||
} else {
|
||||
ret = BUF_PRINTF("%-*s",
|
||||
format_helper.column_len_.at(EstRows),
|
||||
"more than 1.0e19");
|
||||
}
|
||||
}
|
||||
//EST COST
|
||||
if (OB_SUCC(ret)) {
|
||||
ret = BUF_PRINTF(COLUMN_SEPARATOR);
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
if (plan_item->cost_ >= 0) {
|
||||
ret = BUF_PRINTF("%-*ld",
|
||||
format_helper.column_len_.at(EstCost),
|
||||
plan_item->cost_);
|
||||
} else {
|
||||
ret = BUF_PRINTF("%-*s",
|
||||
format_helper.column_len_.at(EstCost),
|
||||
"more than 1.0e19");
|
||||
}
|
||||
}
|
||||
//REAL ROWS
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -2332,6 +2405,7 @@ int ObSqlPlan::init_buffer(PlanText &plan_text)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
plan_text.buf_len_ = 1024 * 1024;
|
||||
plan_text.pos_ = 0;
|
||||
plan_text.buf_ = static_cast<char*>(allocator_.alloc(plan_text.buf_len_));
|
||||
if (OB_ISNULL(plan_text.buf_)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
@ -2459,5 +2533,32 @@ int ObSqlPlan::restore_session(ObSQLSessionInfo *session,
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* ObSqlPlan::get_tree_line(int type)
|
||||
{
|
||||
static const char *tree_line[] = {
|
||||
"│ ",
|
||||
"└─",
|
||||
"├─",
|
||||
"| ",
|
||||
"+-",
|
||||
"|-"
|
||||
};
|
||||
int ret = OB_SUCCESS;
|
||||
ObCharsetType client_character = ObCharsetType::CHARSET_INVALID;
|
||||
ObCharsetType connection_character = ObCharsetType::CHARSET_INVALID;
|
||||
if (NULL == session_ ||
|
||||
OB_FAIL(session_->get_character_set_client(client_character)) ||
|
||||
OB_FAIL(session_->get_character_set_connection(connection_character))) {
|
||||
return tree_line[type%3];
|
||||
} else if ((ObCharsetType::CHARSET_BINARY == client_character ||
|
||||
ObCharsetType::CHARSET_UTF8MB4 == client_character) &&
|
||||
(ObCharsetType::CHARSET_BINARY == connection_character ||
|
||||
ObCharsetType::CHARSET_UTF8MB4 == connection_character)) {
|
||||
return tree_line[type%3];
|
||||
} else {
|
||||
return tree_line[3+type%3];
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace sql
|
||||
} // end of namespace oceanbase
|
||||
|
||||
@ -125,6 +125,7 @@ private:
|
||||
public:
|
||||
ObSqlPlan(common::ObIAllocator &allocator);
|
||||
virtual ~ObSqlPlan();
|
||||
void set_session_info(ObSQLSessionInfo *session) { session_ = session; }
|
||||
int store_sql_plan(ObLogPlan* log_plan, ObPhysicalPlan* phy_plan);
|
||||
|
||||
int store_sql_plan_for_explain(ObExecContext *ctx,
|
||||
@ -144,11 +145,15 @@ public:
|
||||
int format_sql_plan(ObIArray<ObSqlPlanItem*> &sql_plan_infos,
|
||||
ExplainType type,
|
||||
const ObExplainDisplayOpt& option,
|
||||
PlanText &plan_text);
|
||||
PlanText &plan_text,
|
||||
const bool alloc_buffer = true);
|
||||
|
||||
static int get_plan_outline_info_one_line(PlanText &plan_text,
|
||||
ObLogPlan* plan);
|
||||
|
||||
static int get_plan_used_hint_info_one_line(PlanText &plan_text,
|
||||
ObLogPlan* plan);
|
||||
|
||||
static int plan_text_to_string(PlanText &plan_text,
|
||||
common::ObString &plan_str);
|
||||
|
||||
@ -180,8 +185,8 @@ private:
|
||||
ObLogPlan* plan,
|
||||
ObSqlPlanItem* sql_plan_item);
|
||||
|
||||
int get_plan_tree_used_hint(PlanText &plan_text,
|
||||
ObLogicalOperator* op);
|
||||
static int get_plan_tree_used_hint(PlanText &plan_text,
|
||||
ObLogicalOperator* op);
|
||||
|
||||
int get_qb_name_trace(PlanText &plan_text,
|
||||
ObLogPlan* plan,
|
||||
@ -282,6 +287,8 @@ private:
|
||||
transaction::ObTxDesc *tx_desc,
|
||||
int64_t nested_count);
|
||||
|
||||
const char* get_tree_line(int type);
|
||||
|
||||
public:
|
||||
static int format_one_output_expr(char *buf,
|
||||
int64_t buf_len,
|
||||
@ -294,6 +301,7 @@ public:
|
||||
|
||||
private:
|
||||
common::ObIAllocator &allocator_;
|
||||
ObSQLSessionInfo *session_;
|
||||
};
|
||||
|
||||
} // end of namespace sql
|
||||
|
||||
Reference in New Issue
Block a user