fix auto generated identifier is too long
This commit is contained in:
parent
0fe117b645
commit
af61c60757
@ -2065,7 +2065,7 @@ int ObDMLStmtPrinter::print_with()
|
||||
|| TableItem::RECURSIVE_CTE == cte_table->cte_type_) {
|
||||
if (OB_FAIL(print_cte_define_title(cte_table))) {
|
||||
LOG_WARN("print column name failed", K(ret));
|
||||
} else if (OB_FAIL(print_subquery(cte_table->ref_query_, PRINT_BRACKET))) {
|
||||
} else if (OB_FAIL(print_subquery(cte_table->ref_query_, PRINT_BRACKET | FORCE_COL_ALIAS))) {
|
||||
LOG_WARN("print table failed", K(ret));
|
||||
} else if (OB_FAIL(print_search_and_cycle(cte_table->ref_query_))) {
|
||||
LOG_WARN("print search and cycle failed", K(ret));
|
||||
|
@ -164,6 +164,8 @@ int ObCreateViewResolver::resolve(const ParseNode &parse_tree)
|
||||
} else {
|
||||
LOG_WARN("resolve select in create view failed", K(select_stmt_node), K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(view_table_resolver.check_auto_gen_column_names())) {
|
||||
LOG_WARN("fail to check auto gen column names", K(ret));
|
||||
} else if (OB_FAIL(params_.query_ctx_->query_hint_.init_query_hint(params_.allocator_,
|
||||
params_.session_info_,
|
||||
view_table_resolver.get_select_stmt()))) {
|
||||
|
@ -6471,6 +6471,90 @@ int ObSelectResolver::resolve_check_option_clause(const ParseNode *node)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ObSelectResolver::check_auto_gen_column_names()
|
||||
*
|
||||
* For a long expr with no alias
|
||||
* MySQL will rename the overlong auto generated alias to "Name_exp_x",
|
||||
* but Oracle will throw "identifier is too long" error.
|
||||
*/
|
||||
int ObSelectResolver::check_auto_gen_column_names() {
|
||||
int ret = OB_SUCCESS;
|
||||
ObSelectStmt *select_stmt = get_select_stmt();
|
||||
if (OB_ISNULL(select_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("select stmt is null", K(ret));
|
||||
} else if (OB_FAIL(recursive_check_auto_gen_column_names(select_stmt))) {
|
||||
LOG_WARN("fail to check auto gen column names", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSelectResolver::recursive_check_auto_gen_column_names(ObSelectStmt *select_stmt) {
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObSelectStmt*, 4> child_stmts;
|
||||
if (OB_ISNULL(select_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("select stmt is null", K(ret));
|
||||
} else if (OB_FAIL(select_stmt->get_child_stmts(child_stmts))) {
|
||||
LOG_WARN("fail to get child stmts", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); i++) {
|
||||
ObSelectStmt *child_stmt = child_stmts.at(i);
|
||||
if (OB_ISNULL(child_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("child select stmt is null", K(ret), K(i));
|
||||
} else if (OB_FAIL(SMART_CALL(recursive_check_auto_gen_column_names(child_stmt)))) {
|
||||
LOG_WARN("fail to check child stmt", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < select_stmt->get_select_item_size(); ++i) {
|
||||
SelectItem *select_item = &(select_stmt->get_select_item(i));
|
||||
if (OB_ISNULL(select_item) || OB_ISNULL(select_item->expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("select item expr is null", K(ret), K(select_item));
|
||||
} else if (select_item->alias_name_.length() > static_cast<size_t>(OB_MAX_COLUMN_NAME_LENGTH)) {
|
||||
if (lib::is_oracle_mode()) {
|
||||
ret = OB_ERR_TOO_LONG_IDENT;
|
||||
LOG_WARN("auto generated alias is too long", K(ret), K(select_item->alias_name_.length()), K(select_item->alias_name_));
|
||||
} else {
|
||||
char temp_str_buf[OB_MAX_COLUMN_NAME_BUF_LENGTH] = { 0 };
|
||||
if (snprintf(temp_str_buf, sizeof(temp_str_buf), SYNTHETIC_FIELD_NAME "%ld", auto_name_id_++) < 0) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("failed to generate buffer for temp_str_buf", K(ret));
|
||||
} else {
|
||||
ObString tmp_col_name = ObString::make_string(temp_str_buf);
|
||||
ObString col_name;
|
||||
if (OB_FAIL(ob_write_string(*allocator_, tmp_col_name, col_name))) {
|
||||
LOG_WARN("Can not malloc space for constraint name", K(ret));
|
||||
} else if (OB_FALSE_IT(select_item->alias_name_.assign_ptr(col_name.ptr(), col_name.length()))) {
|
||||
} else if (select_item->expr_->is_column_ref_expr()) {
|
||||
ObColumnRefRawExpr *col_ref_expr = static_cast<ObColumnRefRawExpr*>(select_item->expr_);
|
||||
TableItem *table_item = NULL;
|
||||
ObSelectStmt *ref_stmt = NULL;
|
||||
SelectItem *ref_select_item = NULL;
|
||||
if (OB_ISNULL(table_item = select_stmt->get_table_item_by_id(col_ref_expr->get_table_id()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("table item is null", K(ret));
|
||||
} else if (OB_ISNULL(ref_stmt = table_item->ref_query_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("ref query stmt is null", K(ret));
|
||||
} else if (OB_ISNULL(ref_select_item = &ref_stmt->get_select_item(col_ref_expr->get_column_id() - OB_APP_MIN_COLUMN_ID))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("select item is null", K(ret));
|
||||
} else if (OB_FAIL(ob_write_string(*allocator_, ref_select_item->alias_name_, col_name))) {
|
||||
LOG_WARN("Can not malloc space for constraint name", K(ret));
|
||||
} else {
|
||||
col_ref_expr->get_column_name().assign_ptr(col_name.ptr(), col_name.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSelectResolver::check_rollup_items_valid(const ObIArray<ObRollupItem> &rollup_items)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "sql/rewrite/ob_stmt_comparer.h"
|
||||
#include "common/ob_smart_call.h"
|
||||
|
||||
# define SYNTHETIC_FIELD_NAME "Name_exp_"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
@ -87,6 +89,7 @@ public:
|
||||
ObString &cycle_pseudo_column_name);
|
||||
void set_current_recursive_cte_table_item(TableItem *table_item) { current_recursive_cte_table_item_ = table_item; }
|
||||
void set_current_cte_involed_stmt(ObSelectStmt *stmt) { current_cte_involed_stmt_ = stmt; }
|
||||
int check_auto_gen_column_names();
|
||||
|
||||
// function members
|
||||
TO_STRING_KV(K_(has_calc_found_rows),
|
||||
@ -345,6 +348,7 @@ private:
|
||||
|
||||
int resolve_shared_order_item(OrderItem &order_item, ObSelectStmt *select_stmt);
|
||||
int adjust_recursive_cte_table_columns(const ObSelectStmt* parent_stmt, ObSelectStmt *right_stmt);
|
||||
int recursive_check_auto_gen_column_names(ObSelectStmt *select_stmt);
|
||||
protected:
|
||||
// data members
|
||||
/*these member is only for with clause*/
|
||||
|
@ -194,33 +194,13 @@ int ObViewTableResolver::set_select_item(SelectItem &select_item, bool is_auto_g
|
||||
}
|
||||
} else if (OB_FAIL(session_info_->get_collation_connection(cs_type))) {
|
||||
LOG_WARN("fail to get collation_connection", K(ret));
|
||||
} else {
|
||||
// 如果子查询列没有别名,超过 64 的话系统则自动为其会生成一个列别名
|
||||
if (!is_create_view_ && !select_item.is_real_alias_ && is_auto_gen
|
||||
&& select_item.alias_name_.length() > static_cast<size_t>(
|
||||
OB_MAX_VIEW_COLUMN_NAME_LENGTH_MYSQL)) {
|
||||
ObString tmp_col_name;
|
||||
ObString col_name;
|
||||
char temp_str_buf[number::ObNumber::MAX_PRINTABLE_SIZE];
|
||||
if (snprintf(temp_str_buf, sizeof(temp_str_buf), "Name_exp_%ld", auto_name_id_++) < 0) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
SQL_RESV_LOG(WARN, "failed to generate buffer for temp_str_buf", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
tmp_col_name = ObString::make_string(temp_str_buf);
|
||||
if (OB_FAIL(ob_write_string(*allocator_, tmp_col_name, col_name))) {
|
||||
SQL_RESV_LOG(WARN, "Can not malloc space for constraint name", K(ret));
|
||||
} else {
|
||||
select_item.alias_name_.assign_ptr(col_name.ptr(), col_name.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(ObSQLUtils::check_column_name(cs_type, select_item.alias_name_, true))) {
|
||||
LOG_WARN("fail to make field name", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(select_stmt->add_select_item(select_item))) {
|
||||
LOG_WARN("add select item to select stmt failed", K(ret));
|
||||
}
|
||||
} else if (select_item.is_real_alias_
|
||||
&& OB_FAIL(ObSQLUtils::check_column_name(cs_type, select_item.alias_name_, true))) {
|
||||
// Only check real alias here,
|
||||
// auto generated alias will be checked in ObSelectResolver::check_auto_gen_column_names().
|
||||
LOG_WARN("fail to make field name", K(ret));
|
||||
} else if (OB_FAIL(select_stmt->add_select_item(select_item))) {
|
||||
LOG_WARN("add select item to select stmt failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user