cherry-pick from 3_1_x_release to 3.1_opensource_release

This commit is contained in:
obdev
2021-07-19 21:27:14 +08:00
committed by wangzelin.wzl
parent 850ef4e4c3
commit 1777c9769e
14 changed files with 315 additions and 98 deletions

View File

@ -1014,7 +1014,7 @@ int ObRawExprUtils::parse_bool_expr_node_from_str(
int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawExprFactory& expr_factory,
const ObSQLSessionInfo& session_info, ObRawExpr*& expr, ObIArray<ObQualifiedName>& columns,
const ObSchemaChecker* schema_checker)
const ObSchemaChecker* schema_checker, const ObResolverUtils::PureFunctionCheckStatus check_status)
{
int ret = OB_SUCCESS;
const ParseNode* node = NULL;
@ -1023,15 +1023,73 @@ int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawE
} else if (OB_ISNULL(node)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("node is null");
} else if (OB_FAIL(build_generated_column_expr(expr_factory, session_info, *node, expr, columns, schema_checker))) {
} else if (OB_FAIL(build_generated_column_expr(
expr_factory, session_info, *node, expr, columns, schema_checker, check_status))) {
LOG_WARN("build generated column expr failed", K(ret));
}
return ret;
}
int ObRawExprUtils::check_deterministic(
const ObRawExpr* expr, ObIAllocator& allocator, const ObResolverUtils::PureFunctionCheckStatus check_status)
{
int ret = OB_SUCCESS;
CK(OB_NOT_NULL(expr));
CK(expr->get_children_count() >= 0);
ObList<const ObRawExpr*, ObIAllocator> expr_queue(allocator);
OZ(expr_queue.push_back(expr));
const ObRawExpr* cur_expr = NULL;
while (OB_SUCC(ret) && expr_queue.size() > 0) {
OZ(expr_queue.pop_front(cur_expr));
CK(OB_NOT_NULL(cur_expr));
OZ(check_deterministic_single(cur_expr, check_status));
for (int i = 0; OB_SUCC(ret) && i < cur_expr->get_param_count(); ++i) {
OZ(expr_queue.push_back(cur_expr->get_param_expr(i)));
}
}
return ret;
}
int ObRawExprUtils::check_deterministic_single(
const ObRawExpr* expr, const ObResolverUtils::PureFunctionCheckStatus check_status)
{
int ret = OB_SUCCESS;
CK(OB_NOT_NULL(expr));
if (OB_SUCC(ret) && ObResolverUtils::DISABLE_CHECK != check_status) {
if (expr->is_sys_func_expr()) {
if (expr->is_non_pure_sys_func_expr()) {
if (ObResolverUtils::CHECK_FOR_GENERATED_COLUMN == check_status) {
ret = OB_ERR_ONLY_PURE_FUNC_CANBE_VIRTUAL_COLUMN_EXPRESSION;
} else if (ObResolverUtils::CHECK_FOR_FUNCTION_INDEX == check_status) {
ret = OB_ERR_ONLY_PURE_FUNC_CANBE_INDEXED;
}
LOG_WARN("only pure sys function can be indexed", K(ret), K(check_status), K(*expr));
} else if (T_FUN_SYS_ROWNUM == expr->get_expr_type()) {
ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED;
LOG_WARN("ROWNUM is not allowed", K(ret), K(*expr));
}
} else if (expr->is_pseudo_column_expr()) {
if (expr->is_specified_pseudocolumn_expr()) {
ret = OB_ERR_CBY_PSEUDO_COLUMN_NOT_ALLOWED;
LOG_WARN("not allowed pesudo column", K(ret), K(*expr));
}
} else if (expr->is_udf_expr()) {
if (lib::is_mysql_mode()) {
ret = OB_ERR_ONLY_PURE_FUNC_CANBE_VIRTUAL_COLUMN_EXPRESSION;
LOG_WARN("user-defined functions are not allowd in generated column", K(ret), K(*expr));
} else {
ret = OB_NOT_SUPPORTED;
LOG_WARN("user-defined function is not supported", K(ret), K(*expr));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "The user-defined function");
}
}
}
return ret;
}
int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawExprFactory& expr_factory,
const ObSQLSessionInfo& session_info, const ObTableSchema& table_schema, ObRawExpr*& expr,
const ObSchemaChecker* schema_checker)
const ObSchemaChecker* schema_checker, const ObResolverUtils::PureFunctionCheckStatus check_status)
{
int ret = OB_SUCCESS;
const ParseNode* node = NULL;
@ -1042,9 +1100,11 @@ int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawE
} else if (OB_ISNULL(node)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("node is null");
} else if (OB_FAIL(build_generated_column_expr(expr_factory, session_info, *node, expr, columns, schema_checker))) {
} else if (OB_FAIL(build_generated_column_expr(
expr_factory, session_info, *node, expr, columns, schema_checker, check_status))) {
LOG_WARN("build generated column expr failed", K(ret), K(expr_str));
}
for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); i++) {
const ObQualifiedName& q_name = columns.at(i);
if (OB_UNLIKELY(!q_name.database_name_.empty())) {
@ -1121,7 +1181,8 @@ int ObRawExprUtils::build_check_constraint_expr(ObRawExprFactory& expr_factory,
}
int ObRawExprUtils::build_generated_column_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info,
const ParseNode& node, ObRawExpr*& expr, ObIArray<ObQualifiedName>& columns, const ObSchemaChecker* schema_checker)
const ParseNode& node, ObRawExpr*& expr, ObIArray<ObQualifiedName>& columns, const ObSchemaChecker* schema_checker,
const ObResolverUtils::PureFunctionCheckStatus check_status)
{
int ret = OB_SUCCESS;
ObArray<ObVarInfo> sys_vars;
@ -1188,6 +1249,10 @@ int ObRawExprUtils::build_generated_column_expr(ObRawExprFactory& expr_factory,
OZ(columns.assign(real_columns), real_columns);
}
}
// check whether the expression is deterministic recursively
if (OB_SUCC(ret) && ObResolverUtils::DISABLE_CHECK != check_status) {
OZ(check_deterministic(expr, expr_factory.get_allocator(), check_status));
}
return ret;
}
@ -1259,12 +1324,14 @@ int ObRawExprUtils::build_raw_expr(ObRawExprFactory& expr_factory, const ObSQLSe
int ObRawExprUtils::build_generated_column_expr(const ObString& expr_str, ObRawExprFactory& expr_factory,
const ObSQLSessionInfo& session_info, uint64_t table_id, const ObTableSchema& table_schema,
const ObColumnSchemaV2& gen_col_schema, ObRawExpr*& expr, const ObSchemaChecker* schema_checker)
const ObColumnSchemaV2& gen_col_schema, ObRawExpr*& expr, const ObSchemaChecker* schema_checker,
const ObResolverUtils::PureFunctionCheckStatus check_status)
{
int ret = OB_SUCCESS;
ObArray<ObQualifiedName> columns;
const ObColumnSchemaV2* col_schema = NULL;
if (OB_FAIL(build_generated_column_expr(expr_str, expr_factory, session_info, expr, columns, schema_checker))) {
if (OB_FAIL(build_generated_column_expr(
expr_str, expr_factory, session_info, expr, columns, schema_checker, check_status))) {
LOG_WARN("build generated column expr failed", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); ++i) {