Skip to content

Instantly share code, notes, and snippets.

@eatonphil
Last active January 7, 2024 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eatonphil/41f33066b4acfb672d5f05c00f63df3a to your computer and use it in GitHub Desktop.
Save eatonphil/41f33066b4acfb672d5f05c00f63df3a to your computer and use it in GitHub Desktop.
Returning data from rnd_next() in a custom storage engine.

rnd_next(uchar* buf) for a storage engine sets up the current row of data. If there is data, it returns a 0. Otherwise it returns a HA_ERR_END_OF_FILE or other error.

Row data is written into the uchar* buf field. You might imagine you would return structured data for a row and the API would be like rnd_next(Fields**, field_count int). But that's not how the API works. You write the fields as bytes directly into uchar* buf.

The first X bytes are a NULL bitmap. One bit for each NULL-able column, padded out to a full byte. After that is each value for each field. For a table with two INT columns (they'd both be NULL-able), you'd write 9 bytes to uchar* buf. The first byte would be a NULL bitmap of all zeroes if both values in the row were not NULL. The next 4 bytes would be the first column's value. The last 4 bytes would be the second column's value.

Here's a diff for the BLACKHOLE engine, hardcoding a single row response: https://github.com/MariaDB/server/compare/11.4...eatonphil:mariadb:e076ac98a7b29dc857a1fd512553414e7ca0436a.

For some reason, the BLACKHOLE engine is always disabled. But it's just easiest to show these changes as a diff without all the additional renaming of a completely new storage engine.

Once you've rebuilt the project, install the blackhole plugin, create a table with it, SELECT * FROM y and you'll get:

+------+------+
| i    | j    |
+------+------+
|  201 |  432 |
+------+------+

Resources:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment