Archives for August 2007

tcl-mysql-udf 0.2 and Win32 DLL binary

Last week, I released some code that would enable MySQL to evaluate Tcl scripts as a stored function, which I called tcl-mysql-udf. My friend Steve asked if I could prepare a Win32 DLL binary for him, so I worked on that tonight and am releasing version 0.2, along with the DLL:

In order to play with this, you’ll need the following prerequisites installed:

  • MySQL (I’m testing on 5.1.21-beta)
  • Tcl (I’m testing on 8.4.15.0)

Inside the tcl-mysql-udf-0.2-dll.zip will be the file tcl-mysql-udf.dll. On MySQL 5.0.x, it expects it to reside in the Program Files\MySQL\MySQL Server 5.0\bin directory, so copy it there. On MySQL 5.1.x, however, it expects it to be in the Program Files\MySQL\MySQL Server 5.1\lib directory. Pay close attention to what version of MySQL you’re using and the correct directory to copy the DLL into.

Once you’ve got everything installed and copied to the right locations so far, connect to your MySQL database with your favorite MySQL client, and issue the following command (you only type what’s in bold):

mysql> CREATE FUNCTION TCL RETURNS STRING SONAME 'tcl-mysql-udf.dll';
Query OK, 0 rows affected (0.10 sec)

We can check what version of Tcl we’ve loaded this way:

mysql> SELECT TCL('info patchlevel') AS script;
+--------+
| script |
+--------+
| 8.4.15 |
+--------+
1 row in set (0.04 sec)

Here’s a goofy example of storing Tcl scripts in the database and having MySQL evaluate them:

mysql> CREATE TABLE code (
n INT NOT NULL AUTO_INCREMENT,
script TEXT NOT NULL,
PRIMARY KEY pk_code (n)
) ENGINE=MyISAM;

Query OK, 0 rows affected (0.20 sec)

mysql> INSERT INTO code (script) VALUES
('set x 123'),
('expr {$x + 432}'),
('clock format [clock seconds]'),
('incr x [clock seconds]'),
('expr {$x * rand()}');

Query OK, 5 rows affected (0.04 sec)
Records: 5  Duplicates: 0  Warnings: 0

So, we now have a table with five rows in it, each row containing a Tcl script. We can have MySQL evaluate those Tcl scripts like this:

mysql> SELECT n, TCL(script)
FROM code
ORDER BY n;

+---+---------------------------------------------------+
| n | TCL(script)                                       |
+---+---------------------------------------------------+
| 1 | 123                                               |
| 2 | 555                                               |
| 3 | Fri Aug 31 12:41:25 AM Eastern Daylight Time 2007 |
| 4 | 1188535408                                        |
| 5 | 6935485.39171                                     |
+---+---------------------------------------------------+
5 rows in set (0.05 sec)

So what, right? How about fetching HTML documents via HTTP, right from within MySQL?

mysql> CREATE TABLE urls (
n INT NOT NULL AUTO_INCREMENT,
url VARCHAR(255) NOT NULL,
PRIMARY KEY pk_urls (n)
) ENGINE=MyISAM;

Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO urls (url) VALUES
('http://dossy.org/'),
('http://aolserver.com/'),
('http://njgeeks.org/');

Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT n, url, TCL(
'package require http;'
'set url [lindex $args 0];'
'set token [http::geturl $url];'
'set data [http::data $token];'
'http::cleanup $token;'
'regexp -all -inline {<title>.*?</title>} $data',
url) AS script
FROM urls
ORDER BY n \G

*************************** 1. row ***************************
     n: 1
   url: http://dossy.org/
script: {<title>Dossy's Blog</title>}
*************************** 2. row ***************************
     n: 2
   url: http://aolserver.com/
script: <title>AOLserver</title>
*************************** 3. row ***************************
     n: 3
   url: http://njgeeks.org/
script: {<title>NJ Geeks | - New Jersey's IT Community</title>}
3 rows in set (1.54 sec)

This query uses the Tcl “http” package to fetch the documents specified by the url column and plucks out the <title> tag using a regular expression. The TCL() stored function takes a variable number of arguments, the first being the Tcl script to evaluate, followed by zero or more arguments that are placed into the $args Tcl variable. In this case, we pass in “url” so that on each row, we execute our Tcl script with the value from that row.

Be aware that this stored function is a security issue: allowing database users to execute arbitrary code has obvious risks, especially since that code will be executed as the user that the MySQL server is running as.

Hopefully this is enough to get you started and might even give you an idea as to how this could be useful to you in some way. If you have any questions, just leave them in the comments below.

Tags: , , ,

libpurple patch to extend the purple::cmd Tcl command

As of Pidgin 2.1.1, the Tcl plugin can only register and unregister commands using the purple::cmd Tcl command. However, without the ability to execute commands, it’s pretty pointless. So, here’s a patch to add the subcommands “do”, “help” and “list” to purple::cmd. I’ve submitted this as Ticket 2873.

If you’d like to try this out, here’s a Win32 build of tcl.dll for Pidgin 2.1.1 after applying this patch:

Just extract that into your Program Files\Pidgin\plugins directory, after making a backup copy of your old tcl.dll, of course.

If you have any questions about or concerns with this patch, let me know in the comments below. Thanks!

Tags: , ,

Pidgin IM patch for IRC 352 (who) parsing

Pidgin is a multi-protocol IM client (formerly known as “Gaim”) that is available on various platforms (Linux, Win32).

Recently, someone asked in #pidgin about a feature request to make libpurple parse the IRC 352 messages, which are returned in response to a WHO command. I said I could throw together a quick patch to make this happen and I’ve got something working now.

Currently, this is what a IRC chat in Pidgin might look like:

Pidgin IRC chat, before patch

After the patch, you can issue a “/quote who #channel” which will send the literal command “who #channel” to the IRC server, to which it will send the 352 response messages. My patch makes libpurple parse these messages and set the PURPLE_CBFLAGS_AWAY flag on the appropriate user’s PuprleConvChatBuddyFlags record. The result looks like this:

Pidgin IRC chat, after patch

You can now see user “Dossy_” is set away by the status icon (the clock, cirlcled in green in the screenshot).

Of course, there’s a few big caveats with this patch:

  • Only users set “away” who have no other meaningful PurpleConvChatBuddyFlags (i.e., chan op, voiced) will display the away status icon, as it has lowest precedence, since only one buddy status icon is displayed at a time. (See pidgin/gtkconv.c:get_chat_buddy_status_icon() to see what I mean.)
  • The server does not send regular status update notifications with 352 messages. It only sends them in response to a “who” command. Therefore, if you want the status data to be updated, you’ll need to periodically poll the server by issuing a “who” command. This is inefficient and for large IRC channels it can be quite resource intensive. If you want periodic updates, you’ll need to issue the “who” command manually, or write a Pidgin plugin that periodically polls by issuing the command for you.

Here’s the patch against the Pidgin 2.1.1 source tarball:

If you have any questions about or issues with the patch, leave them in the comments below.

Tags: , ,

August 27th NJ Hackfest

Five of us came out for this week’s Hackfest:

NJ Hackfest Meetup 2007-08-27

Left to right: Glenn M., Mike G., Steve G., Robbie the Geek

Tags: , ,

LOLduke says, “I CAN HAS VALUATION NOW?”

Jonathan Schwartz blogs that Sun is changing their trading symbol from SUNW to JAVA. This leaves me with only one thought …

OH HAI! I CAN HAS VALUATION NOW?

(In case you didn’t know, that’s Duke, Java’s mascot.)

Tags: , ,

del.icio.us/dossy links since August 20, 2007 at 09:00 AM

del.icio.us/dossy (RSS) links since August 20, 2007 at 09:00 AM:

Happy campers!

There aren’t many pictures up from MySQL Camp II yet, but Ronald uploaded one so here it is:

Drinks with the MySQL Campers

Do we have goofy grins on our faces? That’s because we had such a great time geeking out for two days straight, followed by beers!

Tags: , ,

Evaluate Tcl scripts as a UDF in MySQL

In the previous blog entry, I mentioned evaluating Tcl scripts from within MySQL using the User-Defined Function (UDF) capability already in MySQL. For example, it would allow you to do this:

CREATE FUNCTION TCL RETURNS STRING SONAME 'libtcl-mysql-udf.so';

SELECT TCL('expr {2 + 2}');

Well, after a few hours of productive coding and hacking, I want to share tcl-mysql-udf-0.1.tar.gz with you.

I’ve done very limited testing on this and on very little sleep, so I wholly expect there to be really stupid mistakes in there–but, it does “work” on my personal Debian 4.0 Linux and MySQL 5.1.20 setup with Tcl 8.4.12. If you want to play around with this, I strongly urge you to read over the README included in the tarball, as it should have all the relevant bits of information necessary to get you started.

A quick demonstration of what’s currently possible with this version:

mysql> SELECT TCL('info patchlevel') AS script;
+--------+
| script |
+--------+
| 8.4.12 |
+--------+
1 row in set (0.00 sec)

mysql> SELECT TCL('info commands') AS script \G
*************************** 1. row ***************************
script: tell socket subst open eof pwd glob list exec pid time eval lrange fblocked lsearch gets case lappend proc break variable llength return linsert error catch clock info split array if fconfigure concat join lreplace source fcopy global switch update close
1 row in set (0.00 sec)

Currently, Tcl errors result in the function returning NULL–I haven’t figured out how to propagate the error string back up, yet.

mysql> SELECT TCL('error foo') AS script;
+--------+
| script |
+--------+
| NULL   |
+--------+
1 row in set (0.01 sec)

Also, the maximum length string that the function can return is currently hard-coded to 255 characters.

mysql> SELECT LENGTH(TCL('string repeat x 1024')) AS script;
+--------+
| script |
+--------+
|    255 |
+--------+
1 row in set (0.07 sec)

I implemented the function as accepting a variable number of arguments, the first being the Tcl script, followed by values that get appended to the $args Tcl variable–as though it were a Tcl proc call, in a sense.

mysql> SELECT TCL('concat [llength $args] $args', 'abc', 123, NOW()) AS script;
+---------------------------------+
| script                          |
+---------------------------------+
| 3 abc 123 {2007-08-25 08:50:35} |
+---------------------------------+
1 row in set (0.05 sec)

If you’re familiar with Tcl and MySQL and aren’t afraid of compiling something and fooling around with it in your dev playground, I’d love to hear what you think of this code. Can you see any use for it? What else would it need to be able to do before it would be useful to you?

Tags: , , ,

No happiness using C-Store as a MySQL storage engine

As the second day of MySQL Camp II comes to an end, all my hacking on a new MySQL pluggable storage engine using C-Store meets a dead-end.

Chad Miller and I worked together to try and make this happen, but the C-Store C++ is just not written to be usable as a library within a larger application codebase. The C-Store 0.2 reference implementation’s C++ doesn’t come with even command-line programs to execute queries. It comes with a pretty comprehensive collection of automated unit tests, which is fantastic, but that’s the only executable it currently builds.

The bigger concern is whether the code is thread-safe, and the fact that the C-Store code requires C++ exceptions, I’m doubtful. If it isn’t thread-safe, it’ll make the C-Store reference implementation a non-starter for any serious work, which is unfortunate.

If I get more ambitious, maybe I’ll take a stab at a fresh implementation in fully thread-safe C, as a library to be embedded in other applications. I’m just sad right now because I was hoping to have this working to show off to the other campers, today.

Perhaps I’ll work on using Tcl as a User-Defined Function (UDF) inside MySQL–which I’m betting nobody would ever take seriously–just for laughs. I imagine making something like this possible:

CREATE FUNCTION TCL RETURNS STRING SONAME 'libtcl-mysql-udf.so';

SELECT TCL('expr {2 + 2}');

Whether there are actually interesting non-trivial uses of this remains to be seen, but at least it’ll allow folks to start playing with it, once it’s ready.

Tags: , ,

Is Vertica’s product just Sybase IQ?

Emmanuelle Skala (Sr. Director, Commercial Sales at Vertica) emailed me a heads-up this morning that Vertica Systems, Inc. earned an honorable mention for this year’s Computerworld Horizon Award.

I first heard and blogged about Vertica back in January 2005 and was very excited to see what Michael Stonebraker was going to introduce to the world this time. He’s pretty much the father of the modern relational database, having been a part of many companies in the industry throughout the years.

His latest work has been on C-Store, a “column-oriented DBMS” developed amongst the Massachusetts tech. universities. It is being released as open source software under one of my favorite licenses, the BSD license.

It’s exciting to finally see a column-oriented DBMS released as open source. The concept is nothing new.  Sybase IQ was doing this commercially over 10 years ago, before 1995 when it acquired Expressway:

Sybase IQ is based on technology that Sybase acquired when it purchased Expressway in 1995. However, it was not until the release of version 12.0 in 1999 that the product really came to its present level of maturity.

It’s clearly in the Sybase IQ documentation, “When you load data into a table, Sybase IQ stores data by column rather than by row, for each column in the table.” I’m guessing, without having looked at their implementation, that C-Store does things differently than IQ, but the underlying premise sounds the same.

Perhaps C-Store can be hooked up to MySQL as a pluggable storage engine. That could be very cool and possibly even useful! Maybe I’ll work on that this week at MySQL Camp II.

Tags: , , , , ,