Add (or subtract) the contents of a descriptor to value block, with dialect-1 semantics. This function can be removed when dialect-3 becomes the lowest supported dialect. (Version 7.0?)
| 2054 | // Add (or subtract) the contents of a descriptor to value block, with dialect-1 semantics. |
| 2055 | // This function can be removed when dialect-3 becomes the lowest supported dialect. (Version 7.0?) |
| 2056 | dsc* ArithmeticNode::add(thread_db* tdbb, const dsc* desc, impure_value* value, const ValueExprNode* node, |
| 2057 | const UCHAR blrOp) |
| 2058 | { |
| 2059 | const ArithmeticNode* arithmeticNode = nodeAs<ArithmeticNode>(node); |
| 2060 | |
| 2061 | #ifdef DEV_BUILD |
| 2062 | const SubQueryNode* subQueryNode = nodeAs<SubQueryNode>(node); |
| 2063 | fb_assert( |
| 2064 | (arithmeticNode && arithmeticNode->dialect1 && |
| 2065 | (arithmeticNode->blrOp == blr_add || arithmeticNode->blrOp == blr_subtract)) || |
| 2066 | nodeIs<AggNode>(node) || |
| 2067 | (subQueryNode && (subQueryNode->blrOp == blr_total || subQueryNode->blrOp == blr_average))); |
| 2068 | #endif |
| 2069 | |
| 2070 | dsc* const result = &value->vlu_desc; |
| 2071 | |
| 2072 | // Handle date arithmetic |
| 2073 | |
| 2074 | if (node->nodFlags & FLAG_DATE) |
| 2075 | { |
| 2076 | fb_assert(arithmeticNode); |
| 2077 | return arithmeticNode->addDateTime(tdbb, desc, value); |
| 2078 | } |
| 2079 | |
| 2080 | // Handle decimal arithmetic |
| 2081 | |
| 2082 | if (node->nodFlags & FLAG_DECFLOAT) |
| 2083 | { |
| 2084 | const Decimal128 d1 = MOV_get_dec128(tdbb, desc); |
| 2085 | const Decimal128 d2 = MOV_get_dec128(tdbb, &value->vlu_desc); |
| 2086 | |
| 2087 | DecimalStatus decSt = tdbb->getAttachment()->att_dec_status; |
| 2088 | value->vlu_misc.vlu_dec128 = (blrOp == blr_subtract) ? d2.sub(decSt, d1) : d1.add(decSt, d2); |
| 2089 | |
| 2090 | result->dsc_dtype = dtype_dec128; |
| 2091 | result->dsc_length = sizeof(Decimal128); |
| 2092 | result->dsc_scale = 0; |
| 2093 | result->dsc_sub_type = 0; |
| 2094 | result->dsc_address = (UCHAR*) &value->vlu_misc.vlu_dec128; |
| 2095 | |
| 2096 | return result; |
| 2097 | } |
| 2098 | |
| 2099 | // Handle floating arithmetic |
| 2100 | |
| 2101 | if (node->nodFlags & FLAG_DOUBLE) |
| 2102 | { |
| 2103 | const double d1 = MOV_get_double(tdbb, desc); |
| 2104 | const double d2 = MOV_get_double(tdbb, &value->vlu_desc); |
| 2105 | |
| 2106 | value->vlu_misc.vlu_double = (blrOp == blr_subtract) ? d2 - d1 : d1 + d2; |
| 2107 | |
| 2108 | if (std::isinf(value->vlu_misc.vlu_double)) |
| 2109 | ERR_post(Arg::Gds(isc_arith_except) << Arg::Gds(isc_exception_float_overflow)); |
| 2110 | |
| 2111 | result->dsc_dtype = DEFAULT_DOUBLE; |
| 2112 | result->dsc_length = sizeof(double); |
| 2113 | result->dsc_scale = 0; |
no test coverage detected