bugfix : json object resolve column expr cause core-dump
This commit is contained in:
		@ -4954,7 +4954,7 @@ int ObRawExprResolverImpl::malloc_new_specified_type_node(common::ObIAllocator &
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// use: json value (mismatch ype) ; json object (entry_op)
 | 
			
		||||
// use: json value (mismatch ype)
 | 
			
		||||
int ObRawExprResolverImpl::expand_node(common::ObIAllocator &allocator, ParseNode *node, int p, ObVector<const ParseNode*> &arr) {
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (node->type_ == T_LINK_NODE || node->type_ == T_VALUE_VECTOR)
 | 
			
		||||
@ -4962,149 +4962,11 @@ int ObRawExprResolverImpl::expand_node(common::ObIAllocator &allocator, ParseNod
 | 
			
		||||
    for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++){
 | 
			
		||||
      if (OB_ISNULL(node->children_[i])) {
 | 
			
		||||
      } else {
 | 
			
		||||
        ObString rownum_str(6, "rownum");
 | 
			
		||||
        if (lib::is_oracle_mode() && ctx_.current_scope_ == T_FIELD_LIST_SCOPE && node->children_[i]->type_ == T_FUN_SYS
 | 
			
		||||
            && node->children_[i]->num_child_ == 1 && OB_NOT_NULL(node->children_[i]->children_[0])
 | 
			
		||||
            && node->children_[i]->children_[0]->type_ == T_IDENT
 | 
			
		||||
            && 0 == rownum_str.case_compare(node->children_[i]->children_[0]->str_value_)
 | 
			
		||||
            && i % 3 == 0 && node->children_[i + 1]->type_ == T_NULL
 | 
			
		||||
            && node->children_[i + 1]->value_ == 2) {
 | 
			
		||||
          ParseNode *fun_key_node;
 | 
			
		||||
          if (OB_ISNULL(fun_key_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
 | 
			
		||||
            ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
            LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
 | 
			
		||||
          } else {
 | 
			
		||||
            fun_key_node = new(fun_key_node) ParseNode;
 | 
			
		||||
            if (OB_ISNULL(node->children_[i]->children_[0])) {
 | 
			
		||||
              ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
              LOG_WARN("no legeal fun", K(ret));
 | 
			
		||||
            } else {
 | 
			
		||||
              ObString str_fun(node->children_[i]->children_[0]->str_len_, node->children_[i]->children_[0]->str_value_);
 | 
			
		||||
              if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, str_fun, fun_key_node, T_CHAR))) {
 | 
			
		||||
                LOG_WARN("key node create fail", K(ret));
 | 
			
		||||
              } else {
 | 
			
		||||
                node->children_[i + 1] = node->children_[i];
 | 
			
		||||
                node->children_[i] = fun_key_node;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        } else if (node->children_[i]->type_ == T_OBJ_ACCESS_REF
 | 
			
		||||
                    && i % 3 == 0 && node->children_[i+1]->type_ == T_NULL && node->children_[i+1]->value_ == 2) {
 | 
			
		||||
          ParseNode *column_ref_node;
 | 
			
		||||
          ParseNode *t_node = node->children_[i];
 | 
			
		||||
          ParseNode *pre_node = NULL;
 | 
			
		||||
          bool is_fun_sys = false;
 | 
			
		||||
          if (OB_ISNULL(column_ref_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
 | 
			
		||||
            ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
            LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
 | 
			
		||||
          } else {
 | 
			
		||||
            column_ref_node = new(column_ref_node) ParseNode;
 | 
			
		||||
            if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", column_ref_node, T_OBJ_ACCESS_REF))) {
 | 
			
		||||
              LOG_WARN("key node create fail", K(ret));
 | 
			
		||||
            } else {
 | 
			
		||||
              node->children_[i]->value_ = 1;
 | 
			
		||||
              pre_node = column_ref_node;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          while (OB_SUCC(ret) && !is_fun_sys && t_node != NULL && t_node->type_ == T_OBJ_ACCESS_REF) {
 | 
			
		||||
            if (OB_ISNULL(t_node->children_[0]) || t_node->children_[0]->type_ != T_IDENT) {
 | 
			
		||||
              is_fun_sys = true;
 | 
			
		||||
            } else {
 | 
			
		||||
              ParseNode *col_ref_node = NULL;
 | 
			
		||||
              ParseNode *ident_node = NULL;
 | 
			
		||||
              if (OB_ISNULL(ident_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
 | 
			
		||||
                ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
                LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
 | 
			
		||||
              } else {
 | 
			
		||||
                ident_node = new(ident_node) ParseNode;
 | 
			
		||||
                memset(ident_node, 0, sizeof(ParseNode));
 | 
			
		||||
                ident_node->type_ = T_IDENT;
 | 
			
		||||
                ident_node->str_value_ = t_node->children_[0]->str_value_;
 | 
			
		||||
                ident_node->str_len_ = t_node->children_[0]->str_len_;
 | 
			
		||||
                ident_node->raw_text_ = t_node->children_[0]->raw_text_;
 | 
			
		||||
                ident_node->text_len_ = t_node->children_[0]->text_len_;
 | 
			
		||||
                pre_node->children_[0] = ident_node;
 | 
			
		||||
              }
 | 
			
		||||
              if (OB_FAIL(ret) || OB_ISNULL(t_node->children_[1])) {
 | 
			
		||||
              } else if (OB_ISNULL(col_ref_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
 | 
			
		||||
                ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
                LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
 | 
			
		||||
              } else {
 | 
			
		||||
                col_ref_node = new(col_ref_node) ParseNode;
 | 
			
		||||
                if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", col_ref_node, T_OBJ_ACCESS_REF))) {
 | 
			
		||||
                  LOG_WARN("key node create fail", K(ret));
 | 
			
		||||
                } else {
 | 
			
		||||
                  pre_node->children_[1] = col_ref_node;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
              if (OB_SUCC(ret)) {
 | 
			
		||||
                pre_node = col_ref_node;
 | 
			
		||||
              }
 | 
			
		||||
              t_node = t_node->children_[1];
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          if (OB_SUCC(ret) && !is_fun_sys && OB_ISNULL(node->children_[i+1] = column_ref_node)) {
 | 
			
		||||
            ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
            LOG_WARN("column_node copy failed", K(ret));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (OB_SUCC(ret) && OB_FAIL(SMART_CALL(expand_node(allocator, node->children_[i], i, arr)))) {
 | 
			
		||||
          LOG_WARN("node expand fail", K(ret));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if (node->type_ == T_STAR) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  } else if ((node->type_ == T_COLUMN_REF || node->type_ == T_OBJ_ACCESS_REF) && node->value_ == 1 && p % 3 == 0) {
 | 
			
		||||
    ObQualifiedName column_ref;
 | 
			
		||||
    ParseNode *col_node;
 | 
			
		||||
    if (nullptr == (col_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
 | 
			
		||||
      ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
      LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
 | 
			
		||||
    } else if (node->type_ == T_COLUMN_REF) {
 | 
			
		||||
      if (OB_FAIL(ObResolverUtils::resolve_column_ref(
 | 
			
		||||
                  node, ctx_.case_mode_, column_ref))) {
 | 
			
		||||
        LOG_WARN("fail to resolve column ref", K(ret));
 | 
			
		||||
      }
 | 
			
		||||
      if (OB_NOT_NULL(node->children_[2]->raw_text_)) {
 | 
			
		||||
        column_ref.col_name_ = node->children_[2]->raw_text_;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (node->type_ == T_OBJ_ACCESS_REF) {
 | 
			
		||||
      while (node->children_[1] != NULL) {
 | 
			
		||||
        node = node->children_[1];
 | 
			
		||||
      }
 | 
			
		||||
      if (OB_NOT_NULL(node->children_[0]) && node->children_[0]->type_ == T_IDENT) {
 | 
			
		||||
        if (OB_FAIL(ObResolverUtils::resolve_obj_access_ref_node(
 | 
			
		||||
                    ctx_.expr_factory_, node->children_[0], column_ref, *ctx_.session_info_))) {
 | 
			
		||||
          LOG_WARN("fail to resolve column ref", K(ret));
 | 
			
		||||
        }
 | 
			
		||||
        if (OB_NOT_NULL(node->children_[0]->raw_text_)) {
 | 
			
		||||
          column_ref.col_name_ = node->children_[0]->raw_text_;
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        column_ref.is_star_ = true;
 | 
			
		||||
        const ParseNode* new_node = node;
 | 
			
		||||
        if (OB_FAIL(arr.push_back(node))) {
 | 
			
		||||
          LOG_WARN("node resolver fail", K(ret));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    if (OB_SUCC(ret) && !column_ref.is_star_) {
 | 
			
		||||
      col_node = new(col_node) ParseNode;
 | 
			
		||||
      ObString col_name = column_ref.col_name_;
 | 
			
		||||
      if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, col_name, col_node, T_CHAR))) {
 | 
			
		||||
        LOG_WARN("fail to create column node ");
 | 
			
		||||
      }
 | 
			
		||||
      const ParseNode* new_node = col_node;
 | 
			
		||||
      if (OB_FAIL(arr.push_back(new_node))) {
 | 
			
		||||
        LOG_WARN("node resolver fail", K(ret));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if (node->type_ == T_COLUMN_REF && node->children_[2]->type_ == T_STAR) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  } else if (node->type_ == T_NULL && node->value_ == 2) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  } else {
 | 
			
		||||
    const ParseNode* new_node = node;
 | 
			
		||||
    if (OB_FAIL(arr.push_back(node))) {
 | 
			
		||||
@ -5162,9 +5024,38 @@ int ObRawExprResolverImpl::remove_strict_opt_in_pl(ParseNode *node, int8_t expr_
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObRawExprResolverImpl::get_column_raw_text_from_node(const ParseNode *node, ObString &col_name)
 | 
			
		||||
{
 | 
			
		||||
  INIT_SUCC(ret);
 | 
			
		||||
  ObQualifiedName column_ref;
 | 
			
		||||
  if (node->type_ == T_COLUMN_REF) {
 | 
			
		||||
    col_name = node->children_[2]->raw_text_;
 | 
			
		||||
  } else if (node->type_ == T_OBJ_ACCESS_REF) {
 | 
			
		||||
    while (OB_SUCC(ret) && node->children_[1] != NULL) {
 | 
			
		||||
      node = node->children_[1];
 | 
			
		||||
      if (node->type_ != T_OBJ_ACCESS_REF) {
 | 
			
		||||
        ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
        LOG_WARN("fail to get column name from node", K(ret));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (OB_SUCC(ret) && OB_NOT_NULL(node->children_[0]) && node->children_[0]->type_ == T_IDENT) {
 | 
			
		||||
        col_name = node->children_[0]->raw_text_;
 | 
			
		||||
    } else {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("fail to get column name from node", K(ret));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, ObRawExpr *&expr)
 | 
			
		||||
{
 | 
			
		||||
  INIT_SUCC(ret);
 | 
			
		||||
  ObVector<const ParseNode*> key_value_arr;
 | 
			
		||||
  ParseNode* data_node = NULL;
 | 
			
		||||
  ParseNode* cur_node_kv = NULL;
 | 
			
		||||
  int cur_col_size = 0;
 | 
			
		||||
  ParseNode key_node;
 | 
			
		||||
  CK(OB_NOT_NULL(node));
 | 
			
		||||
  int32_t num = 0;
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
@ -5208,7 +5099,6 @@ int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, O
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ObVector<const ParseNode*> key_value_arr;
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
    const ParseNode *key_value = node->children_[0];
 | 
			
		||||
    if (OB_ISNULL(key_value)) {
 | 
			
		||||
@ -5226,30 +5116,76 @@ int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, O
 | 
			
		||||
          LOG_WARN("illegal use of 'strcit' clause.");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      ParseNode *cur_node = NULL;
 | 
			
		||||
      if (OB_FAIL(ret) || OB_ISNULL(key_value)) {
 | 
			
		||||
      } else if (OB_NOT_NULL(node->children_[0]) && (node->children_[0]->num_child_ == 0 || (node->children_[0]->num_child_ > 0 && OB_ISNULL(cur_node = node->children_[0]->children_[0])))) {
 | 
			
		||||
      } else if (cur_node->type_ == T_COLUMN_REF && OB_NOT_NULL(cur_node->children_[2]) && cur_node->children_[2]->type_ == T_STAR) {
 | 
			
		||||
      } else if (OB_FAIL(expand_node(ctx_.local_allocator_, const_cast<ParseNode *>(key_value), 0, key_value_arr))) {
 | 
			
		||||
        LOG_WARN("expand node has error", K(ret), K(key_value_arr.size()));
 | 
			
		||||
      } else if (key_value_arr.size() != key_value->num_child_) {
 | 
			
		||||
        ret = OB_ERR_MISS_VALUE;
 | 
			
		||||
        LOG_WARN("missing value keyword", K(ret), K(key_value_arr.size()), K(key_value->num_child_));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (OB_SUCC(ret)) {
 | 
			
		||||
        // [key-value(vector)][null_type][returning_type][strict][unique_keys]
 | 
			
		||||
        for (int32_t i = 0; OB_SUCC(ret) && i < key_value_arr.size(); i++) {
 | 
			
		||||
          if (key_value_arr[i]->type_ == T_LINK_NODE || key_value_arr[i]->type_ == T_VALUE_VECTOR) {
 | 
			
		||||
          } else {
 | 
			
		||||
        // [key-value(vector)]
 | 
			
		||||
        if (OB_NOT_NULL(node->children_[0])) {
 | 
			
		||||
          data_node = node->children_[0];
 | 
			
		||||
          for (int64_t i = 0; OB_SUCC(ret) && i < data_node->num_child_; i++) {  // 3 node in group
 | 
			
		||||
            ObRawExpr *para_expr = NULL;
 | 
			
		||||
            CK(OB_NOT_NULL(key_value_arr[i]));
 | 
			
		||||
            OZ(SMART_CALL(recursive_resolve(key_value_arr[i], para_expr)));
 | 
			
		||||
            CK(OB_NOT_NULL(para_expr));
 | 
			
		||||
            OZ(func_expr->add_param_expr(para_expr));
 | 
			
		||||
            cur_node_kv = NULL;
 | 
			
		||||
            int val_pos = i + 1; //  key is i where i % 3 == 0 , value is i + 1, format json is i + 2
 | 
			
		||||
            if (OB_ISNULL(data_node->children_[i])) {
 | 
			
		||||
            } else if ((i % 3 == 1) && data_node->children_[i]->type_ == T_NULL && data_node->children_[i]->value_ == 2) {  // 2 is flag of empty value
 | 
			
		||||
              cur_node_kv = data_node->children_[i - 1];
 | 
			
		||||
            } else {
 | 
			
		||||
              cur_node_kv = data_node->children_[i];
 | 
			
		||||
            }
 | 
			
		||||
            if (OB_FAIL(ret) || OB_ISNULL(cur_node_kv)) {
 | 
			
		||||
            } else if (OB_FAIL(SMART_CALL(recursive_resolve(cur_node_kv, para_expr)))) {
 | 
			
		||||
              LOG_WARN("fail to get raw expr from node", K(ret), K(i));
 | 
			
		||||
            } else if (OB_ISNULL(para_expr)) {
 | 
			
		||||
              ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
              LOG_WARN("raw expr is null", K(ret), K(i));
 | 
			
		||||
            } else if ((i % JSON_OBJECT_GROUP == ObJsonObjectEntry::JSON_OBJECT_KEY) && data_node->children_[val_pos]->type_ == T_NULL
 | 
			
		||||
                        && data_node->children_[val_pos]->value_ == 2  // 2 is flag of empty value
 | 
			
		||||
                        && !(((para_expr->get_expr_type() == T_COLUMN_REF  // column type
 | 
			
		||||
                              || para_expr->get_expr_type() == T_REF_COLUMN)
 | 
			
		||||
                            && ctx_.columns_->at(ctx_.columns_->count()-1).access_idents_.at(0).get_type() == oceanbase::sql::UNKNOWN)
 | 
			
		||||
                        || para_expr->get_expr_type() == T_FUN_SYS_ROWNUM)) {  // rownum
 | 
			
		||||
              ret = OB_ERR_MISS_VALUE;
 | 
			
		||||
              LOG_WARN("missing value keyword", K(ret), K(para_expr->get_expr_type()), K(i));
 | 
			
		||||
            } else if ((i % JSON_OBJECT_GROUP == ObJsonObjectEntry::JSON_OBJECT_KEY)  && data_node->children_[val_pos]->type_ == T_NULL
 | 
			
		||||
                                     && data_node->children_[val_pos]->value_ == 2   // 2 is flag of empty value
 | 
			
		||||
                                     && (((para_expr->get_expr_type() == T_COLUMN_REF   // column type
 | 
			
		||||
                                          || para_expr->get_expr_type() == T_REF_COLUMN)
 | 
			
		||||
                                        && ctx_.columns_->at(ctx_.columns_->count() - 1).access_idents_.at(0).get_type() == oceanbase::sql::UNKNOWN)
 | 
			
		||||
                                      || para_expr->get_expr_type() == T_FUN_SYS_ROWNUM)) {  // rownum
 | 
			
		||||
              ObString col_name;
 | 
			
		||||
              if (para_expr->get_expr_type() == T_FUN_SYS_ROWNUM) {
 | 
			
		||||
                col_name.assign_ptr("rownum", 6);
 | 
			
		||||
              } else if (ctx_.columns_->count() > cur_col_size && OB_SUCC(get_column_raw_text_from_node(cur_node_kv, col_name))) {
 | 
			
		||||
                for (int col_pos = cur_col_size; col_pos < ctx_.columns_->count(); col_pos ++) {
 | 
			
		||||
                  ctx_.columns_->pop_back();  // delete column para
 | 
			
		||||
                }
 | 
			
		||||
              } else {
 | 
			
		||||
                ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
                LOG_WARN("fail to resolve column", K(ret), K(cur_col_size), K(ctx_.columns_->count()));
 | 
			
		||||
              }
 | 
			
		||||
              para_expr = NULL;
 | 
			
		||||
              if (OB_FAIL(ret)) {
 | 
			
		||||
              } else if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(ctx_.local_allocator_, col_name, &key_node, T_CHAR))) {
 | 
			
		||||
                LOG_WARN("create json doc node fail", K(ret));
 | 
			
		||||
              } else if (OB_FAIL(SMART_CALL(recursive_resolve(&key_node, para_expr)))) {
 | 
			
		||||
                LOG_WARN("fail to get raw expr from node", K(ret), K(i));
 | 
			
		||||
              } else if (OB_ISNULL(para_expr)) {
 | 
			
		||||
                ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
                LOG_WARN("raw expr is null", K(ret), K(i));
 | 
			
		||||
              } else if (OB_FAIL(func_expr->add_param_expr(para_expr))) {
 | 
			
		||||
                ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
                LOG_WARN("fail to add into func expr", K(ret), K(i));
 | 
			
		||||
              } else {
 | 
			
		||||
                cur_col_size = ctx_.columns_->count();
 | 
			
		||||
              }
 | 
			
		||||
            } else if (OB_FAIL(func_expr->add_param_expr(para_expr))) {
 | 
			
		||||
              ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
              LOG_WARN("fail to add into func expr", K(ret), K(i));
 | 
			
		||||
            } else {
 | 
			
		||||
              cur_col_size = ctx_.columns_->count();
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        } //end for
 | 
			
		||||
        // ([on_mismatch][opt_mismatch_types] on oracle)
 | 
			
		||||
        }
 | 
			
		||||
        // [null_type][returning_type][strict][unique_keys]
 | 
			
		||||
        for (int32_t i = 1; OB_SUCC(ret) && i < num; i++) {
 | 
			
		||||
          ObRawExpr *para_expr = NULL;
 | 
			
		||||
          CK(OB_NOT_NULL(node->children_[i]));
 | 
			
		||||
 | 
			
		||||
@ -104,10 +104,17 @@ private:
 | 
			
		||||
    OPT_JSON_OBJECT,
 | 
			
		||||
    OPT_JSON_ARRAY,
 | 
			
		||||
  };
 | 
			
		||||
  enum ObJsonObjectEntry: int8_t {
 | 
			
		||||
    JSON_OBJECT_KEY = 0,
 | 
			
		||||
    JSON_OBJECT_VAL = 1,
 | 
			
		||||
    JSON_OBJECT_FORMAT = 2
 | 
			
		||||
  };
 | 
			
		||||
  const int JSON_OBJECT_GROUP = 3;
 | 
			
		||||
  int remove_strict_opt_in_pl(ParseNode *node, int8_t expr_flag);
 | 
			
		||||
  int remove_format_json_opt_in_pl(ParseNode *node, int8_t expr_flag);
 | 
			
		||||
  int process_json_value_node(const ParseNode *node, ObRawExpr *&expr);
 | 
			
		||||
  int pre_check_json_path_valid(const ParseNode *node);
 | 
			
		||||
  int get_column_raw_text_from_node(const ParseNode *node, ObString &col_name);
 | 
			
		||||
  int process_ora_json_object_node(const ParseNode *node, ObRawExpr *&expr);
 | 
			
		||||
  int process_is_json_node(const ParseNode *node, ObRawExpr *&expr);
 | 
			
		||||
  int process_json_equal_node(const ParseNode *node, ObRawExpr *&expr);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user