[FEAT MERGE] OB Support XMLType
Co-authored-by: simonjoylet <simonjoylet@gmail.com>
This commit is contained in:
		| @ -711,7 +711,8 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr | ||||
|       case T_FUN_JSON_ARRAYAGG: | ||||
|       case T_FUN_JSON_OBJECTAGG: | ||||
|       case T_FUN_ORA_JSON_ARRAYAGG: | ||||
|       case T_FUN_ORA_JSON_OBJECTAGG: { | ||||
|       case T_FUN_ORA_JSON_OBJECTAGG: | ||||
|       case T_FUN_ORA_XMLAGG: { | ||||
|  | ||||
|         if (OB_FAIL(process_agg_node(node, expr))) { | ||||
|           LOG_WARN("fail to process agg node", K(ret), K(node)); | ||||
| @ -1088,6 +1089,30 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr | ||||
|         OZ (process_geo_func_node(node, expr)); | ||||
|         break; | ||||
|       } | ||||
|       case T_FUN_SYS_XML_ELEMENT: { | ||||
|         if (OB_FAIL(process_xml_element_node(node, expr))) { | ||||
|           LOG_WARN("failed to process xmlelement node", K(ret)); | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case T_FUN_SYS_XMLPARSE: { | ||||
|         if (OB_FAIL(process_xmlparse_node(node, expr))) { | ||||
|           LOG_WARN("fail to process xmlparse node", K(ret), K(node)); | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case T_FUN_SYS_XML_ATTRIBUTES: { | ||||
|         if (OB_FAIL(process_xml_attributes_node(node, expr))) { | ||||
|           LOG_WARN("fail to process xmlattributes node", K(ret), K(node)); | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       case T_FUN_SYS_XML_ATTRIBUTES_VALUES: { | ||||
|         if (OB_FAIL(process_xml_attributes_values_node(node, expr))) { | ||||
|           LOG_WARN("fail to process xmlattributes node", K(ret), K(node)); | ||||
|         } | ||||
|         break; | ||||
|       } | ||||
|       default: | ||||
|         ret = OB_ERR_PARSER_SYNTAX; | ||||
|         LOG_WARN("Wrong type in expression", K(get_type_name(node->type_))); | ||||
| @ -1156,6 +1181,177 @@ int ObRawExprResolverImpl::process_ident_node(const ParseNode &node, ObRawExpr * | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRawExprResolverImpl::process_xml_element_node(const ParseNode *node, ObRawExpr *&expr) | ||||
| { | ||||
|   INIT_SUCC(ret); | ||||
|   CK(OB_NOT_NULL(node)); | ||||
|   if(OB_SUCC(ret) && T_FUN_SYS_XML_ELEMENT != node->type_) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("node->type_ error", K(node->type_)); | ||||
|   } else if (OB_SUCC(ret) && (1 > node->num_child_ || 4 < node->num_child_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("num_child_ error", K(node->num_child_)); | ||||
|   } | ||||
|   ObSysFunRawExpr *func_expr = NULL; | ||||
|   if (OB_SUCC(ret)) { | ||||
|     if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr))) { | ||||
|       LOG_WARN("create raw expr failed", K(node->num_child_), K(ret)); | ||||
|     } else if (OB_ISNULL(func_expr)) { | ||||
|       ret = OB_ERR_UNEXPECTED; | ||||
|       LOG_WARN("func expr is null", K(node->num_child_)); | ||||
|     } else { | ||||
|       func_expr->set_func_name(ObString::make_string("xmlelement")); | ||||
|     } | ||||
|   } | ||||
|   for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { | ||||
|     const ParseNode *expr_node = node->children_[i]; | ||||
|     CK (OB_NOT_NULL(expr_node)); | ||||
|     if (expr_node->num_child_ > 1 && T_FUN_SYS_XML_ATTRIBUTES != expr_node->type_) { | ||||
|       for (int j = 0; OB_SUCC(ret) && j < expr_node->num_child_; j++) { | ||||
|         ObRawExpr *para_expr = NULL; | ||||
|         CK(OB_NOT_NULL(expr_node->children_[j])); | ||||
|         OZ(recursive_resolve(expr_node->children_[j], para_expr)); | ||||
|         CK(OB_NOT_NULL(para_expr)); | ||||
|         OZ(func_expr->add_param_expr(para_expr)); | ||||
|       } | ||||
|     } else { | ||||
|       ObRawExpr *para_expr = NULL; | ||||
|       OZ(recursive_resolve(expr_node, para_expr)); | ||||
|       CK(OB_NOT_NULL(para_expr)); | ||||
|       OZ(func_expr->add_param_expr(para_expr)); | ||||
|     } | ||||
|   } | ||||
|   OX(expr = func_expr); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRawExprResolverImpl::process_xml_attributes_values_node(const ParseNode *node, ObRawExpr *&expr) | ||||
| { | ||||
|   INIT_SUCC(ret); | ||||
|   int cur_col_size = ctx_.columns_->count(); | ||||
|   ParseNode key_node; | ||||
|   CK(OB_NOT_NULL(node)); | ||||
|   if(OB_SUCC(ret) && T_FUN_SYS_XML_ATTRIBUTES_VALUES != node->type_) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("node->type_ error", K(node->type_)); | ||||
|   } else if (OB_SUCC(ret) && (2 != node->num_child_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("num_child_ error", K(node->num_child_)); | ||||
|   } | ||||
|   ObSysFunRawExpr *func_expr = NULL; | ||||
|   if (OB_FAIL(ret)) { | ||||
|     LOG_WARN("ret failed", K(ret)); | ||||
|   } else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_XML_ATTRIBUTES_VALUES, func_expr))) { | ||||
|     LOG_WARN("create raw expr failed", K(node->num_child_), K(ret)); | ||||
|   } else if (OB_ISNULL(func_expr)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("func expr is null", K(node->num_child_)); | ||||
|   } else if (OB_FALSE_IT(func_expr->set_func_name(ObString::make_string("xmlattributes_values")))) { | ||||
|   } else { | ||||
|     const ParseNode *expr_value_node = node->children_[0]; | ||||
|     CK (OB_NOT_NULL(expr_value_node)); | ||||
|     ObRawExpr *para_expr = NULL; | ||||
|     OZ(recursive_resolve(expr_value_node, para_expr)); | ||||
|     CK(OB_NOT_NULL(para_expr)); | ||||
|     OZ(func_expr->add_param_expr(para_expr)); | ||||
|     if (OB_FAIL(ret)) { | ||||
|       LOG_WARN("ret failed", K(ret)); | ||||
|     } else if (OB_ISNULL(node->children_[1])) { | ||||
|       ObRawExpr *para_key_expr = NULL; | ||||
|       ObString col_name; | ||||
|       para_expr = NULL; | ||||
|       if (OB_FAIL(get_column_raw_text_from_node(expr_value_node, col_name))) { | ||||
|         LOG_WARN("get column raw text failed", K(ret)); | ||||
|       } else if (!col_name.empty() && OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(ctx_.local_allocator_, | ||||
|                                                                                 ObString(col_name.length(), easy_string_toupper(col_name.ptr())), | ||||
|                                                                                 &key_node, T_CHAR))) { | ||||
|         LOG_WARN("create key node failed", K(ret)); | ||||
|       } else { | ||||
|         OZ(recursive_resolve(&key_node, para_expr)); | ||||
|         CK(OB_NOT_NULL(para_expr)); | ||||
|         OZ(func_expr->add_param_expr(para_expr)); | ||||
|       } | ||||
|     } else { | ||||
|       const ParseNode *expr_key_node = node->children_[1]; | ||||
|       CK (OB_NOT_NULL(expr_key_node)); | ||||
|       ObRawExpr *para_expr = NULL; | ||||
|       OZ(recursive_resolve(expr_key_node, para_expr)); | ||||
|       CK(OB_NOT_NULL(para_expr)); | ||||
|       OZ(func_expr->add_param_expr(para_expr)); | ||||
|     } | ||||
|   } | ||||
|   OX(expr = func_expr); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRawExprResolverImpl::process_xml_attributes_node(const ParseNode *node, ObRawExpr *&expr) { | ||||
|   INIT_SUCC(ret); | ||||
|   CK(OB_NOT_NULL(node)); | ||||
|   if(OB_SUCC(ret) && T_FUN_SYS_XML_ATTRIBUTES != node->type_) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("node->type_ error", K(node->type_)); | ||||
|   } else if (OB_SUCC(ret) && (3 != node->num_child_)) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("num_child_ error", K(node->num_child_)); | ||||
|   } | ||||
|   ObSysFunRawExpr *func_expr = NULL; | ||||
|   if (OB_SUCC(ret)) { | ||||
|     if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr))) { | ||||
|       LOG_WARN("create raw expr failed", K(node->num_child_), K(ret)); | ||||
|     } else if (OB_ISNULL(func_expr)) { | ||||
|       ret = OB_ERR_UNEXPECTED; | ||||
|       LOG_WARN("func expr is null", K(node->num_child_)); | ||||
|     } else { | ||||
|       func_expr->set_func_name(ObString::make_string("xmlattributes")); | ||||
|     } | ||||
|   } | ||||
|   for (int32_t i = 0; OB_SUCC(ret) && i < 2; i++) { | ||||
|     const ParseNode *expr_node = node->children_[i]; | ||||
|     CK (OB_NOT_NULL(expr_node)); | ||||
|     ObRawExpr *para_expr = NULL; | ||||
|     OZ(recursive_resolve(expr_node, para_expr)); | ||||
|     CK(OB_NOT_NULL(para_expr)); | ||||
|     OZ(func_expr->add_param_expr(para_expr)); | ||||
|   } | ||||
|   ParseNode *node_ptr = node->children_[2]; | ||||
|   if (OB_ISNULL(node_ptr)) { | ||||
|     ret = OB_ERR_PARAM_INVALID; | ||||
|     LOG_WARN("node children_[2] invalid", K(ret)); | ||||
|   } else if (2 != node_ptr->num_child_) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("num child invalid", K(ret), K(node_ptr->num_child_)); | ||||
|   } else { | ||||
|     do { | ||||
|       ObRawExpr *para_expr = NULL; | ||||
|       if (T_LINK_NODE != node_ptr->type_) { | ||||
|         const ParseNode *expr_node = node_ptr; | ||||
|         CK (OB_NOT_NULL(expr_node)); | ||||
|         OZ(recursive_resolve(expr_node, para_expr)); | ||||
|         CK(OB_NOT_NULL(para_expr)); | ||||
|         for (int i = 0; OB_SUCC(ret) && i < para_expr->get_param_count(); i++) { | ||||
|           OZ(func_expr->add_param_expr(para_expr->get_param_expr(i))); | ||||
|         } | ||||
|         break; | ||||
|       } else if (T_LINK_NODE == node_ptr->type_ && | ||||
|                   node_ptr->children_[0]->num_child_ == 2) { | ||||
|         const ParseNode *expr_node = node_ptr->children_[0]; | ||||
|         CK (OB_NOT_NULL(expr_node)); | ||||
|         OZ(recursive_resolve(expr_node, para_expr)); | ||||
|         CK(OB_NOT_NULL(para_expr)); | ||||
|         node_ptr = node_ptr->children_[1]; | ||||
|         for (int i = 0; OB_SUCC(ret) && i < para_expr->get_param_count(); i++) { | ||||
|           OZ(func_expr->add_param_expr(para_expr->get_param_expr(i))); | ||||
|         } | ||||
|       } else { | ||||
|         ret = OB_ERR_UNEXPECTED; | ||||
|         LOG_WARN("resolver attributes failed", K(ret), K(node_ptr->num_child_), K(node_ptr->children_[0]->num_child_)); | ||||
|       } | ||||
|     } while (OB_SUCC(ret)); | ||||
|   } | ||||
|   OX(expr = func_expr); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRawExprResolverImpl::process_cursor_attr_node(const ParseNode &node, ObRawExpr *&expr) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
| @ -1285,7 +1481,7 @@ int ObRawExprResolverImpl::process_obj_access_node(const ParseNode &node, ObRawE | ||||
|   if (OB_ISNULL(ctx_.columns_)) { | ||||
|     ret = OB_INVALID_ARGUMENT; | ||||
|     LOG_WARN("invalid argument", K_(ctx_.columns)); | ||||
|   } else if (IS_AGGR_FUN(node.children_[0]->type_)) { | ||||
|   } else if (IS_AGGR_FUN(node.children_[0]->type_) && node.children_[0]->type_ != T_FUN_ORA_XMLAGG) { | ||||
|     //in oracle ,we could not define standalone or package function with the same name as agg function | ||||
|     if (IS_KEEP_AGGR_FUN(node.children_[0]->type_)) { | ||||
|       if (OB_FAIL(process_keep_aggr_node(node.children_[0], expr))) { | ||||
| @ -1294,6 +1490,13 @@ int ObRawExprResolverImpl::process_obj_access_node(const ParseNode &node, ObRawE | ||||
|     } else if (OB_FAIL(process_agg_node(node.children_[0], expr))) { | ||||
|       LOG_WARN("process agg node failed", K(ret)); | ||||
|     } | ||||
|   } else if (node.children_[0]->type_ == T_FUN_ORA_XMLAGG | ||||
|              && (node.num_child_ == 1 | ||||
|                  || ((node.num_child_ == 2) && OB_ISNULL(node.children_[1])))) { | ||||
|     // xmlagg without any xmltype member functions | ||||
|     if (OB_FAIL(process_agg_node(node.children_[0], expr))) { | ||||
|       LOG_WARN("process xmlagg node failed", K(ret)); | ||||
|     } | ||||
|   } else { | ||||
|     ObQualifiedName column_ref; | ||||
|     int64_t child_start = ctx_.columns_->count(); | ||||
| @ -1558,7 +1761,8 @@ int ObRawExprResolverImpl::check_sys_func(ObQualifiedName &q_name, bool &is_sys_ | ||||
|   int ret = OB_SUCCESS; | ||||
|   is_sys_func = 1 == q_name.access_idents_.count() | ||||
|       && (IS_FUN_SYS_TYPE(ObExprOperatorFactory::get_type_by_name(q_name.access_idents_.at(0).access_name_)) | ||||
|           || 0 == q_name.access_idents_.at(0).access_name_.case_compare("sqlerrm")) | ||||
|           || 0 == q_name.access_idents_.at(0).access_name_.case_compare("sqlerrm") | ||||
|           || 0 == q_name.access_idents_.at(0).access_name_.case_compare("xmlagg")) | ||||
|       && q_name.access_idents_.at(0).access_name_.case_compare("nextval") != 0 | ||||
|       && q_name.access_idents_.at(0).access_name_.case_compare("currval") != 0; | ||||
|  | ||||
| @ -1682,6 +1886,16 @@ int ObRawExprResolverImpl::resolve_func_node_of_obj_access_idents(const ParseNod | ||||
|     if (ident_name.empty() && T_PL_SCOPE == ctx_.current_scope_ && lib::is_oracle_mode()) { | ||||
|       ret = OB_ERR_IDENT_EMPTY; | ||||
|       LOG_WARN("Identifier cannot be an empty string", K(ret), K(ident_name)); | ||||
|     } else if (ident_name.empty()) { | ||||
|       if (func_node.type_ == T_FUN_SYS_MAKEXML) { | ||||
|         ident_name = ObString::make_string("sys_makexml"); | ||||
|       } else if (func_node.type_ == T_FUN_SYS_XML_ELEMENT) { | ||||
|         ident_name = ObString::make_string("xmlelement"); | ||||
|       } else if (func_node.type_ == T_FUN_SYS_XMLPARSE) { | ||||
|         ident_name = ObString::make_string("xmlparse"); | ||||
|       } else if (func_node.type_ == T_FUN_ORA_XMLAGG) { | ||||
|         ident_name = ObString::make_string("xmlagg"); | ||||
|       } | ||||
|     } | ||||
|     OZ (q_name.access_idents_.push_back(ObObjAccessIdent(ident_name, OB_INVALID_INDEX)), K(ident_name)); | ||||
|  | ||||
| @ -1729,7 +1943,13 @@ int ObRawExprResolverImpl::resolve_func_node_of_obj_access_idents(const ParseNod | ||||
|           } else if (0 == q_name.access_idents_.at(0).access_name_.case_compare("json_equal")) { | ||||
|             ret = OB_ERR_JSON_EQUAL_OUTSIDE_PREDICATE; | ||||
|             LOG_WARN("JSON_EQUAL used outside predicate", K(ret)); | ||||
|           } else { | ||||
|           } else if (func_node.type_ == T_FUN_SYS_XMLPARSE) { | ||||
|             OZ (process_xmlparse_node(&func_node, func_expr)); | ||||
|           } else if (func_node.type_ == T_FUN_SYS_XML_ELEMENT) { | ||||
|             OZ (process_xml_element_node(&func_node, func_expr)); | ||||
|           } else if (func_node.type_ == T_FUN_ORA_XMLAGG) { | ||||
|             OZ (process_agg_node(&func_node, func_expr)); | ||||
|           }else { | ||||
|             OZ (process_fun_sys_node(&func_node, func_expr)); | ||||
|           } | ||||
|           CK (OB_NOT_NULL(func_expr)); | ||||
| @ -1855,7 +2075,10 @@ int ObRawExprResolverImpl::resolve_left_node_of_obj_access_idents(const ParseNod | ||||
|         LOG_USER_ERROR(OB_ERR_CALL_WRONG_ARG, ident_name.length(), ident_name.ptr()); | ||||
|       } | ||||
|     } | ||||
|   } else if (T_FUN_SYS == left_node.type_) { | ||||
|   } else if (T_FUN_SYS == left_node.type_ | ||||
|              || T_FUN_SYS_XML_ELEMENT == left_node.type_ | ||||
|              || T_FUN_SYS_XMLPARSE == left_node.type_ | ||||
|              || T_FUN_ORA_XMLAGG == left_node.type_) { | ||||
|     OZ (resolve_func_node_of_obj_access_idents(left_node, q_name)); | ||||
|   } else { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
| @ -3584,7 +3807,7 @@ int ObRawExprResolverImpl::process_agg_node(const ParseNode *node, ObRawExpr *&e | ||||
|   } else if (OB_FAIL(ctx_.aggr_exprs_->push_back(agg_expr))) { | ||||
|     LOG_WARN("store aggr expr failed", K(ret)); | ||||
|   } else if (OB_UNLIKELY(1 > node->num_child_) || OB_ISNULL(node->children_) | ||||
|       || (2 == node->num_child_ && OB_ISNULL(node->children_[1])) | ||||
|       || (2 == node->num_child_ && OB_ISNULL(node->children_[1]) && node->type_ != T_FUN_ORA_XMLAGG) | ||||
|       || (T_FUN_COUNT == node->type_ && (OB_ISNULL(node->children_[0])))) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("invalid node children", K(node->num_child_)); | ||||
| @ -3827,6 +4050,47 @@ int ObRawExprResolverImpl::process_agg_node(const ParseNode *node, ObRawExpr *&e | ||||
|           LOG_WARN("fail to add param expr to agg expr", K(ret)); | ||||
|         } | ||||
|       } // end for | ||||
|     } else if (T_FUN_ORA_XMLAGG == node->type_) { | ||||
|       sub_expr = NULL; | ||||
|       for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; ++i) { | ||||
|         if (OB_ISNULL(node->children_[i])) { | ||||
|           // do nothing | ||||
|         } else if (i == 0) { | ||||
|           // TODO Subsequent Interception Aggregation Function | ||||
|           if (OB_FAIL(SMART_CALL(recursive_resolve(node->children_[i], sub_expr)))) { | ||||
|             LOG_WARN("fail to resursive resolve expr list item", K(ret)); | ||||
|           } else if (OB_FAIL(agg_expr->add_real_param_expr(sub_expr))) { | ||||
|             LOG_WARN("fail to add param expr to agg expr", K(ret)); | ||||
|           } | ||||
|         } else if (i == 1) { | ||||
|           const ParseNode *sort_list = NULL; | ||||
|           if (OB_UNLIKELY(node->children_[1]->type_ != T_ORDER_BY) | ||||
|               || OB_UNLIKELY(node->children_[1]->num_child_ != 2) | ||||
|               || OB_ISNULL(node->children_[1]->children_) | ||||
|               || OB_ISNULL(sort_list = node->children_[1]->children_[0])) { | ||||
|             ret = OB_ERR_UNEXPECTED; | ||||
|             LOG_WARN("invalid parameter", K(node->children_[1])); | ||||
|           } else if (NULL != node->children_[1]->children_[1]) { | ||||
|             ret = OB_ERR_CBY_OREDER_SIBLINGS_BY_NOT_ALLOWED; | ||||
|             LOG_WARN("should not be here, invalid agg node"); | ||||
|           } else { | ||||
|             for (int32_t i = 0; OB_SUCC(ret) && i < sort_list->num_child_; i++) { | ||||
|               ParseNode *sort_node = sort_list->children_[i]; | ||||
|               OrderItem order_item; | ||||
|               if (OB_FAIL(SMART_CALL(recursive_resolve(sort_node->children_[0], sub_expr)))) { | ||||
|                 LOG_WARN("fail to recursive_resolve expr list item", K(ret)); | ||||
|               } else if (OB_FAIL(ObResolverUtils::set_direction_by_mode(*sort_node, order_item))) { | ||||
|                 LOG_WARN("failed to set direction by mode", K(ret)); | ||||
|               } else { | ||||
|                 order_item.expr_ = sub_expr; | ||||
|                 if (OB_FAIL(agg_expr->add_order_item(order_item))) { | ||||
|                   LOG_WARN("Add order expression error", K(ret)); | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } else if (T_FUN_COUNT != node->type_ | ||||
|         || (T_FUN_COUNT == node->type_ && 2 == node->num_child_ && T_ALL == node->children_[0]->type_) | ||||
|         || T_FUN_GROUPING == node->type_) { | ||||
| @ -4249,6 +4513,53 @@ int ObRawExprResolverImpl::reset_keep_aggr_sort_direction(ObIArray<OrderItem> &a | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRawExprResolverImpl::process_xmlparse_node(const ParseNode *node, ObRawExpr *&expr) | ||||
| { | ||||
|   INIT_SUCC(ret); | ||||
|   // check type and num_child | ||||
|   CK(OB_NOT_NULL(node)); | ||||
|   if (OB_SUCC(ret) && T_FUN_SYS_XMLPARSE != node->type_) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("node->type_ error"); | ||||
|   } else if (OB_SUCC(ret) && node->num_child_ != 4) { | ||||
|     ret = OB_ERR_UNEXPECTED; | ||||
|     LOG_WARN("num_child_ error"); | ||||
|   } | ||||
|   // declare func_expr | ||||
|   int32_t child_num = 0; | ||||
|   ObSysFunRawExpr *func_expr = NULL; | ||||
|   if (OB_SUCC(ret)) { | ||||
|     child_num = node->num_child_; | ||||
|     ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr); | ||||
|     CK(OB_NOT_NULL(func_expr)); | ||||
|     OX(func_expr->set_func_name(ObString::make_string("xmlparse"))); | ||||
|   } | ||||
|  | ||||
|   // add param | ||||
|   for (int32_t i = 0; OB_SUCC(ret) && i < child_num; i++) { | ||||
|     ObRawExpr *para_expr = NULL; | ||||
|     CK(OB_NOT_NULL(node->children_[i])); | ||||
|     OZ(SMART_CALL(recursive_resolve(node->children_[i], para_expr))); | ||||
|     CK(OB_NOT_NULL(para_expr)); | ||||
|     if (i == 3) { | ||||
|       int flag = node->reserved_; | ||||
|       if (OB_NOT_NULL(ctx_.stmt_) && ctx_.stmt_->is_select_stmt()){ | ||||
|         flag |= 0x08; | ||||
|       } | ||||
|       ObConstRawExpr *const_expr = static_cast<ObConstRawExpr *>(para_expr); | ||||
|       ObObj val; | ||||
|       val.set_int(flag); | ||||
|       const_expr->set_value(val); | ||||
|       const_expr->set_param(val); | ||||
|     } | ||||
|  | ||||
|     //para_expr->clear_flag(IS_CALCULABLE_EXPR); | ||||
|     OZ(func_expr->add_param_expr(para_expr)); | ||||
|   } | ||||
|   OX(expr = func_expr); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRawExprResolverImpl::process_oracle_timestamp_node(const ParseNode *node, | ||||
|                                                          ObRawExpr *&expr, | ||||
|                                                          int16_t min_precision, | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 obdev
					obdev