| 6145 | |
| 6146 | |
| 6147 | dsc* evlPower(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, |
| 6148 | impure_value* impure) |
| 6149 | { |
| 6150 | fb_assert(args.getCount() == 2); |
| 6151 | |
| 6152 | Request* request = tdbb->getRequest(); |
| 6153 | |
| 6154 | const dsc* value[2]; |
| 6155 | value[0] = EVL_expr(tdbb, request, args[0]); |
| 6156 | if (request->req_flags & req_null) // return NULL if value is NULL |
| 6157 | return NULL; |
| 6158 | |
| 6159 | value[1] = EVL_expr(tdbb, request, args[1]); |
| 6160 | if (request->req_flags & req_null) // return NULL if value is NULL |
| 6161 | return NULL; |
| 6162 | |
| 6163 | if (!areParamsDouble(2, value)) |
| 6164 | { |
| 6165 | DecimalStatus decSt = tdbb->getAttachment()->att_dec_status; |
| 6166 | impure->vlu_misc.vlu_dec128 = MOV_get_dec128(tdbb, value[0]); |
| 6167 | Decimal128 v2 = MOV_get_dec128(tdbb, value[1]); |
| 6168 | |
| 6169 | impure->vlu_misc.vlu_dec128 = impure->vlu_misc.vlu_dec128.pow(decSt, v2); |
| 6170 | impure->vlu_desc.makeDecimal128(&impure->vlu_misc.vlu_dec128); |
| 6171 | } |
| 6172 | else |
| 6173 | { |
| 6174 | impure->vlu_desc.makeDouble(&impure->vlu_misc.vlu_double); |
| 6175 | |
| 6176 | const double v1 = MOV_get_double(tdbb, value[0]); |
| 6177 | const double v2 = MOV_get_double(tdbb, value[1]); |
| 6178 | |
| 6179 | if (v1 == 0 && v2 < 0) |
| 6180 | { |
| 6181 | status_exception::raise(Arg::Gds(isc_expression_eval_err) << |
| 6182 | Arg::Gds(isc_sysf_invalid_zeropowneg) << |
| 6183 | Arg::Str(function->name)); |
| 6184 | } |
| 6185 | |
| 6186 | if (v1 < 0 && |
| 6187 | (!value[1]->isExact() || |
| 6188 | MOV_get_int64(tdbb, value[1], 0) * SINT64(CVT_power_of_ten(-value[1]->dsc_scale)) != |
| 6189 | MOV_get_int64(tdbb, value[1], value[1]->dsc_scale))) |
| 6190 | { |
| 6191 | status_exception::raise(Arg::Gds(isc_expression_eval_err) << |
| 6192 | Arg::Gds(isc_sysf_invalid_negpowfp) << |
| 6193 | Arg::Str(function->name)); |
| 6194 | } |
| 6195 | |
| 6196 | const double rc = pow(v1, v2); |
| 6197 | if (std::isinf(rc)) |
| 6198 | status_exception::raise(Arg::Gds(isc_arith_except) << Arg::Gds(isc_exception_float_overflow)); |
| 6199 | |
| 6200 | impure->vlu_misc.vlu_double = rc; |
| 6201 | } |
| 6202 | |
| 6203 | return &impure->vlu_desc; |
| 6204 | } |
nothing calls this directly
no test coverage detected