1
- /*
2
- * Copyright Redis Ltd. 2016 - present
3
- * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or
4
- * the Server Side Public License v1 (SSPLv1).
5
- */
6
-
1
+ /*
2
+ * Copyright Redis Ltd. 2016 - present
3
+ * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or
4
+ * the Server Side Public License v1 (SSPLv1).
5
+ */
6
+
7
7
use crate :: error:: Error ;
8
+ use crate :: jsonpath:: select_value:: SelectValue ;
8
9
use crate :: manager:: { err_json, err_msg_json_expected, err_msg_json_path_doesnt_exist} ;
9
10
use crate :: manager:: { Manager , ReadHolder , WriteHolder } ;
10
11
use crate :: redisjson:: normalize_arr_start_index;
@@ -219,7 +220,7 @@ impl<'a> IValueKeyHolderWrite<'a> {
219
220
mut op2_fun : F2 ,
220
221
) -> Result < Number , RedisError >
221
222
where
222
- F1 : FnMut ( i64 , i64 ) -> i64 ,
223
+ F1 : FnMut ( i64 , i64 ) -> ( i64 , bool ) ,
223
224
F2 : FnMut ( f64 , f64 ) -> f64 ,
224
225
{
225
226
let in_value = & serde_json:: from_str ( num) ?;
@@ -230,14 +231,40 @@ impl<'a> IValueKeyHolderWrite<'a> {
230
231
v. as_number ( ) . unwrap ( ) . has_decimal_point ( ) ,
231
232
in_value. as_i64 ( ) ,
232
233
) {
233
- ( false , Some ( num2) ) => Ok ( ( ( op1_fun ) ( v . to_i64 ( ) . unwrap ( ) , num2 ) ) . into ( ) ) ,
234
- _ => {
235
- let num1 = v. to_f64 ( ) . unwrap ( ) ;
236
- let num2 = in_value . as_f64 ( ) . unwrap ( ) ;
237
- if let Ok ( num) = INumber :: try_from ( ( op2_fun ) ( num1, num2) ) {
238
- Ok ( num)
234
+ ( false , Some ( num2) ) => {
235
+ // Both are integers
236
+ if let Ok ( num1) = v. get_long ( ) {
237
+ // v is i64
238
+ let ( num, _ ) = ( op1_fun ) ( num1, num2) ;
239
+ Ok ( INumber :: from ( num) )
239
240
} else {
240
- Err ( RedisError :: Str ( "result is not a number" ) )
241
+ Err ( RedisError :: Str ( "u64 is not supported" ) )
242
+ }
243
+ }
244
+ ( false , None ) => {
245
+ // Left is integer, Right is f64 or u64
246
+ match ( v. get_long ( ) , in_value. as_f64 ( ) ) {
247
+ ( Ok ( num1) , Some ( num2) ) => {
248
+ if let Ok ( num) = INumber :: try_from ( ( op2_fun) ( num1 as f64 , num2) ) {
249
+ Ok ( num)
250
+ } else {
251
+ Err ( RedisError :: Str ( "result is not a number" ) )
252
+ }
253
+ }
254
+ _ => Err ( RedisError :: Str ( "u64 is not supported" ) ) ,
255
+ }
256
+ }
257
+ _ => {
258
+ // Both are double
259
+ match ( v. get_double ( ) , in_value. as_f64 ( ) ) {
260
+ ( num1, Some ( num2) ) => {
261
+ if let Ok ( num) = INumber :: try_from ( ( op2_fun) ( num1, num2) ) {
262
+ Ok ( num)
263
+ } else {
264
+ Err ( RedisError :: Str ( "result is not a number" ) )
265
+ }
266
+ }
267
+ _ => Err ( RedisError :: Str ( "bad input number" ) ) ,
241
268
}
242
269
}
243
270
} ;
@@ -382,15 +409,15 @@ impl<'a> WriteHolder<IValue, IValue> for IValueKeyHolderWrite<'a> {
382
409
}
383
410
384
411
fn incr_by ( & mut self , path : Vec < String > , num : & str ) -> Result < Number , RedisError > {
385
- self . do_num_op ( path, num, |i1, i2| i1 + i2 , |f1, f2| f1 + f2)
412
+ self . do_num_op ( path, num, |i1, i2| i1. overflowing_add ( i2 ) , |f1, f2| f1 + f2)
386
413
}
387
414
388
415
fn mult_by ( & mut self , path : Vec < String > , num : & str ) -> Result < Number , RedisError > {
389
- self . do_num_op ( path, num, |i1, i2| i1 * i2 , |f1, f2| f1 * f2)
416
+ self . do_num_op ( path, num, |i1, i2| i1. overflowing_mul ( i2 ) , |f1, f2| f1 * f2)
390
417
}
391
418
392
419
fn pow_by ( & mut self , path : Vec < String > , num : & str ) -> Result < Number , RedisError > {
393
- self . do_num_op ( path, num, |i1, i2| i1. pow ( i2 as u32 ) , f64:: powf)
420
+ self . do_num_op ( path, num, |i1, i2| i1. overflowing_pow ( i2 as u32 ) , f64:: powf)
394
421
}
395
422
396
423
fn bool_toggle ( & mut self , path : Vec < String > ) -> Result < bool , RedisError > {
0 commit comments