拡張関数を使いMySQLのSQLコマンドでシェルを実行

CodeGen_MySQL_UDFでh-indexな集計関数の続きっぽいこと。

mysqlってSQLコマンドからシェルコマンドを実行できる関数って確かないような。
あったらあったでセキュリティ的にどうなの?と突っ込まれそうだけど、
mysql>insert into test(data) values(my_cmd('cat /tmp/hoge'));
とかできたら楽しそうじゃない(なにが?)

ってことで、CodeGen_MySQL_UDFを利用し、拡張関数でそれっぽいのを作ってみた。

なお、環境は、

(今回はMySQL5.1系。5.0でも可能なハズだがmakeで失敗した)
まず、udf-gen + makeでインストールまで。

# udf-gen my_cmd.xml
# cd ./my_cmd
# ./configure --libdir=/path/lib/mysql --with-mysql=/path/bin/mysql_config
# make clean;make;make install

mysqlクライアントからcreate function 及び 動作。

mysql> create function my_cmd returns string soname 'my_cmd.so';
mysql> select my_cmd('touch /tmp/aaaa');
+---------------------------+
| my_cmd('touch /tmp/aaaa') |
+---------------------------+
|                           |
+---------------------------+
1 row in set (0.01 sec)
mysql> select my_cmd('ls -all /tmp/aaaa');
+------------------------------------------------------+
| my_cmd('ls -all /tmp/aaaa')                          |
+------------------------------------------------------+
| -rw-rw---- 1 mysql mysql 0  8月  3 02:01 /tmp/aaaa   |
+------------------------------------------------------+
1 row in set (0.02 sec)

実際には my_cmd('cmd hogehoge 2>/dev/null') ってエラー出力を抑制してもいいのかな。

ソースコード
No.1229 バイナリファイルを全て読み込むを参考にした) [xml] <?xml version="1.0"?>

<![CDATA[ FILE fp; char buf, *nbuf; size_t s,p =0;

buf = (char *) calloc(1, BUFSIZ); if (!buf) { NULL; }

fp = popen(text, "r"); if (fp!=NULL) { while((s=fread(buf+p, 1, BUFSIZ, fp)) == BUFSIZ) { s = 0; p += BUFSIZ; nbuf = (char ) realloc(buf, p+BUFSIZ); if(!nbuf) break; buf = nbuf; } pclose(fp); } buf = (char ) realloc(buf, p+s+1); buf[p+s] = '\0';

RETURN_STRING(buf); ]]> [/xml]