[FEAT MERGE] OB Support XMLType

Co-authored-by: simonjoylet <simonjoylet@gmail.com>
This commit is contained in:
obdev
2023-04-28 03:45:10 +00:00
committed by ob-robot
parent 58bb3d34b7
commit 17abf2818a
405 changed files with 18839 additions and 1573 deletions

View File

@ -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,