Bug #72624 memcached incr decr process_command
Submitted: 12 May 2014 21:22 Modified: 21 Jul 2014 18:35
Reporter: 徹 赤松 Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Memcached Severity:S3 (Non-critical)
Version:mysql-5.7.4-m14 OS:Linux
Assigned to: Daniel Price CPU Architecture:Any
Tags: decr, incr, innodb_memcached, memcached.c, plugin, process_command

[12 May 2014 21:22] 徹 赤松
Description:
i am reading source code of plugin/innodb_memcached in version 5.7.4 now.
When i read process_command() function in plugin/innodb_memcached/daemon_memcached/daemon/memcached.c file, i found a bug.
i read a manual incr,decr command of memcached oparations, must set KEY but option [, value].

i try incr command value(KEY).
# telnet localhost 11211

incr value
ERROR  *** if not set 1, comming ERROR ***

incr value 1
1279   *** must set 1 option ***
quit

How to repeat:
After added ntokens==3 and incr process,
when not set 1, have no ERROR, and execute increment 1.

# telnet localhost 11211

get value
VALUE value 1235 4
1279
END

incr value
1280       *** Not set 1, execute increment 1 have no error ***

incr value 1
1281

decr value
1280       *** Not set 1, execute decrement 1 have no error ***

quit

Suggested fix:
i added case ntokens==3, before incr,decr command process. diff /changed/plugin/innodb_memcached/daemon_memcached/daemon/memcached.c /original/plugin/innodb_memcached/daemon_memcached/daemon/memcached.c

4577,4583d4576
<     } else if ((ntokens == 3) && (strcmp(tokens[COMMAND_TOKEN].value, "incr") == 0)) {
<
<         tokens[2].value=  tokens[3].value= "1";
<         tokens[2].length= tokens[3].length= 1;
<         ntokens++;
<         ret = process_arithmetic_command(c, tokens, ntokens, 1);
<

decr command as same.
4591,4597d4583
<
<     } else if ((ntokens == 3) && (strcmp(tokens[COMMAND_TOKEN].value, "decr") == 0)) {
<
<         tokens[2].value=  tokens[3].value= "1";
<         tokens[2].length= tokens[3].length= 1;
<         ntokens++;
<         ret = process_arithmetic_command(c, tokens, ntokens, 0);
[13 May 2014 2:13] 徹 赤松
i read a manual 15.6.3.1 Basic memcached Operations in version 5.7.

.incr(key [, value]): Incremants the item associated with the key by one or the optional value.

.decr(key [, value]): Decrements the item associated with the key by one or the optional value.

Which is right soce sode or manual?
[18 Jul 2014 4:42] MySQL Verification Team
Thank you for the bug report.
Verified as described.

Thanks,
Umesh
[18 Jul 2014 4:46] MySQL Verification Team
// How to repeat

[ushastry@cluster-repo mysql-5.7.4]$ telnet localhost 11211
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
[ushastry@cluster-repo mysql-5.7.4]$ telnet localhost 11221
Trying ::1...
Connected to localhost.
Escape character is '^]'.
stats
STAT pid 4598
STAT uptime 201
STAT time 1405797326
STAT version 5.7.4-m14
STAT libevent 5.7.4-m14
..
set mykey 0 1111 3
100
STORED
get mykey
VALUE mykey 0 3
100
END
incr mykey 1
101
decr mykey 3
98
incr mykey
ERROR          <--- should have incremented by 1
decr mykey     <--- should have decremented by 1
ERROR

get mykey
VALUE mykey 0 2
98  <---------------- not incr or decr
END

As per the manual http://dev.mysql.com/doc/refman/5.7/en/ha-memcached-operations.html

incr(key [, value]): Increments the item associated with the key by one or the optional value.
decr(key [, value]): Decrements the item associated with the key by one or the optional value.

value is optional, i.e if provided would be used else just increment/decement by 1 but it gives error instead.
[21 Jul 2014 18:35] Daniel Price
The documentation has been updated to reflect that the "value" option for incr and decr is not optional.

http://dev.mysql.com/doc/refman/5.6/en/ha-memcached-operations.html

The change should appear soon, with the next published documentation build. 

Thank you for the bug report.