Monday, August 24, 2009

More Drizzle plug-ins

Last weekend, I finally got some time to look around Drizzle. I had already compiled it on my laptop, but hadn't really looked at the code.
Then, I thought that looking over some of the blueprints on Launchpad, would be a good way to get familiar with the code base.
After a quick search, I found move function/time/ functions into plugin(s)

This blueprint is basically to create UDF plug-ins for the different time related functions.
There was no priority assigned and it was on the low hanging fruit milestone. Which was perfect for someone who doesn't really know how much time he could spend, and wants to get to know the code.

The first step was to read a bit about the process to contribute to the Drizzle project, I went to the wiki here and read about the coding standards.

I then, went ahead and saw how difficult easy the code looked like. And proceeded to email the list, asking for feedback and also to tell others what I was up to. This is important, to avoid duplicating the work of others.

Code?
This is where the fun began. I had a fresh branch, and it was time to pick the first function to make into an UDF plugin.
By luck (and you will know why luck), I picked to move unix_timestamp() first.

The Process
There are already some great plugins on the Drizzle branch. I went ahead and duplicated the md5 plugin (in plugin/md5). Renamed the folder unix_timestamp, also renamed the md5.cc to unix_timestamp.cc and edited the plugin.ini file that was on the same folder.

The md5 plugin folder also has a plugin.ac file, but it turned out I didn't need this file, so I just removed it.

It was then time to do the actual code moving. To start, I opened drizzled/function/time/unix_timestamp.cc and drizzled/function/time/unix_timestamp.h
It was pretty much copy and paste from those two files into plugin/unix_timestamp/unix_timestamp.cc

And the rest was to replace md5 for unix_timestamp :)

Notes:
When I first started, I had both, the built-in unix_timestamp() and the plugin version. To make sure the plugin was returning the correct values, I just temporary named the plugin function unix_timestamp2(). And you can do that by just changing code in two lines:

Error messages
Whenever there is an error with your function, the error message will call the plugin function func_name(), the string you return there, will be shown on error messages. One way to force this error is by including either too many, or too few parameters.

const char *func_name() const
{
return "unix_timestamp2";
}

To tell Drizzle the name of your plugin function, you use this line:

Create_function unix_timestampudf(string("unix_timestamp2"));

Most (all?) plugins files will start with lib + <name of the plugin> + _plugin.la. You specify this name using this line:

drizzle_declare_plugin(unix_timestamp)
The rest should be pretty easy to figure out.

Tip
Which I wish I knew before. Something that took me way too long to find out, when you add a new plugin folder, you need to run ./config/autorun.sh and ./configure ... && make && make install. This would make sure your new plugin gets compiled., if you skip autorun.sh, your new plugin will not be compiled.

Final steps
Once I compiled the new plugin, and verified that it all worked well. It was time to delete the built-in function.
1) Went to drizzled/Makefile.am and removed function/time/unix_timestamp.h from there.
2) Removed the files drizzled/function/time/unix_timestamp.cc and drizzled/function/time/unix_timestamp.h
3) Edited drizzled/item/create.cc and removed #include and some other references to the unix_timestamp function.
4) drizzled/sql_parse.cc also had to be edited, to remove #include .
5) Added the new plugin/unix_timestamp/ folder and files to the bzr branch.
6) Run tests (and here I found a new problem)

I'm still working on a fix for it. I'm going with using one error message, for built-in functions, as well as plugins. I hope to be pushing those changes soon.

Oh, why was I lucky to pick the unix_timestamp() function as the first one to tackle, well, I have been working on timestamp_diff for many hours, and it just does not want to work. It somehow does not see the first parameter. I'm pretty sure I'll be asking the Drizzle-discuss for help :)

The end.


select * from information_schema.plugins where plugin_name like '%time%';
+-------------------------+----------------+---------------+---------------+--------------------------------+----------------+
| PLUGIN_NAME | PLUGIN_VERSION | PLUGIN_STATUS | PLUGIN_AUTHOR | PLUGIN_DESCRIPTION | PLUGIN_LICENSE |
+-------------------------+----------------+---------------+---------------+--------------------------------+----------------+
| unix_timestamp_function | 1.0 | ACTIVE | Diego Medina | UDF for getting unix_timestamp | GPL |
+-------------------------+----------------+---------------+---------------+--------------------------------+----------------+
1 row in set (0 sec)

drizzle>
Well, not really the end, I still have plenty of functions to move into plugins.

Thanks!

2 comments:

  1. Do you have to recompile all of Drizzle when compiling a single plugin?

    ReplyDelete
  2. Hi, I keep learning new things about Drizzle, it turned out that once you add a new folder with some basic plugin code, you only need to run this:

    $ python ./config/register_plugins.py

    And then you can run make.

    That being said, Monty Taylor has been working on a way to build plugins without having to compile the drizzle code at all (so you could have a totally separate branch). I'm not sure how far along he is, but the way you can add plugins now, is not that bad imho.

    Thanks

    -Diego

    ReplyDelete

Vote on Planet MySQL