HandlerSocket-Plugin-for-MySQL
HandlerSocket-Plugin-for-MySQL copied to clipboard
HandlerSocket & non-primary keys
Should it work?
For example, I do following:
CREATE TABLE test (id INT PRIMARY KEY AUTO_INCREMENT, value INT UNIQUE); INSERT INTO test VALUES (10,15);
Index on value is created, and it is displayed when I do 'SHOW INDEX FROM test';
HandlerSocket works fine when I query the PRIMARY index for value '10', but doesn't work when I query 'value' index for value 15.
Hi! I think I found the source of this strange behavior:
at database.cpp:dbcontext::cmd_find_internal() you define key_buf as uchar key_buf[kinfo.key_length], but on key_copy() you pass kplen_sum, so, you don't initialize trailing bytes in key_buf.
There is the patch:
--- a/handlersocket/database.cpp
+++ b/handlersocket/database.cpp
@ -744,8 +776,9 @@ dbcontext::cmd_find_internal(dbcallback_i& cb, const prep_stmt& pst,
kpt.field->store(kval.begin(), kval.size(), &my_charset_bin);
kplen_sum += kpt.length;
}
- key_copy(key_buf, table->record[0], &kinfo, kplen_sum);
+ key_copy(key_buf, table->record[0], &kinfo, kinfo.key_length);
}
+
/* filters */
uchar *filter_buf = 0;
if (args.filters != 0) {
I've reproduced the bug. The problem is that kplen_sum accumulates kpt.length instead of kpt.store_length. Because of this, the last byte of the specified value is dropped when the field is nullable.
Thanks a lot.
Hi kzn,
What is the syntax for 'find' request in this case, ie., while using non-primary keys
As per the docs, the get data syntax is as follows,
<indexid> <op> <vlen> <v1> ... <vn> <limit> <offset>
I think <v1> ... <vn> takes the order of the fields as in the table.
Suppose, as in your example table,
CREATE TABLE test (id INT PRIMARY KEY AUTO_INCREMENT, value INT UNIQUE);
what is the syntax to get data by comparing only the 'value' field.