Value DecimalType::Modulo(const Value& left, const Value &right) const { PL_ASSERT(GetTypeId() == Type::DECIMAL); PL_ASSERT(left.CheckComparable(right)); if (left.IsNull() || right.IsNull()) return left.OperateNull(right); if (right.IsZero()) { throw Exception(EXCEPTION_TYPE_DIVIDE_BY_ZERO, "Division by zero."); } switch(right.GetTypeId()) { case Type::TINYINT: return ValueFactory::GetDecimalValue(ValMod(left.value_.decimal, right.GetAs<int8_t>())); case Type::SMALLINT: return ValueFactory::GetDecimalValue(ValMod(left.value_.decimal, right.GetAs<int16_t>())); case Type::INTEGER: return ValueFactory::GetDecimalValue(ValMod(left.value_.decimal, right.GetAs<int32_t>())); case Type::BIGINT: return ValueFactory::GetDecimalValue(ValMod(left.value_.decimal, right.GetAs<int64_t>())); case Type::DECIMAL: return ValueFactory::GetDecimalValue(ValMod(left.value_.decimal, right.GetAs<double>())); default: throw Exception("type error"); } }
Value SmallintType::Modulo(const Value& left, const Value &right) const { PL_ASSERT(left.CheckInteger()); PL_ASSERT(left.CheckComparable(right)); if (left.IsNull() || right.IsNull()) return left.OperateNull(right); if (right.IsZero()) { throw Exception(ExceptionType::DIVIDE_BY_ZERO, "Division by zero on right-hand side"); } switch (right.GetTypeId()) { case TypeId::TINYINT: return ModuloValue<int16_t, int8_t>(left, right); case TypeId::SMALLINT: return ModuloValue<int16_t, int16_t>(left, right); case TypeId::INTEGER: case TypeId::PARAMETER_OFFSET: return ModuloValue<int16_t, int32_t>(left, right); case TypeId::BIGINT: return ModuloValue<int16_t, int64_t>(left, right); case TypeId::DECIMAL: return ValueFactory::GetDecimalValue( ValMod(left.value_.smallint, right.GetAs<double>())); case TypeId::VARCHAR: { auto r_value = right.CastAs(TypeId::SMALLINT); return ModuloValue<int16_t, int16_t>(left, r_value); } default: break; } throw Exception("type error"); }
Value *IntegerValue::Modulo(const Value &o) const { CheckInteger(); CheckComparable(o); if (IsNull() || o.IsNull()) return OperateNull(o); if (((NumericValue &)o).IsZero()) { throw Exception(EXCEPTION_TYPE_DIVIDE_BY_ZERO, "Division by zero."); } switch (GetTypeId()) { case Type::TINYINT: switch (o.GetTypeId()) { case Type::TINYINT: return ModuloValue<int8_t, int8_t>(o); case Type::SMALLINT: return ModuloValue<int8_t, int16_t>(o); case Type::INTEGER: case Type::PARAMETER_OFFSET: return ModuloValue<int8_t, int32_t>(o); case Type::BIGINT: return ModuloValue<int8_t, int64_t>(o); case Type::DECIMAL: return new DecimalValue(ValMod(value_.tinyint, o.GetAs<double>())); default: break; } case Type::SMALLINT: switch (o.GetTypeId()) { case Type::TINYINT: return ModuloValue<int16_t, int8_t>(o); case Type::SMALLINT: return ModuloValue<int16_t, int16_t>(o); case Type::INTEGER: case Type::PARAMETER_OFFSET: return ModuloValue<int16_t, int32_t>(o); case Type::BIGINT: return ModuloValue<int16_t, int64_t>(o); case Type::DECIMAL: return new DecimalValue(ValMod(value_.smallint, o.GetAs<double>())); default: break; } case Type::INTEGER: case Type::PARAMETER_OFFSET: switch (o.GetTypeId()) { case Type::TINYINT: return ModuloValue<int32_t, int8_t>(o); case Type::SMALLINT: return ModuloValue<int32_t, int16_t>(o); case Type::INTEGER: case Type::PARAMETER_OFFSET: return ModuloValue<int32_t, int32_t>(o); case Type::BIGINT: return ModuloValue<int32_t, int64_t>(o); case Type::DECIMAL: return new DecimalValue(ValMod(value_.integer, o.GetAs<double>())); default: break; } case Type::BIGINT: switch (o.GetTypeId()) { case Type::TINYINT: return ModuloValue<int64_t, int8_t>(o); case Type::SMALLINT: return ModuloValue<int64_t, int16_t>(o); case Type::INTEGER: case Type::PARAMETER_OFFSET: return ModuloValue<int64_t, int32_t>(o); case Type::BIGINT: return ModuloValue<int64_t, int64_t>(o); case Type::DECIMAL: return new DecimalValue(ValMod(value_.bigint, o.GetAs<double>())); default: break; } default: break; } throw Exception("type error"); }