Fix dblink bugs
This commit is contained in:
		| @ -1112,7 +1112,7 @@ int ObDMLStmtPrinter::print_where() | |||||||
|       } else if (condition_exprs_size > 0 && stmt_->get_semi_info_size() > 0) { |       } else if (condition_exprs_size > 0 && stmt_->get_semi_info_size() > 0) { | ||||||
|         DATA_PRINTF(" and "); |         DATA_PRINTF(" and "); | ||||||
|       } |       } | ||||||
|       if (OB_FAIL(print_semi_info_to_subquery())) { |       if (OB_SUCC(ret) && OB_FAIL(print_semi_info_to_subquery())) { | ||||||
|         LOG_WARN("failed to print semi info to subquery", K(ret)); |         LOG_WARN("failed to print semi info to subquery", K(ret)); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -207,14 +207,17 @@ int ObRawExprPrinter::print(ObConstRawExpr *expr) | |||||||
|   } else if (print_params_.for_dblink_ && T_QUESTIONMARK == expr->get_expr_type()) { |   } else if (print_params_.for_dblink_ && T_QUESTIONMARK == expr->get_expr_type()) { | ||||||
|     int64_t idx = expr->get_value().get_unknown(); |     int64_t idx = expr->get_value().get_unknown(); | ||||||
|     bool is_bool_expr = false; |     bool is_bool_expr = false; | ||||||
|  |     bool is_null_type = ob_is_null(expr->get_result_type().get_type()); | ||||||
|     if (expr->is_exec_param_expr()) { |     if (expr->is_exec_param_expr()) { | ||||||
|       ObExecParamRawExpr *exec_expr = static_cast<ObExecParamRawExpr*>(expr); |       ObExecParamRawExpr *exec_expr = static_cast<ObExecParamRawExpr*>(expr); | ||||||
|       if (OB_FAIL(ObRawExprUtils::check_is_bool_expr(exec_expr->get_ref_expr(), is_bool_expr))) { |       if (OB_FAIL(ObRawExprUtils::check_is_bool_expr(exec_expr->get_ref_expr(), is_bool_expr))) { | ||||||
|         LOG_WARN("failed to check is bool expr", K(ret)); |         LOG_WARN("failed to check is bool expr", K(ret)); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** To preserve the type information of questionmark when it is NULL, print a cast*/ | ||||||
|     if (OB_FAIL(ret)) { |     if (OB_FAIL(ret)) { | ||||||
|     } else if (is_bool_expr) { |     } else if (is_bool_expr && OB_FAIL(databuff_printf(buf_, buf_len_, *pos_, "1 = "))) { | ||||||
|       /** |       /** | ||||||
|        * For SQL like "select * from T1 where C1 = 1 and C1 = 2", |        * For SQL like "select * from T1 where C1 = 1 and C1 = 2", | ||||||
|        * because the where clause is always false, |        * because the where clause is always false, | ||||||
| @ -223,19 +226,18 @@ int ObRawExprPrinter::print(ObConstRawExpr *expr) | |||||||
|        * by rewriting startup_filter as "0 = 1" or "1 = 1". |        * by rewriting startup_filter as "0 = 1" or "1 = 1". | ||||||
|        * |        * | ||||||
|        */ |        */ | ||||||
|       if (OB_FAIL(databuff_printf(buf_, buf_len_, *pos_, "1 = "))) { |       LOG_WARN("fail to print 1 =", K(ret)); | ||||||
|         LOG_WARN("fail to print startup filter", K(ret)); |     } else if (!is_null_type && OB_FAIL(databuff_printf(buf_, buf_len_, *pos_, "cast("))) { | ||||||
|       } else if (OB_NOT_NULL(param_store_) && 0 <= idx && idx < param_store_->count()) { |       LOG_WARN("fail to print cast(", K(ret)); | ||||||
|         OZ (param_store_->at(idx).print_sql_literal(buf_, buf_len_, *pos_, print_params_)); |     } else if (OB_NOT_NULL(param_store_) && 0 <= idx && idx < param_store_->count()) { | ||||||
|       } else if (OB_FAIL(ObLinkStmtParam::write(buf_, buf_len_, *pos_, expr->get_value().get_unknown()))) { |       OZ (param_store_->at(idx).print_sql_literal(buf_, buf_len_, *pos_, print_params_)); | ||||||
|         LOG_WARN("fail to write param to buf", K(ret)); |     } else if (OB_FAIL(ObLinkStmtParam::write(buf_, buf_len_, *pos_, expr->get_value().get_unknown()))) { | ||||||
|       } |       LOG_WARN("fail to write param to buf", K(ret)); | ||||||
|     } else { |     } | ||||||
|       if (OB_NOT_NULL(param_store_) && 0 <= idx && idx < param_store_->count()) { |     if (OB_SUCC(ret) && !is_null_type) { | ||||||
|         OZ (param_store_->at(idx).print_sql_literal(buf_, buf_len_, *pos_, print_params_)); |       DATA_PRINTF(" as "); | ||||||
|       } else if (OB_FAIL(ObLinkStmtParam::write(buf_, buf_len_, *pos_, expr->get_value().get_unknown()))) { |       OZ(print_type(expr->get_result_type())); | ||||||
|         LOG_WARN("fail to write param to buf", K(ret)); |       DATA_PRINTF(")"); | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } else if (OB_NOT_NULL(param_store_) && T_QUESTIONMARK == expr->get_expr_type()) { |   } else if (OB_NOT_NULL(param_store_) && T_QUESTIONMARK == expr->get_expr_type()) { | ||||||
|     int64_t idx = expr->get_value().get_unknown(); |     int64_t idx = expr->get_value().get_unknown(); | ||||||
| @ -2505,7 +2507,7 @@ int ObRawExprPrinter::print(ObSysFunRawExpr *expr) | |||||||
|           if (OB_SUCC(ret)) { |           if (OB_SUCC(ret)) { | ||||||
|             PRINT_EXPR(expr->get_param_expr(0)); |             PRINT_EXPR(expr->get_param_expr(0)); | ||||||
|             DATA_PRINTF(" as "); |             DATA_PRINTF(" as "); | ||||||
|             if (OB_FAIL(print_cast_type(expr->get_param_expr(1)))) { |             if (OB_SUCC(ret) && OB_FAIL(print_cast_type(expr->get_param_expr(1)))) { | ||||||
|               LOG_WARN("fail to print cast_type", K(ret)); |               LOG_WARN("fail to print cast_type", K(ret)); | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
| @ -3918,6 +3920,23 @@ int ObRawExprPrinter::pre_check_treat_opt(ObRawExpr *expr, bool &is_treat) | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int ObRawExprPrinter::print_type(const ObExprResType &dst_type) | ||||||
|  | { | ||||||
|  |   int ret = OB_SUCCESS; | ||||||
|  |   ObConstRawExpr *type_expr = NULL; | ||||||
|  |   ObArenaAllocator allocator("PrintType"); | ||||||
|  |   ObRawExprFactory expr_factory(allocator); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   if (OB_FAIL(ObRawExprUtils::create_type_expr(expr_factory, type_expr, | ||||||
|  |                                                dst_type, /*avoid_zero_len*/true))) { | ||||||
|  |     LOG_WARN("create type expr failed", K(ret)); | ||||||
|  |   } else if (OB_FAIL(print_cast_type(type_expr))) { | ||||||
|  |     LOG_WARN("failed to print cast type", K(ret)); | ||||||
|  |   } | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
| int ObRawExprPrinter::print_cast_type(ObRawExpr *expr) | int ObRawExprPrinter::print_cast_type(ObRawExpr *expr) | ||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|  | |||||||
| @ -142,6 +142,8 @@ private: | |||||||
|   int print_order_items(ObWinFunRawExpr *expr); |   int print_order_items(ObWinFunRawExpr *expr); | ||||||
|   int print_window_clause(ObWinFunRawExpr *expr); |   int print_window_clause(ObWinFunRawExpr *expr); | ||||||
|  |  | ||||||
|  |   int print_type(const ObExprResType &dst_type); | ||||||
|  |  | ||||||
|   int inner_print_fun_params(ObSysFunRawExpr &expr); |   int inner_print_fun_params(ObSysFunRawExpr &expr); | ||||||
|  |  | ||||||
|   // disallow copy |   // disallow copy | ||||||
|  | |||||||
| @ -6840,77 +6840,18 @@ int ObRawExprUtils::create_real_cast_expr(ObRawExprFactory &expr_factory, | |||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   ObConstRawExpr *dst_expr = NULL; |   ObConstRawExpr *dst_expr = NULL; | ||||||
|   ParseNode parse_node; |  | ||||||
|   memset(&parse_node, 0, sizeof(ParseNode)); |  | ||||||
|   ObObj val; |  | ||||||
|  |  | ||||||
|   if (OB_ISNULL(src_expr) || OB_ISNULL(session_info)) { |   if (OB_ISNULL(src_expr) || OB_ISNULL(session_info)) { | ||||||
|     ret = OB_INVALID_ARGUMENT; |     ret = OB_INVALID_ARGUMENT; | ||||||
|     LOG_WARN("invalid args", KP(src_expr), KP(session_info)); |     LOG_WARN("invalid args", KP(src_expr), KP(session_info)); | ||||||
|   } else { |   } else { | ||||||
|     if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_CAST, func_expr))) { |     if (OB_FAIL(expr_factory.create_raw_expr(T_FUN_SYS_CAST, func_expr))) { | ||||||
|       LOG_WARN("create cast expr failed", K(ret)); |       LOG_WARN("create cast expr failed", K(ret)); | ||||||
|     } else if (OB_FAIL(expr_factory.create_raw_expr(T_INT, dst_expr))) { |     } else if (OB_FAIL(create_type_expr(expr_factory, dst_expr, dst_type))) { | ||||||
|       LOG_WARN("create dest type expr failed", K(ret)); |       LOG_WARN("create type expr failed", K(ret)); | ||||||
|     } else if (OB_FAIL(func_expr->add_param_expr(src_expr))) { |     } else if (OB_FAIL(func_expr->add_param_expr(src_expr))) { | ||||||
|       LOG_WARN("add real param expr failed", K(ret)); |       LOG_WARN("add real param expr failed", K(ret)); | ||||||
|     } else { |     } else { | ||||||
|       ObString func_name = ObString::make_string(N_CAST); |       ObString func_name = ObString::make_string(N_CAST); | ||||||
|       parse_node.int16_values_[OB_NODE_CAST_TYPE_IDX] = static_cast<int16_t>(dst_type.get_type()); |  | ||||||
|       parse_node.int16_values_[OB_NODE_CAST_COLL_IDX] = static_cast<int16_t>( |  | ||||||
|                                                           dst_type.get_collation_type()); |  | ||||||
|       if (ob_is_string_or_lob_type(dst_type.get_type())) { |  | ||||||
|         parse_node.int32_values_[OB_NODE_CAST_C_LEN_IDX] = dst_type.get_length(); |  | ||||||
|         if (lib::is_oracle_mode()) { |  | ||||||
|           dst_expr->set_length_semantics(dst_type.get_length_semantics()); |  | ||||||
|         } |  | ||||||
|       } else if (ob_is_rowid_tc(dst_type.get_type())) { |  | ||||||
|         int32_t urowid_len = dst_type.get_length(); |  | ||||||
|         if (urowid_len <= -1) { |  | ||||||
|           urowid_len = 4000; |  | ||||||
|         } |  | ||||||
|         parse_node.int32_values_[OB_NODE_CAST_C_LEN_IDX] = 4000; |  | ||||||
|       } else if (ObIntervalYMType == dst_type.get_type()) { |  | ||||||
|         // TODO: @shaoge 针对ObIntervalYMType和ObIntervalDSType,parse_node的设置需要写case验证 |  | ||||||
|         if (dst_type.get_scale() == -1) { |  | ||||||
|           // scale=-1 is invalid, update to default value |  | ||||||
|           ObCompatibilityMode compatibility_mode = get_compatibility_mode(); |  | ||||||
|           parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = |  | ||||||
|               ObAccuracy::DDL_DEFAULT_ACCURACY2[compatibility_mode] |  | ||||||
|                                                [ObIntervalYMType] |  | ||||||
|                                                    .get_scale(); |  | ||||||
|         } else { |  | ||||||
|           parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = |  | ||||||
|               dst_type.get_scale(); // year |  | ||||||
|         } |  | ||||||
|       } else if (ObIntervalDSType == dst_type.get_type()) { |  | ||||||
|         ObCompatibilityMode compatibility_mode = get_compatibility_mode(); |  | ||||||
|         parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = (dst_type.get_scale() / 10); // day |  | ||||||
|         if (dst_type.get_scale() == -1) { |  | ||||||
|           // scale=-1 is invalid, update to default value |  | ||||||
|           parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = 0; |  | ||||||
|         } else { |  | ||||||
|           parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = (dst_type.get_scale() % 10);// second |  | ||||||
|         } |  | ||||||
|       } else if ((ObTimestampNanoType == dst_type.get_type() || |  | ||||||
|                   ObTimestampTZType == dst_type.get_type() || |  | ||||||
|                   ObTimestampLTZType == dst_type.get_type()) && |  | ||||||
|                  dst_type.get_scale() == -1) { |  | ||||||
|         // scale=-1 is invalid, update to default value |  | ||||||
|         ObCompatibilityMode compatibility_mode = get_compatibility_mode(); |  | ||||||
|         parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = dst_type.get_precision(); |  | ||||||
|         parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = |  | ||||||
|               ObAccuracy::DDL_DEFAULT_ACCURACY2[compatibility_mode] |  | ||||||
|                                                [dst_type.get_type()] |  | ||||||
|                                                    .get_scale(); |  | ||||||
|       } else { |  | ||||||
|         parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = dst_type.get_precision(); |  | ||||||
|         parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = dst_type.get_scale(); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       val.set_int(parse_node.value_); |  | ||||||
|       dst_expr->set_value(val); |  | ||||||
|       dst_expr->set_param(val); |  | ||||||
|       func_expr->set_func_name(func_name); |       func_expr->set_func_name(func_name); | ||||||
|       if (src_expr->is_for_generated_column()) { |       if (src_expr->is_for_generated_column()) { | ||||||
|         func_expr->set_for_generated_column(); |         func_expr->set_for_generated_column(); | ||||||
| @ -6925,6 +6866,80 @@ int ObRawExprUtils::create_real_cast_expr(ObRawExprFactory &expr_factory, | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int ObRawExprUtils::create_type_expr(ObRawExprFactory &expr_factory, | ||||||
|  |                                      ObConstRawExpr *&type_expr, | ||||||
|  |                                      const ObExprResType &dst_type, | ||||||
|  |                                      bool avoid_zero_len) | ||||||
|  | { | ||||||
|  |   int ret = OB_SUCCESS; | ||||||
|  |   ObConstRawExpr *dst_expr = NULL; | ||||||
|  |   ParseNode parse_node; | ||||||
|  |   memset(&parse_node, 0, sizeof(ParseNode)); | ||||||
|  |   ObObj val; | ||||||
|  |   if (OB_FAIL(expr_factory.create_raw_expr(T_INT, dst_expr))) { | ||||||
|  |     LOG_WARN("create dest type expr failed", K(ret)); | ||||||
|  |   } else { | ||||||
|  |     parse_node.int16_values_[OB_NODE_CAST_TYPE_IDX] = static_cast<int16_t>(dst_type.get_type()); | ||||||
|  |     parse_node.int16_values_[OB_NODE_CAST_COLL_IDX] = static_cast<int16_t>( | ||||||
|  |                                                         dst_type.get_collation_type()); | ||||||
|  |     if (ob_is_string_or_lob_type(dst_type.get_type())) { | ||||||
|  |       parse_node.int32_values_[OB_NODE_CAST_C_LEN_IDX] = (avoid_zero_len && dst_type.get_length() == 0) ? | ||||||
|  |                                                           1 : dst_type.get_length(); | ||||||
|  |       if (lib::is_oracle_mode()) { | ||||||
|  |         dst_expr->set_length_semantics(dst_type.get_length_semantics()); | ||||||
|  |       } | ||||||
|  |     } else if (ob_is_rowid_tc(dst_type.get_type())) { | ||||||
|  |       int32_t urowid_len = dst_type.get_length(); | ||||||
|  |       if (urowid_len <= -1) { | ||||||
|  |         urowid_len = 4000; | ||||||
|  |       } | ||||||
|  |       parse_node.int32_values_[OB_NODE_CAST_C_LEN_IDX] = 4000; | ||||||
|  |     } else if (ObIntervalYMType == dst_type.get_type()) { | ||||||
|  |       // TODO: @shaoge 针对ObIntervalYMType和ObIntervalDSType,parse_node的设置需要写case验证 | ||||||
|  |       if (dst_type.get_scale() == -1) { | ||||||
|  |         // scale=-1 is invalid, update to default value | ||||||
|  |         ObCompatibilityMode compatibility_mode = get_compatibility_mode(); | ||||||
|  |         parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = | ||||||
|  |             ObAccuracy::DDL_DEFAULT_ACCURACY2[compatibility_mode] | ||||||
|  |                                              [ObIntervalYMType] | ||||||
|  |                                                  .get_scale(); | ||||||
|  |       } else { | ||||||
|  |         parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = | ||||||
|  |             dst_type.get_scale(); // year | ||||||
|  |       } | ||||||
|  |     } else if (ObIntervalDSType == dst_type.get_type()) { | ||||||
|  |       ObCompatibilityMode compatibility_mode = get_compatibility_mode(); | ||||||
|  |       parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = (dst_type.get_scale() / 10); // day | ||||||
|  |       if (dst_type.get_scale() == -1) { | ||||||
|  |         // scale=-1 is invalid, update to default value | ||||||
|  |         parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = 0; | ||||||
|  |       } else { | ||||||
|  |         parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = (dst_type.get_scale() % 10);// second | ||||||
|  |       } | ||||||
|  |     } else if ((ObTimestampNanoType == dst_type.get_type() || | ||||||
|  |                 ObTimestampTZType == dst_type.get_type() || | ||||||
|  |                 ObTimestampLTZType == dst_type.get_type()) && | ||||||
|  |                dst_type.get_scale() == -1) { | ||||||
|  |       // scale=-1 is invalid, update to default value | ||||||
|  |       ObCompatibilityMode compatibility_mode = get_compatibility_mode(); | ||||||
|  |       parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = dst_type.get_precision(); | ||||||
|  |       parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = | ||||||
|  |             ObAccuracy::DDL_DEFAULT_ACCURACY2[compatibility_mode] | ||||||
|  |                                              [dst_type.get_type()] | ||||||
|  |                                                  .get_scale(); | ||||||
|  |     } else { | ||||||
|  |       parse_node.int16_values_[OB_NODE_CAST_N_PREC_IDX] = dst_type.get_precision(); | ||||||
|  |       parse_node.int16_values_[OB_NODE_CAST_N_SCALE_IDX] = dst_type.get_scale(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     val.set_int(parse_node.value_); | ||||||
|  |     dst_expr->set_value(val); | ||||||
|  |     dst_expr->set_param(val); | ||||||
|  |     type_expr = dst_expr; | ||||||
|  |   } | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
| int ObRawExprUtils::build_add_expr(ObRawExprFactory &expr_factory, | int ObRawExprUtils::build_add_expr(ObRawExprFactory &expr_factory, | ||||||
|                                    ObRawExpr *param_expr1, |                                    ObRawExpr *param_expr1, | ||||||
|                                    ObRawExpr *param_expr2, |                                    ObRawExpr *param_expr2, | ||||||
|  | |||||||
| @ -1059,6 +1059,11 @@ public: | |||||||
|                                   ObColumnRefRawExpr *&spk_expr); |                                   ObColumnRefRawExpr *&spk_expr); | ||||||
|   static int check_contain_case_when_exprs(const ObRawExpr *raw_expr, bool &contain); |   static int check_contain_case_when_exprs(const ObRawExpr *raw_expr, bool &contain); | ||||||
|  |  | ||||||
|  |   static int create_type_expr(ObRawExprFactory &expr_factory, | ||||||
|  |                               ObConstRawExpr *&type_expr, | ||||||
|  |                               const ObExprResType &dst_type, | ||||||
|  |                               bool avoid_zero_len = false); | ||||||
|  |  | ||||||
| private : | private : | ||||||
|  |  | ||||||
|   static int create_real_cast_expr(ObRawExprFactory &expr_factory, |   static int create_real_cast_expr(ObRawExprFactory &expr_factory, | ||||||
|  | |||||||
| @ -1064,6 +1064,26 @@ int ObTransformDBlink::get_from_item_idx(ObDMLStmt *stmt, | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int ObTransformDBlink::check_can_pushdown(ObDMLStmt *stmt, const LinkTableHelper &helper, bool &can_push) | ||||||
|  | { | ||||||
|  |   int ret = OB_SUCCESS; | ||||||
|  |   bool is_on_null_side = false; | ||||||
|  |   JoinedTable *joined_table = helper.parent_table_; | ||||||
|  |   TableItem *table = NULL; | ||||||
|  |   if (NULL != joined_table) { | ||||||
|  |     if (OB_UNLIKELY(1 != helper.table_items_.count()) || | ||||||
|  |         OB_ISNULL(table = helper.table_items_.at(0)) || | ||||||
|  |         OB_UNLIKELY(table != joined_table->left_table_ && table != joined_table->right_table_)) { | ||||||
|  |       ret = OB_ERR_UNEXPECTED; | ||||||
|  |       LOG_WARN("unexpected push down tables", K(ret)); | ||||||
|  |     } else if (OB_FAIL(ObOptimizerUtil::is_table_on_null_side(stmt, table->table_id_, is_on_null_side))) { | ||||||
|  |       LOG_WARN("failed to check table on null side", K(ret)); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   can_push = !is_on_null_side; | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
| int ObTransformDBlink::collect_pushdown_conditions(ObDMLStmt *stmt, ObIArray<LinkTableHelper> &helpers) | int ObTransformDBlink::collect_pushdown_conditions(ObDMLStmt *stmt, ObIArray<LinkTableHelper> &helpers) | ||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
| @ -1074,27 +1094,33 @@ int ObTransformDBlink::collect_pushdown_conditions(ObDMLStmt *stmt, ObIArray<Lin | |||||||
|   } |   } | ||||||
|   for (int64_t i = 0; OB_SUCC(ret) && i < helpers.count(); ++i) { |   for (int64_t i = 0; OB_SUCC(ret) && i < helpers.count(); ++i) { | ||||||
|     table_ids.reuse(); |     table_ids.reuse(); | ||||||
|     if (OB_FAIL(ObTransformUtils::get_rel_ids_from_tables(stmt, |     bool can_push = false; | ||||||
|                                                           helpers.at(i).table_items_, |     if (OB_FAIL(check_can_pushdown(stmt, helpers.at(i), can_push))) { | ||||||
|                                                           table_ids))) { |       LOG_WARN("failed to check if conditions can be push", K(ret)); | ||||||
|  |     } else if (!can_push) { | ||||||
|  |       // do nothing | ||||||
|  |     } else if (OB_FAIL(ObTransformUtils::get_rel_ids_from_tables(stmt, | ||||||
|  |                                                                  helpers.at(i).table_items_, | ||||||
|  |                                                                  table_ids))) { | ||||||
|       LOG_WARN("failed to get rel ids", K(ret)); |       LOG_WARN("failed to get rel ids", K(ret)); | ||||||
|     } |     } else { | ||||||
|     bool has_special_expr = false; |       bool has_special_expr = false; | ||||||
|     for (int64_t j = 0; OB_SUCC(ret) && j < stmt->get_condition_size(); ++j) { |       for (int64_t j = 0; OB_SUCC(ret) && j < stmt->get_condition_size(); ++j) { | ||||||
|       ObRawExpr *expr = stmt->get_condition_expr(j); |         ObRawExpr *expr = stmt->get_condition_expr(j); | ||||||
|       if (OB_ISNULL(expr)) { |         if (OB_ISNULL(expr)) { | ||||||
|         ret = OB_ERR_UNEXPECTED; |           ret = OB_ERR_UNEXPECTED; | ||||||
|         LOG_WARN("unexpect null expr", K(ret)); |           LOG_WARN("unexpect null expr", K(ret)); | ||||||
|       } else if (!expr->get_relation_ids().is_subset(table_ids)) { |         } else if (!expr->get_relation_ids().is_subset(table_ids)) { | ||||||
|         //do nothing |           //do nothing | ||||||
|       }  else if (OB_FAIL(has_none_pushdown_expr(expr, |         } else if (OB_FAIL(has_none_pushdown_expr(expr, | ||||||
|                                                  helpers.at(i).dblink_id_, |                                                   helpers.at(i).dblink_id_, | ||||||
|                                                  has_special_expr))) { |                                                   has_special_expr))) { | ||||||
|         LOG_WARN("failed to check has none push down expr", K(ret)); |           LOG_WARN("failed to check has none push down expr", K(ret)); | ||||||
|       } else if (has_special_expr) { |         } else if (has_special_expr) { | ||||||
|         //do nothing |           //do nothing | ||||||
|       } else if (OB_FAIL(helpers.at(i).conditions_.push_back(expr))) { |         } else if (OB_FAIL(helpers.at(i).conditions_.push_back(expr))) { | ||||||
|         LOG_WARN("failed to push back expr", K(ret)); |           LOG_WARN("failed to push back expr", K(ret)); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -131,6 +131,8 @@ private: | |||||||
|  |  | ||||||
|   int get_from_item_idx(ObDMLStmt *stmt, ObRawExpr *expr, ObIArray<int64_t> &idxs); |   int get_from_item_idx(ObDMLStmt *stmt, ObRawExpr *expr, ObIArray<int64_t> &idxs); | ||||||
|  |  | ||||||
|  |   int check_can_pushdown(ObDMLStmt *stmt, const LinkTableHelper &helper, bool &can_push); | ||||||
|  |  | ||||||
|   int collect_pushdown_conditions(ObDMLStmt *stmt, ObIArray<LinkTableHelper> &helpers); |   int collect_pushdown_conditions(ObDMLStmt *stmt, ObIArray<LinkTableHelper> &helpers); | ||||||
|  |  | ||||||
|   int has_none_pushdown_expr(ObIArray<ObRawExpr*> &exprs, |   int has_none_pushdown_expr(ObIArray<ObRawExpr*> &exprs, | ||||||
|  | |||||||
| @ -431,6 +431,16 @@ int ObTransformerImpl::choose_rewrite_rules(ObDMLStmt *stmt, uint64_t &need_type | |||||||
|     } |     } | ||||||
|     if (func.contain_link_table_) { |     if (func.contain_link_table_) { | ||||||
|       disable_list |= (~ObTransformRule::ALL_HEURISTICS_RULES); |       disable_list |= (~ObTransformRule::ALL_HEURISTICS_RULES); | ||||||
|  |  | ||||||
|  |       // Below rules might generate filter which contains constant values which has implicit types, | ||||||
|  |       // which can not be printed in the link sql. | ||||||
|  |       // example: | ||||||
|  |       // create table t (c1 varchar(10), c2 char(10)) | ||||||
|  |       // select * from t where c1 = 'a' and c2 = c1; | ||||||
|  |       // => select * from t where c1 = 'a' and c2 = implicit cast('a' as varchar); | ||||||
|  |       ObTransformRule::add_trans_type(disable_list, PREDICATE_MOVE_AROUND); | ||||||
|  |       ObTransformRule::add_trans_type(disable_list, CONST_PROPAGATE); | ||||||
|  |       ObTransformRule::add_trans_type(disable_list, SIMPLIFY_EXPR); | ||||||
|     } |     } | ||||||
|     need_types = ObTransformRule::ALL_TRANSFORM_RULES & (~disable_list); |     need_types = ObTransformRule::ALL_TRANSFORM_RULES & (~disable_list); | ||||||
|   } |   } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 xianyu-w
					xianyu-w