@@ -2577,25 +2577,57 @@ int redis_zadd_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
2577
2577
char * * cmd , int * cmd_len , short * slot , void * * ctx )
2578
2578
{
2579
2579
zval * z_args ;
2580
- char * key , * val ;
2580
+ char * key , * val , * exp_type = NULL ;
2581
2581
int key_len , key_free , val_len , val_free ;
2582
- int argc = ZEND_NUM_ARGS (), i ;
2582
+ int num = ZEND_NUM_ARGS (), i = 1 , argc ;
2583
+ zend_bool ch = 0 , incr = 0 ;
2583
2584
smart_string cmdstr = {0 };
2584
2585
2585
- z_args = emalloc (argc * sizeof (zval ));
2586
- if (zend_get_parameters_array (ht , argc , z_args ) == FAILURE ) {
2586
+ if (num < 3 ) return FAILURE ;
2587
+ z_args = ecalloc (num , sizeof (zval ));
2588
+ if (zend_get_parameters_array (ht , num , z_args ) == FAILURE ) {
2587
2589
efree (z_args );
2588
2590
return FAILURE ;
2589
2591
}
2590
2592
2591
- // Need key, score, value, [score, value...] */
2592
- if (argc > 0 ) convert_to_string (& z_args [0 ]);
2593
- if (argc < 3 || Z_TYPE (z_args [0 ])!= IS_STRING || (argc - 1 )%2 != 0 ) {
2594
- efree (z_args );
2595
- return FAILURE ;
2593
+ // Need key, [NX|XX] [CH] [INCR] score, value, [score, value...] */
2594
+ if (num % 2 == 0 ) {
2595
+ if (Z_TYPE (z_args [1 ]) != IS_ARRAY ) {
2596
+ efree (z_args );
2597
+ return FAILURE ;
2598
+ }
2599
+ zval * z_opt ;
2600
+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL (z_args [1 ]), z_opt ) {
2601
+ if (Z_TYPE_P (z_opt ) == IS_STRING ) {
2602
+ if (Z_STRLEN_P (z_opt ) == 2 ) {
2603
+ if (IS_NX_XX_ARG (Z_STRVAL_P (z_opt ))) {
2604
+ exp_type = Z_STRVAL_P (z_opt );
2605
+ } else if (strncasecmp (Z_STRVAL_P (z_opt ), "ch" , 2 ) == 0 ) {
2606
+ ch = 1 ;
2607
+ }
2608
+ } else if (Z_STRLEN_P (z_opt ) == 4 &&
2609
+ strncasecmp (Z_STRVAL_P (z_opt ), "incr" , 4 ) == 0
2610
+ ) {
2611
+ if (num > 4 ) {
2612
+ // Only one score-element pair can be specified in this mode.
2613
+ efree (z_args );
2614
+ return FAILURE ;
2615
+ }
2616
+ incr = 1 ;
2617
+ }
2618
+
2619
+ }
2620
+ } ZEND_HASH_FOREACH_END ();
2621
+ argc = num - 1 ;
2622
+ if (exp_type ) argc ++ ;
2623
+ argc += ch + incr ;
2624
+ i ++ ;
2625
+ } else {
2626
+ argc = num ;
2596
2627
}
2597
2628
2598
2629
// Prefix our key
2630
+ convert_to_string (& z_args [0 ]);
2599
2631
key = Z_STRVAL (z_args [0 ]);
2600
2632
key_len = Z_STRLEN (z_args [0 ]);
2601
2633
key_free = redis_key_prefix (redis_sock , & key , & key_len );
@@ -2608,19 +2640,32 @@ int redis_zadd_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
2608
2640
CMD_SET_SLOT (slot ,key ,key_len );
2609
2641
if (key_free ) efree (key );
2610
2642
2643
+ if (exp_type ) redis_cmd_append_sstr (& cmdstr , exp_type , 2 );
2644
+ if (ch ) redis_cmd_append_sstr (& cmdstr , "CH" , 2 );
2645
+ if (incr ) redis_cmd_append_sstr (& cmdstr , "INCR" , 4 );
2646
+
2611
2647
// Now the rest of our arguments
2612
- for (i = 1 ;i < argc ;i += 2 ) {
2613
- // Convert score to a double, serialize value if requested
2614
- convert_to_double (& z_args [i ]);
2648
+ while (i < num ) {
2649
+ // Append score and member
2650
+ if (Z_TYPE (z_args [i ]) == IS_STRING && (
2651
+ /* The score values should be the string representation of a double
2652
+ * precision floating point number. +inf and -inf values are valid
2653
+ * values as well. */
2654
+ strncasecmp (Z_STRVAL (z_args [i ]), "-inf" , 4 ) == 0 ||
2655
+ strncasecmp (Z_STRVAL (z_args [i ]), "+inf" , 4 ) == 0
2656
+ )) {
2657
+ redis_cmd_append_sstr (& cmdstr , Z_STRVAL (z_args [i ]), Z_STRLEN (z_args [i ]));
2658
+ } else {
2659
+ redis_cmd_append_sstr_dbl (& cmdstr , zval_get_double (& z_args [i ]));
2660
+ }
2661
+ // serialize value if requested
2615
2662
val_free = redis_serialize (redis_sock , & z_args [i + 1 ], & val , & val_len
2616
2663
TSRMLS_CC );
2617
-
2618
- // Append score and member
2619
- redis_cmd_append_sstr_dbl (& cmdstr , Z_DVAL (z_args [i ]));
2620
2664
redis_cmd_append_sstr (& cmdstr , val , val_len );
2621
2665
2622
2666
// Free value if we serialized
2623
2667
if (val_free ) efree (val );
2668
+ i += 2 ;
2624
2669
}
2625
2670
2626
2671
// Push output values
0 commit comments