Exemplo n.º 1
0
int ObObj::apply(const ObObj &mutation)
{
  int err = OB_SUCCESS;
  int org_type = get_type();
  int org_ext = get_ext();
  int mut_type = mutation.get_type();
  ObCreateTime create_time = 0;
  ObModifyTime modify_time = 0;
  bool is_add = false;
  bool org_is_add = false;
  if (ObSeqType == mut_type
      || ObMinType >= mut_type
      || ObMaxType <= mut_type)
  {
    TBSYS_LOG(WARN,"unsupported type [type:%d]", mut_type);
    err = OB_INVALID_ARGUMENT;
  }
  if (OB_SUCCESS == err
      && ObExtendType != org_type
      && ObNullType != org_type
      && ObExtendType != mut_type
      && ObNullType != mut_type
      && org_type != mut_type)
  {
    TBSYS_LOG(WARN,"type not coincident [this->type:%d,mutation.type:%d]",
        org_type, mut_type);
    err = OB_INVALID_ARGUMENT;
  }
  _ObjValue value, mutation_value;
  if (OB_SUCCESS == err)
  {
    bool ext_val_can_change =  (ObActionFlag::OP_ROW_DOES_NOT_EXIST == org_ext)  ||  (ObNullType == org_type);
    bool org_is_nop = (ObActionFlag::OP_NOP == org_ext);
    switch (mut_type)
    {
      case ObNullType:
        set_null();
        break;
      case ObVarcharType:
        *this = mutation;
        break;
      case ObBoolType:
        *this = mutation;
        break;
      case ObIntType:
        if (ext_val_can_change || org_is_nop)
        {
          set_int(0);
        }
        err = get_int(value.int_val,org_is_add);
        if (OB_SUCCESS == err)
        {
          err = mutation.get_int(mutation_value.int_val,is_add);
        }
        if (OB_SUCCESS == err)
        {
          if (is_add)
          {
            value.int_val += mutation_value.int_val; // @bug value overflow
          }
          else
          {
            value.int_val = mutation_value.int_val;
          }
          set_int(value.int_val, (org_is_add || org_is_nop) && is_add);
        }
        break;
      case ObFloatType:
        if (ext_val_can_change || org_is_nop)
        {
          set_float(0);
        }
        err = get_float(value.float_val,org_is_add);
        if (OB_SUCCESS == err)
        {
          err = mutation.get_float(mutation_value.float_val, is_add);
        }
        if (OB_SUCCESS == err)
        {
          if (is_add)
          {
            value.float_val += mutation_value.float_val;
          }
          else
          {
            value.float_val = mutation_value.float_val;
          }
          set_float(value.float_val,is_add && (org_is_add || org_is_nop));
        }
        break;
      case ObDoubleType:
        if (ext_val_can_change || org_is_nop)
        {
          set_double(0);
        }
        err = get_double(value.double_val,org_is_add);
        if (OB_SUCCESS == err)
        {
          err = mutation.get_double(mutation_value.double_val,is_add);
        }
        if (OB_SUCCESS == err)
        {
          if (is_add)
          {
            value.double_val += mutation_value.double_val;
          }
          else
          {
            value.double_val = mutation_value.double_val;
          }
          set_double(value.double_val, (org_is_add || org_is_nop) && is_add);
        }
        break;
      case ObDateTimeType:
        if (ext_val_can_change || org_is_nop)
        {
          set_datetime(0);
        }
        err = get_datetime(value.second_val,org_is_add);
        if (OB_SUCCESS == err)
        {
          err = mutation.get_datetime(mutation_value.second_val,is_add);
        }
        if (OB_SUCCESS == err)
        {
          if (is_add)
          {
            value.second_val += mutation_value.second_val;
          }
          else
          {
            value.second_val = mutation_value.second_val;
          }
          set_datetime(value.second_val,is_add && (org_is_add || org_is_nop));
        }
        break;
      case ObPreciseDateTimeType:
        if (ext_val_can_change || org_is_nop)
        {
          set_precise_datetime(0);
        }
        err = get_precise_datetime(value.microsecond_val,org_is_add);
        if (OB_SUCCESS == err)
        {
          err = mutation.get_precise_datetime(mutation_value.microsecond_val,is_add);
        }
        if (OB_SUCCESS == err)
        {
          if (is_add)
          {
            value.microsecond_val += mutation_value.microsecond_val;
          }
          else
          {
            value.microsecond_val = mutation_value.microsecond_val;
          }
          set_precise_datetime(value.microsecond_val,is_add && (org_is_add || org_is_nop));
        }
        break;
      case ObExtendType:
        switch (mutation.get_ext())
        {
          case ObActionFlag::OP_DEL_ROW:
          case ObActionFlag::OP_DEL_TABLE:
            /// used for join, if right row was deleted, set the cell to null
            set_null();
            break;
          case ObActionFlag::OP_ROW_DOES_NOT_EXIST:
            /// do nothing
            break;
          case ObActionFlag::OP_NOP:
            if (org_ext == ObActionFlag::OP_ROW_DOES_NOT_EXIST
                || org_ext == ObActionFlag::OP_DEL_ROW)
            {
              set_null();
            }
            break;
          default:
            TBSYS_LOG(ERROR,"unsupported ext value [value:%ld]", mutation.get_ext());
            err = OB_INVALID_ARGUMENT;
            break;
        }

        break;
      case ObCreateTimeType:
        err = mutation.get_createtime(create_time);
        if (OB_SUCCESS == err)
        {
          if (ext_val_can_change || org_is_nop)
          {
            set_createtime(create_time);
          }
        }
        if (OB_SUCCESS == err)
        {
          err = get_createtime(value.create_time_val);
        }
        if (OB_SUCCESS == err)
        {
          err = mutation.get_createtime(mutation_value.create_time_val);
        }
        if (OB_SUCCESS == err)
        {
          set_createtime(std::min<ObCreateTime>(value.create_time_val,mutation_value.create_time_val));
        }
        break;
      case ObModifyTimeType:
        err = mutation.get_modifytime(modify_time);
        if (OB_SUCCESS == err)
        {
          if (ext_val_can_change || org_is_nop)
          {
            set_modifytime(modify_time);
          }
        }
        if (OB_SUCCESS == err)
        {
          err = get_modifytime(value.modify_time_val);
        }
        if (OB_SUCCESS == err)
        {
          err = mutation.get_modifytime(mutation_value.modify_time_val);
        }
        if (OB_SUCCESS == err)
        {
          set_modifytime(std::max<ObCreateTime>(value.modify_time_val,mutation_value.modify_time_val));
        }
        break;
      case ObDecimalType:
        {
          ObNumber num, mutation_num, res;
          if (ext_val_can_change || org_is_nop)
          {
            num.set_zero();
          }
          else
          {
            err = get_decimal(num, org_is_add);
          }
          if (OB_SUCCESS == err)
          {
            err = mutation.get_decimal(mutation_num, is_add);
          }
          if (OB_SUCCESS == err)
          {
            if (is_add)
            {
              err = num.add(mutation_num, res);
            }
            else
            {
              res = mutation_num;
            }
          }
          if (OB_SUCCESS == err)
          {
            set_decimal(res, meta_.dec_precision_, meta_.dec_scale_, (org_is_add || org_is_nop) && is_add);
          }
          break;
        }
      default:
        /* case ObSeqType: */
        TBSYS_LOG(ERROR,"unsupported type [type:%d]", mut_type);
        err = OB_INVALID_ARGUMENT;
        break;
    }
  }
  if(OB_SUCCESS != err)
  {
    TBSYS_LOG(WARN,"fail to apply [this->type:%d,this->ext:%d,"
        "mutation->type:%d,mutation->ext:%ld, err:%d]",
        org_type, org_ext, mut_type, mutation.get_ext(), err);
  }
  return err;
}
Exemplo n.º 2
0
int ObObj::compare_same_type(const ObObj &other) const
{
  int cmp = 0;
  switch(get_type())
  {
    case ObIntType:
      if (this->value_.int_val < other.value_.int_val)
      {
        cmp = -1;
      }
      else if (this->value_.int_val == other.value_.int_val)
      {
        cmp = 0;
      }
      else
      {
        cmp = 1;
      }
      break;
    case ObDecimalType:
      {
        ObNumber n1, n2;
        get_decimal(n1);
        other.get_decimal(n2);
        cmp = n1.compare(n2);
        break;
      }
    case ObVarcharType:
      {
        ObString varchar1, varchar2;
        this->get_varchar(varchar1);
        other.get_varchar(varchar2);
        cmp = varchar1.compare(varchar2);
        break;
      }
    case ObFloatType:
      {
        bool float_eq = fabsf(value_.float_val - other.value_.float_val) < FLOAT_EPSINON;
        if (float_eq)
        {
          cmp = 0;
        }
        else if (this->value_.float_val < other.value_.float_val)
        {
          cmp = -1;
        }
        else
        {
          cmp = 1;
        }
        break;
      }
    case ObDoubleType:
      {
        bool double_eq = fabs(value_.double_val - other.value_.double_val) < DOUBLE_EPSINON;
        if (double_eq)
        {
          cmp = 0;
        }
        else if (this->value_.double_val < other.value_.double_val)
        {
          cmp = -1;
        }
        else
        {
          cmp = 1;
        }
        break;
      }
    case ObDateTimeType:
    case ObPreciseDateTimeType:
    case ObCreateTimeType:
    case ObModifyTimeType:
      {
        int64_t ts1 = 0;
        int64_t ts2 = 0;
        get_timestamp(ts1);
        other.get_timestamp(ts2);
        if (ts1 < ts2)
        {
          cmp = -1;
        }
        else if (ts1 == ts2)
        {
          cmp = 0;
        }
        else
        {
          cmp = 1;
        }
        break;
      }
    case ObBoolType:
      cmp = this->value_.bool_val - other.value_.bool_val;
      break;
    default:
      TBSYS_LOG(ERROR, "invalid type=%d", get_type());
      break;
  }
  return cmp;
}