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; }
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; }