I wrote a lightweight sockets based HandlerSocket query system and it's worked perfectly.... short of this one little problem....
I have a table in the DB that has a unique
index with 5 key parts:
function, type, parameter, Module_ID, Site_ID
All are strings, the first 4 columns are required, the last (Site_ID) is not AND it may be NULL
. The brief explanation is that all Sites share records that have a Site_ID = NULL
, however each Site can override the default record with one of it's own with their specific Site_ID
supplied.
My Sockets query prepares the request like so:
$request = array(
'indexid' => $key,
'op' => $query->get_type(),
'vlen' => count($query->get_keys()),
'keys' => implode("\t",$query->get_key_values()),
'limit' => $query->get_limit(),
'offset' => $query->get_offset());
// Join as TAB separated values
$request = implode("\t",$request)."\n";
So when all 5 column parts and key values are supplied it works, when the first 4 columns and first 4 key values are supplied it works, but when all 5 columns and their corresponding key values with the 5th being NULL
are used, it returns nothing when I know for a fact there are records that match the first 4 and have a NULL
Site_ID.
I MUST be able to use the 3rd scenario because I need to be sure that it doesn't match any that have Site_ID's defined.
I'm assuming that the issues lies in the \t
joined key values but I'm not sure what the correct value to use here is to match a NULL column value... because it's not NULL
.
If anyone can shed some light on the correct way of formatting this request so that it can match the NULL
5th column, I'd be grateful!
So in the end, it helps to Re-RTM... which can be found here: https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/blob/master/docs-en/protocol.en.txt
In the opening section Basic syntax
, it states that:
NULL is expressed as a single NUL(0x00).
And so I've adjusted my key value preparation to the following:
$values = $query->get_key_values();
foreach ($values as $vid => $value) { if (!isset($value)) { $values[$vid] = "\x00"; } }
$values = implode("\t",$values); // TAB Separated
This replaces all native NULL
values with a HEX Null byte which is differentiated from an empty string allowing the server to match the column to NULL
values.
Hope that helps someone else.