fix missing cast when simplify set stmt
This commit is contained in:
parent
a1e6b1c440
commit
0c6b823cc8
@ -724,76 +724,68 @@ int ObTransformSimplifySet::replace_set_stmt_with_child_stmt(ObSelectStmt *&pare
|
||||
ObSelectStmt *child_stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(parent_stmt) || OB_ISNULL(child_stmt)) {
|
||||
if (OB_ISNULL(parent_stmt) || OB_ISNULL(child_stmt) || OB_ISNULL(ctx_) || OB_ISNULL(ctx_->expr_factory_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get null pointer", K(ret));
|
||||
} else {
|
||||
if ((parent_stmt->has_order_by() && (child_stmt->has_order_by() || child_stmt->has_limit()))
|
||||
|| (parent_stmt->has_limit() && child_stmt->has_limit())
|
||||
|| (parent_stmt->is_set_distinct() && child_stmt->has_limit())
|
||||
|| (parent_stmt->has_select_into() && child_stmt->has_select_into())) {
|
||||
/* 1. for limit clause
|
||||
* if both parent_stmt and child_stmt has limit, we should create a view to hold parent's limit.
|
||||
*
|
||||
* 2. for add_order_by, child stmt shouldn't have order_by_items or limit items.
|
||||
* if we meet conflict order by items. We can't directly reset child's order by.
|
||||
* e.g., select * from t1 order by c1 limit 2 UNION ALL select * from t2 where 1=2 order by c2;
|
||||
* if we overwrite the order by, the result is not correct.
|
||||
*
|
||||
* 3. for distinct.
|
||||
* if child stmt has limit, we can't add distinct to child stmt. Since limit should be done before distinct.
|
||||
*
|
||||
* 4. select into is not allowed in subquery, we add the code here to handle conflict select into.
|
||||
* just in case of some transformer rule generating conflict select into.
|
||||
*/
|
||||
ObSelectStmt *view_stmt = NULL;
|
||||
if (OB_FAIL(ObTransformUtils::create_stmt_with_generated_table(ctx_, child_stmt, view_stmt))) {
|
||||
LOG_WARN("fail to create view with generated table", K(ret));
|
||||
} else if (OB_ISNULL(view_stmt)) {
|
||||
LOG_WARN("view table is null", K(ret));
|
||||
} else if (OB_FAIL(add_order_by(view_stmt, parent_stmt))) {
|
||||
// set child's order by to view.
|
||||
LOG_WARN("fail to assign parents's order items to child", K(ret));
|
||||
} else {
|
||||
//set child's limit to view. and reset child's order by items.
|
||||
view_stmt->set_fetch_info(parent_stmt->get_offset_expr(),
|
||||
parent_stmt->get_limit_expr(),
|
||||
parent_stmt->get_limit_percent_expr());
|
||||
if (parent_stmt->is_set_distinct()) {
|
||||
view_stmt->assign_distinct();
|
||||
}
|
||||
if (parent_stmt->has_select_into()) {
|
||||
view_stmt->set_select_into(parent_stmt->get_select_into());
|
||||
}
|
||||
parent_stmt = view_stmt;
|
||||
}
|
||||
/* 1. for limit clause
|
||||
* if both parent_stmt and child_stmt has limit, we should create a view to hold parent's limit.
|
||||
*
|
||||
* 2. for add_order_by, child stmt shouldn't have order_by_items or limit items.
|
||||
* if we meet conflict order by items. We can't directly reset child's order by.
|
||||
* e.g., select * from t1 order by c1 limit 2 UNION ALL select * from t2 where 1=2 order by c2;
|
||||
* if we overwrite the order by, the result is not correct.
|
||||
*
|
||||
* 3. for distinct.
|
||||
* if child stmt has limit, we can't add distinct to child stmt. Since limit should be done before distinct.
|
||||
*
|
||||
* 4. select into is not allowed in subquery, we add the code here to handle conflict select into.
|
||||
* just in case of some transformer rule generating conflict select into.
|
||||
*/
|
||||
ObSelectStmt *view_stmt = NULL;
|
||||
if (OB_FAIL(ObTransformUtils::create_stmt_with_generated_table(ctx_, child_stmt, view_stmt))) {
|
||||
LOG_WARN("fail to create view with generated table", K(ret));
|
||||
} else if (OB_ISNULL(view_stmt)) {
|
||||
LOG_WARN("view table is null", K(ret));
|
||||
} else if (OB_FAIL(add_order_by(view_stmt, parent_stmt))) {
|
||||
// set child's order by to view.
|
||||
LOG_WARN("fail to assign parents's order items to child", K(ret));
|
||||
} else {
|
||||
/* order by clause*/
|
||||
if (parent_stmt->has_order_by()) {
|
||||
if (OB_FAIL(add_order_by(child_stmt, parent_stmt))) {
|
||||
LOG_WARN("fail to assign parents's order items to child", K(ret));
|
||||
// set child's limit to view. and reset child's order by items.
|
||||
view_stmt->set_fetch_info(parent_stmt->get_offset_expr(),
|
||||
parent_stmt->get_limit_expr(),
|
||||
parent_stmt->get_limit_percent_expr());
|
||||
if (parent_stmt->is_set_distinct()) {
|
||||
view_stmt->assign_distinct();
|
||||
}
|
||||
if (parent_stmt->has_select_into()) {
|
||||
view_stmt->set_select_into(parent_stmt->get_select_into());
|
||||
}
|
||||
// if the result type of the view stmt's projection expr does not match that of the parent set stmt
|
||||
// cast expr need to be added to view's select items
|
||||
if (OB_SUCC(ret) && OB_UNLIKELY(view_stmt->get_select_item_size() != parent_stmt->get_select_item_size())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("select item size missmatch", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < view_stmt->get_select_item_size(); i++) {
|
||||
ObRawExpr *expr1 = parent_stmt->get_select_item(i).expr_;
|
||||
ObRawExpr *expr2 = view_stmt->get_select_item(i).expr_;
|
||||
if (OB_ISNULL(expr1) || OB_ISNULL(expr2)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null pointer", K(ret), KP(expr1), KP(expr2));
|
||||
} else {
|
||||
if (OB_FAIL(ObTransformUtils::add_cast_for_replace_if_need(*(ctx_->expr_factory_),
|
||||
expr1,
|
||||
expr2,
|
||||
ctx_->session_info_))) {
|
||||
LOG_WARN("fail to add cast expr for replace", K(ret));
|
||||
} else {
|
||||
view_stmt->get_select_item(i).expr_ = expr2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && parent_stmt->is_set_distinct()) {
|
||||
if (child_stmt->is_set_stmt()) {
|
||||
child_stmt->assign_set_distinct();
|
||||
} else {
|
||||
child_stmt->assign_distinct();
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && parent_stmt->has_select_into()) {
|
||||
child_stmt->set_select_into(parent_stmt->get_select_into());
|
||||
}
|
||||
|
||||
/*limit clause*/
|
||||
if (OB_SUCC(ret) && parent_stmt->has_limit()) {
|
||||
child_stmt->set_fetch_info(parent_stmt->get_offset_expr(),
|
||||
parent_stmt->get_limit_expr(),
|
||||
parent_stmt->get_limit_percent_expr());
|
||||
}
|
||||
parent_stmt = child_stmt;
|
||||
parent_stmt = view_stmt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4352,11 +4352,13 @@ int ObTransformUtils::add_cast_for_replace_if_need(ObRawExprFactory &expr_factor
|
||||
} else {
|
||||
const ObExprResType &src_type = from_expr->get_result_type();
|
||||
const ObExprResType &dst_type = to_expr->get_result_type();
|
||||
bool need_length_cast = (ob_is_string_or_lob_type(dst_type.get_type()) || ob_is_rowid_tc(dst_type.get_type()))
|
||||
? (src_type.get_length() != dst_type.get_length()) : false;
|
||||
bool need_cast = (src_type.get_type() != dst_type.get_type()) ||
|
||||
(src_type.get_length() != dst_type.get_length()) ||
|
||||
(src_type.get_precision() != dst_type.get_precision()) ||
|
||||
(src_type.get_scale() != dst_type.get_scale()) ||
|
||||
from_expr->get_result_type().has_result_flag(ZEROFILL_FLAG);
|
||||
from_expr->get_result_type().has_result_flag(ZEROFILL_FLAG) ||
|
||||
need_length_cast;
|
||||
if (ob_is_string_or_lob_type(src_type.get_type())) {
|
||||
need_cast |= (src_type.get_collation_type() != dst_type.get_collation_type()) ||
|
||||
(src_type.get_collation_level() != dst_type.get_collation_level());
|
||||
|
@ -3955,7 +3955,7 @@ Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([v0.v1]), filter(nil), rowset=16
|
||||
conds(nil), nl_params_(nil), use_batch=false
|
||||
1 - output([v0.v1]), filter([v0.v1 = cast(cast(-127, VARCHAR(20)), VARCHAR(1048576))]), rowset=16
|
||||
1 - output([v0.v1]), filter([v0.v1 = cast(cast(-127, VARCHAR(20)), VARCHAR(20))]), rowset=16
|
||||
access([v0.v1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([v0.__pk_increment]), range(MIN ; MAX)always true
|
||||
@ -3984,7 +3984,7 @@ Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([v0.v1]), filter(nil), rowset=16
|
||||
conds(nil), nl_params_(nil), use_batch=false
|
||||
1 - output([v0.v1]), filter([v0.v1 = cast(cast(-127, VARCHAR(20)), VARCHAR(1048576))]), rowset=16
|
||||
1 - output([v0.v1]), filter([v0.v1 = cast(cast(-127, VARCHAR(20)), VARCHAR(20))]), rowset=16
|
||||
access([v0.v1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([v0.__pk_increment]), range(MIN ; MAX)always true
|
||||
|
Loading…
x
Reference in New Issue
Block a user