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

@ -472,6 +472,37 @@ int ObRawExpr::set_enum_set_values(const common::ObIArray<common::ObString>& val
return ret;
}
bool ObRawExpr::is_non_pure_sys_func_expr() const
{
if (lib::is_oracle_mode()) {
if (T_FUN_SYS_LOCALTIMESTAMP == type_ || T_FUN_SYS_SESSIONTIMEZONE == type_ || T_FUN_SYS_DBTIMEZONE == type_ ||
T_FUN_SYS_SYSDATE == type_ || T_FUN_SYS_SYSTIMESTAMP == type_ || T_FUN_SYS_UID == type_ ||
T_FUN_SYS_USER == type_ || T_FUN_SYS_CUR_TIMESTAMP == type_ || T_FUN_SYS_GUID == type_ ||
T_FUN_SYS_CUR_DATE == type_ || T_FUN_SYS_USERENV == type_ || T_FUN_SYS_REGEXP_REPLACE == type_) {
return true;
}
} else {
if (T_FUN_SYS_CONNECTION_ID == type_ || T_FUN_SYS_VERSION == type_ || T_FUN_SYS_CURRENT_USER == type_ ||
T_FUN_SYS_USER == type_ || T_FUN_SYS_DATABASE == type_ || T_FUN_SYS_SYSDATE == type_ ||
T_FUN_SYS_CUR_DATE == type_ || T_FUN_SYS_CUR_TIME == type_ || T_FUN_SYS_CUR_TIMESTAMP == type_ ||
T_FUN_SYS_UNIX_TIMESTAMP == type_ || T_FUN_SYS_UTC_TIMESTAMP == type_ || T_FUN_SYS_RAND == type_ ||
T_FUN_SYS_UUID == type_ || T_FUN_SYS_SLEEP == type_ || T_FUN_SYS_LAST_INSERT_ID == type_ ||
T_FUN_SYS_ROW_COUNT == type_ || T_FUN_SYS_FOUND_ROWS == type_ || T_FUN_SYS_REGEXP_INSTR == type_ ||
T_FUN_SYS_REGEXP_LIKE == type_ || T_FUN_SYS_REGEXP_REPLACE == type_ || T_FUN_SYS_REGEXP_SUBSTR == type_) {
return true;
}
}
return false;
}
bool ObRawExpr::is_specified_pseudocolumn_expr() const
{
if (T_FUN_SYS_ROWNUM == type_ || T_LEVEL == type_ || T_CONNECT_BY_ISCYCLE == type_ || T_CONNECT_BY_ISLEAF == type_) {
return true;
}
return false;
}
////////////////////////////////////////////////////////////////
int ObConstRawExpr::assign(const ObConstRawExpr& other)
{

View File

@ -1351,6 +1351,8 @@ public:
{
return T_FUN_PL_ASSOCIATIVE_INDEX == get_expr_type();
}
bool is_non_pure_sys_func_expr() const;
bool is_specified_pseudocolumn_expr() const;
void set_alias_column_name(const common::ObString& alias_name)
{
alias_column_name_ = alias_name;

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) {

View File

@ -174,19 +174,27 @@ public:
const common::ObString& expr_str, common::ObIAllocator& allocator, const ParseNode*& node);
static int build_check_constraint_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info,
const ParseNode& node, ObRawExpr*& expr, common::ObIArray<ObQualifiedName>& columns);
static int check_deterministic(const ObRawExpr* expr, common::ObIAllocator& allocator,
const ObResolverUtils::PureFunctionCheckStatus check_status = ObResolverUtils::DISABLE_CHECK);
static int check_deterministic_single(const ObRawExpr* expr,
const ObResolverUtils::PureFunctionCheckStatus check_status = ObResolverUtils::DISABLE_CHECK);
static int build_generated_column_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info,
const ParseNode& node, ObRawExpr*& expr, common::ObIArray<ObQualifiedName>& columns,
const ObSchemaChecker* schema_checker = NULL);
const ObSchemaChecker* schema_checker = NULL,
const ObResolverUtils::PureFunctionCheckStatus check_status = ObResolverUtils::DISABLE_CHECK);
static int build_generated_column_expr(const common::ObString& expr_str, ObRawExprFactory& expr_factory,
const ObSQLSessionInfo& session_info, ObRawExpr*& expr, common::ObIArray<ObQualifiedName>& columns,
const ObSchemaChecker* schema_checker = NULL);
const ObSchemaChecker* schema_checker = NULL,
const ObResolverUtils::PureFunctionCheckStatus check_status = ObResolverUtils::DISABLE_CHECK);
static int build_generated_column_expr(const common::ObString& expr_str, ObRawExprFactory& expr_factory,
const ObSQLSessionInfo& session_info, const share::schema::ObTableSchema& table_schema, ObRawExpr*& expr,
const ObSchemaChecker* schema_checker = NULL);
const ObSchemaChecker* schema_checker = NULL,
const ObResolverUtils::PureFunctionCheckStatus check_status = ObResolverUtils::DISABLE_CHECK);
static int build_generated_column_expr(const common::ObString& expr_str, ObRawExprFactory& expr_factory,
const ObSQLSessionInfo& session_info, uint64_t table_id, const share::schema::ObTableSchema& table_schema,
const share::schema::ObColumnSchemaV2& gen_col_schema, ObRawExpr*& expr,
const ObSchemaChecker* schema_checker = NULL);
const ObSchemaChecker* schema_checker = NULL,
const ObResolverUtils::PureFunctionCheckStatus check_status = ObResolverUtils::DISABLE_CHECK);
static int build_raw_expr(ObRawExprFactory& expr_factory, const ObSQLSessionInfo& session_info, const ParseNode& node,
ObRawExpr*& expr, common::ObIArray<ObQualifiedName>& columns, common::ObIArray<ObVarInfo>& sys_vars,
common::ObIArray<ObAggFunRawExpr*>& aggr_exprs, common::ObIArray<ObWinFunRawExpr*>& win_exprs,