fix core caused by missing const flag
This commit is contained in:
		| @ -263,3 +263,59 @@ int ObStmtExecParamFormatter::do_formalize_exec_param(ObRawExpr *&expr, bool &is | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObStmtExprChecker::do_visit(ObRawExpr *&expr) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   if (OB_FAIL(check_expr(expr))) { | ||||
|     LOG_WARN("failed to check expr", K(ret), KPC(expr)); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObStmtExprChecker::check_expr(const ObRawExpr *expr) const | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   if (OB_ISNULL(expr)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("expr is null", K(ret)); | ||||
|   } else if (OB_FAIL(check_const_flag(expr))) { | ||||
|     LOG_WARN("failed to check const flag", K(ret)); | ||||
|   } | ||||
|   for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { | ||||
|     if (OB_FAIL(SMART_CALL(check_expr(expr->get_param_expr(i))))) { | ||||
|       LOG_WARN("failed to check param expr", K(ret)); | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObStmtExprChecker::check_const_flag(const ObRawExpr *expr) const | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   bool expect_is_const = true; | ||||
|   if (OB_ISNULL(expr)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("expr is null", K(ret), K(expr)); | ||||
|   } | ||||
|   for (int64_t i = 0; OB_SUCC(ret) && expect_is_const && i < expr->get_param_count(); ++i) { | ||||
|     const ObRawExpr *param_expr = expr->get_param_expr(i); | ||||
|     if (OB_ISNULL(param_expr)) { | ||||
|       ret = OB_ERR_UNEXPECTED; | ||||
|       LOG_WARN("param expr is null", K(ret), K(param_expr)); | ||||
|     } else { | ||||
|       expect_is_const = param_expr->is_const_expr(); | ||||
|     } | ||||
|   } | ||||
|   if (OB_SUCC(ret) && expect_is_const) { | ||||
|     if (OB_FAIL(expr->is_const_inherit_expr(expect_is_const))) { | ||||
|       LOG_WARN("failed to check expr is const inherit", K(ret)); | ||||
|     } | ||||
|   } | ||||
|   if (OB_FAIL(ret)) { | ||||
|   } else if (OB_UNLIKELY(expr->is_const_expr() != expect_is_const)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("expr const flag is not match", K(ret), K(expect_is_const), KPC(expr)); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| @ -236,6 +236,15 @@ public: | ||||
|  | ||||
| }; | ||||
|  | ||||
| class ObStmtExprChecker : public ObStmtExprVisitor | ||||
| { | ||||
| public: | ||||
|   ObStmtExprChecker() {} | ||||
|   virtual int do_visit(ObRawExpr *&expr) override; | ||||
|   int check_expr(const ObRawExpr *expr) const; | ||||
|   int check_const_flag(const ObRawExpr *expr) const; | ||||
| }; | ||||
|  | ||||
| } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -789,6 +789,17 @@ int ObRawExpr::is_const_inherit_expr(bool &is_const_inherit, | ||||
|       || T_FUN_NORMAL_UDF == type_ | ||||
|       || T_FUN_SYS_REMOVE_CONST == type_ | ||||
|       || T_FUN_SYS_WRAPPER_INNER == type_ | ||||
|       || T_FUN_SYS_VALUES == type_ | ||||
|       || T_OP_GET_PACKAGE_VAR == type_ | ||||
|       || T_OP_GET_SUBPROGRAM_VAR == type_ | ||||
|       || T_FUN_SYS_JSON_VALUE == type_ | ||||
|       || T_FUN_SYS_JSON_QUERY == type_ | ||||
|       || (T_FUN_SYS_JSON_EXISTS == type_ && lib::is_oracle_mode()) | ||||
|       || T_FUN_SYS_JSON_EQUAL == type_ | ||||
|       || T_FUN_SYS_IS_JSON == type_ | ||||
|       || (T_FUN_SYS_JSON_MERGE_PATCH == type_ && lib::is_oracle_mode()) | ||||
|       || T_FUN_SYS_JSON_OBJECT == type_ | ||||
|       || IS_LABEL_SE_POLICY_FUNC(type_) | ||||
|       || (T_FUN_SYS_LAST_INSERT_ID == type_ && get_param_count() > 0) | ||||
|       || T_FUN_SYS_TO_BLOB == type_ | ||||
|       || (T_FUN_SYS_SYSDATE == type_ && lib::is_mysql_mode()) | ||||
|  | ||||
| @ -567,32 +567,6 @@ int ObRawExprInfoExtractor::visit(ObSysFunRawExpr &expr) | ||||
|         } | ||||
|       } else {} | ||||
|     } | ||||
|  | ||||
|     if (OB_SUCC(ret) | ||||
|         && (T_FUN_SYS_JSON_VALUE == expr.get_expr_type() | ||||
|            || T_FUN_SYS_JSON_QUERY == expr.get_expr_type() | ||||
|            || (T_FUN_SYS_JSON_EXISTS == expr.get_expr_type() && lib::is_oracle_mode()) | ||||
|            || T_FUN_SYS_JSON_EQUAL == expr.get_expr_type() | ||||
|            || T_FUN_SYS_IS_JSON == expr.get_expr_type() | ||||
|            || (T_FUN_SYS_JSON_MERGE_PATCH == expr.get_expr_type() && lib::is_oracle_mode()) | ||||
|            || T_FUN_SYS_JSON_OBJECT == expr.get_expr_type() | ||||
|            || IS_LABEL_SE_POLICY_FUNC(expr.get_expr_type())) | ||||
|         && OB_FAIL(expr.clear_flag(IS_CONST_EXPR))) { | ||||
|       LOG_WARN("failed to clear flag", K(ret)); | ||||
|     } | ||||
|  | ||||
|     if (OB_SUCC(ret) && T_FUN_SYS_JSON_VALUE == expr.get_expr_type()) { | ||||
|       if (expr.get_param_count() >= 12) { | ||||
|         ObRawExpr * sub_expr = expr.get_param_expr(7); | ||||
|         if (OB_NOT_NULL(sub_expr) | ||||
|             && OB_FAIL(sub_expr->clear_flag(IS_CONST_EXPR))) { | ||||
|           LOG_WARN("failed to clear flag", K(ret)); | ||||
|         } else if (OB_NOT_NULL(sub_expr = expr.get_param_expr(4)) | ||||
|                    && OB_FAIL(sub_expr->clear_flag(IS_CONST_EXPR))) { | ||||
|           LOG_WARN("failed to clear flag", K(ret)); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| @ -598,6 +598,10 @@ int ObTransformOrExpansion::try_do_transform_left_join(ObIArray<ObParentDMLStmt> | ||||
|     if (OB_FAIL(ret)) { | ||||
|     } else if (!trans_happened && OB_FAIL(try_trans_helper1.recover(stmt->get_query_ctx()))) { | ||||
|       LOG_WARN("failed to recover params", K(ret)); | ||||
|     } else if (!trans_happened && OB_FAIL(remove_temp_table_select_item(ref_query, | ||||
|                                                                   not_null_side_table->table_id_, | ||||
|                                                                   right_flag_pos))) { | ||||
|       LOG_WARN("failed to remove temp table select item", K(ret)); | ||||
|     } else { | ||||
|       ctx_->src_hash_val_.pop_back(); | ||||
|     } | ||||
| @ -726,7 +730,7 @@ int ObTransformOrExpansion::add_select_item_to_ref_query(ObSelectStmt *stmt, | ||||
|   ObSEArray<ObRawExpr*, 4> right_flag_exprs; | ||||
|   ObSEArray<ObRawExpr*, 4> select_exprs; | ||||
|   if (OB_ISNULL(stmt) || OB_ISNULL(ctx_) || OB_ISNULL(ctx_->expr_factory_) | ||||
|       || OB_ISNULL(ctx_->allocator_)) { | ||||
|       || OB_ISNULL(ctx_->allocator_) || OB_ISNULL(ctx_->session_info_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("unexpect null", K(ret), K(stmt), K(ctx_)); | ||||
|   } else if (OB_UNLIKELY(1 != stmt->get_from_item_size()) || | ||||
| @ -758,6 +762,8 @@ int ObTransformOrExpansion::add_select_item_to_ref_query(ObSelectStmt *stmt, | ||||
|     } else if (OB_FAIL(ObRawExprUtils::build_const_number_expr(*ctx_->expr_factory_, ObNumberType, | ||||
|                                               number::ObNumber::get_positive_one(), const_expr))) { | ||||
|       LOG_WARN("failed to build const expr", K(ret)); | ||||
|     } else if (OB_FAIL(const_expr->formalize(ctx_->session_info_))) { | ||||
|       LOG_WARN("failed to formalize const number expr", K(ret)); | ||||
|     } else if (OB_FAIL(select_list.push_back(const_expr))) { | ||||
|       LOG_WARN("failed to push back expr", K(ret)); | ||||
|     } else if (OB_FAIL(ObTransformUtils::create_columns_for_view(ctx_, *flag_table, stmt, | ||||
| @ -818,6 +824,33 @@ int ObTransformOrExpansion::add_select_item_to_ref_query(ObSelectStmt *stmt, | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObTransformOrExpansion::remove_temp_table_select_item(ObSelectStmt *stmt, | ||||
|                                                           const uint64_t flag_table_id, | ||||
|                                                           ObSqlBitSet<> &right_flag_pos) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   TableItem *flag_table = NULL; | ||||
|   ObSelectStmt *view_stmt = NULL; | ||||
|   if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("unexpect null", K(ret), K(stmt)); | ||||
|   } else if (OB_ISNULL(flag_table = stmt->get_table_item_by_id(flag_table_id))) { | ||||
|     LOG_WARN("faield to get table item", K(ret), K(flag_table), K(flag_table_id)); | ||||
|   } else if (!flag_table->is_temp_table()) { | ||||
|     // do nothing | ||||
|   } else if (OB_UNLIKELY(right_flag_pos.num_members() != 1)) { | ||||
|     ret= OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("unexpected right flag pos count", K(ret), K(right_flag_pos)); | ||||
|   } else if (OB_ISNULL(view_stmt = flag_table->ref_query_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("view_stmt is null", K(ret), K(view_stmt)); | ||||
|   } else if (ObTransformUtils::remove_select_items(ctx_, flag_table_id, *view_stmt, | ||||
|                                                    *stmt, right_flag_pos)) { | ||||
|     LOG_WARN("failed to remove select items", K(ret)); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| // do transform after get a union stmt: | ||||
| // 1. add win func level | ||||
| // 2. add filter level | ||||
|  | ||||
| @ -169,6 +169,9 @@ private: | ||||
|                                    StmtUniqueKeyProvider &unique_key_provider, | ||||
|                                    ObSqlBitSet<> &left_unique_pos, | ||||
|                                    ObSqlBitSet<> &right_flag_pos); | ||||
|   int remove_temp_table_select_item(ObSelectStmt *stmt, | ||||
|                                     const uint64_t flag_table_id, | ||||
|                                     ObSqlBitSet<> &right_flag_pos); | ||||
|  | ||||
|   int create_row_number_window_function(ObIArray<ObRawExpr *> &partition_exprs, | ||||
|                                         ObIArray<ObRawExpr *> &order_exprs, | ||||
|  | ||||
| @ -159,6 +159,8 @@ int ObTransformerImpl::do_after_transform(ObDMLStmt *stmt) | ||||
|     LOG_WARN("failed to add pre calc constraints", K(ret)); | ||||
|   } else if (OB_FAIL(adjust_global_dependency_tables(stmt))) { | ||||
|     LOG_WARN("failed to adjust global depency", K(ret)); | ||||
|   } else if (OB_FAIL(verify_all_stmt_exprs(stmt))) { | ||||
|     LOG_WARN("failed to verify all stmt exprs", K(ret)); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
| @ -649,6 +651,44 @@ int ObTransformerImpl::adjust_global_dependency_tables(ObDMLStmt *stmt) | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObTransformerImpl::verify_all_stmt_exprs(ObDMLStmt *stmt) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   if (OB_ISNULL(stmt)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("stmt is NULL", K(ret)); | ||||
|   } else if (OB_FAIL(verify_stmt_exprs(stmt))) { | ||||
|     LOG_WARN("failed to verify stmt exprs", K(ret)); | ||||
|   } else { | ||||
|     ObArray<ObDMLStmt::TempTableInfo> temp_table_infos; | ||||
|     if (OB_FAIL(stmt->collect_temp_table_infos(temp_table_infos))) { | ||||
|       LOG_WARN("failed to collect temp table infos", K(ret)); | ||||
|     } | ||||
|     for (int64_t i = 0; OB_SUCC(ret) && i < temp_table_infos.count(); ++i) { | ||||
|       if (OB_FAIL(verify_stmt_exprs(temp_table_infos.at(i).temp_table_query_))) { | ||||
|         LOG_WARN("failed to verify temp table query exprs", K(ret)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObTransformerImpl::verify_stmt_exprs(ObDMLStmt *stmt) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   if (OB_ISNULL(stmt)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("stmt is NULL", K(ret)); | ||||
|   } else { | ||||
|     ObStmtExprChecker checker; | ||||
|     checker.set_relation_scope(); | ||||
|     if (OB_FAIL(stmt->iterate_stmt_expr(checker))) { | ||||
|       LOG_WARN("failed to check stmt expr", K(ret), KPC(stmt)); | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObTransformerImpl::add_param_and_expr_constraints(ObExecContext &exec_ctx, | ||||
|                                                       ObTransformerCtx &trans_ctx, | ||||
|                                                       ObDMLStmt &stmt) | ||||
|  | ||||
| @ -158,6 +158,8 @@ private: | ||||
|    * 为pl收集依赖表的schema version信息 | ||||
|    */ | ||||
|   int adjust_global_dependency_tables(ObDMLStmt *stmt); | ||||
|   int verify_all_stmt_exprs(ObDMLStmt *stmt); | ||||
|   int verify_stmt_exprs(ObDMLStmt *stmt); | ||||
|  | ||||
|   template<typename T> | ||||
|   int transform_one_rule(ObDMLStmt *&stmt, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 yinyj17
					yinyj17