{"id":1855,"date":"2010-03-17T18:02:34","date_gmt":"2010-03-17T08:02:34","guid":{"rendered":"http:\/\/www.flamingspork.com\/blog\/?p=1855"},"modified":"2014-10-08T09:16:07","modified_gmt":"2014-10-07T23:16:07","slug":"stored-proceduresfunctions-for-drizzle","status":"publish","type":"post","link":"https:\/\/www.flamingspork.com\/blog\/2010\/03\/17\/stored-proceduresfunctions-for-drizzle\/","title":{"rendered":"Stored Procedures\/Functions for Drizzle"},"content":{"rendered":"<p>Previously, in &#8220;<a href=\"http:\/\/www.flamingspork.com\/blog\/2010\/03\/15\/thoughts-on-thoughts-on-drizzle\/\">Thoughts on Thoughts on Drizzle<\/a>&#8221; I theorized that one of the major reasons why we did not see lots of people jumping at stored procedures in <a href=\"http:\/\/www.mysql.com\">MySQL<\/a> was that it wasn&#8217;t in their native language (for lack of a better term). We&#8217;ve seen <a href=\"http:\/\/web.archive.org\/web\/20120628125238\/http:\/\/forge.mysql.com:80\/wiki\/ProjectPage_External_Language_Stored_Procedures\">External Language Stored Procedures<\/a> for MySQL that let you write stored procedures in some other languages&#8230;. but I felt something was missing.<\/p>\n<p>Firstly, I wanted a language I was really familiar with and comfortable writing complex things in.<\/p>\n<p>Secondly, it should be compiled so that it runs as fast as possible.<\/p>\n<p>Thirdly, it shouldn&#8217;t just be linking to a pre-compiled library (drizzle function plugins do that already)<\/p>\n<p>So&#8230; the obvious choice was C.<\/p>\n<p>I have a really, really, really early prototype:<br \/>\n<code><br \/>\ndrizzle&gt; SELECT LIBTCC(\"int foo(char* s) { s[0]='4'; s[1]='2'; s[2]=0; return 2; }\") AS RESULT;<br \/>\n<\/code><\/p>\n<pre>+--------+\r\n| RESULT |\r\n+--------+\r\n| 42     |\r\n+--------+\r\n1 row in set (0 sec)<\/pre>\n<p>or&#8230; a bit more sophisticated:<br \/>\n<code><br \/>\ndrizzle&gt; SELECT LIBTCC(\"#include &lt;string.h&gt;\\nint foo(char* s) { strcpy(s,\\\"Hello World!\\\");; return strlen(s); }\") AS RESULT;<br \/>\n<\/code><\/p>\n<pre>+--------------+\r\n| RESULT       |\r\n+--------------+\r\n| Hello World! |\r\n+--------------+\r\n1 row in set (0 sec)<\/pre>\n<p>I&#8217;m using a function as a bit of a cheat&#8230; but the string is passed to <a href=\"http:\/\/bellard.org\/tcc\/\">libtcc<\/a> (modified so it&#8217;s a shared library so I can load it into <a href=\"http:\/\/www.drizzle.org\">drizzle<\/a>), where it is compiled into native object code (in my case x86-64) and then run.<\/p>\n<p>With the right bits of foo&#8230; I could allow calling of all sorts of server functions&#8230;. such as those to execute SQL inside the current transaction context.<\/p>\n<p>There are a number of reasons why this is Pure Evil(TM):<\/p>\n<ul>\n<li><strong>It executes inside the address space of your database server<\/strong><br \/>\none null pointer dereference and your database server is all gone.<\/li>\n<li>It&#8217;s <strong>arbitrary code injection<\/strong> by design<br \/>\nExactly how insane are you? Security&#8211;;<\/li>\n<li>While great for me and my C hacking friends, possibly not for web app developers, who likely aren&#8217;t writing their apps in C every day.<\/li>\n<li>See the first reason. Is that not reason enough? Memory protection is a <strong>good thing<\/strong> yo.<\/li>\n<\/ul>\n<p>Anyway, you can see the code up on launchpad in the <a href=\"https:\/\/code.launchpad.net\/~stewart\/drizzle\/drizzle-libtcc-function\">drizzle-libtcc-function<\/a> branch. You&#8217;ll need to modify your tcc source so that the Makefile snippet for libtcc.o looks like this:<\/p>\n<pre># libtcc generation and test\r\nlibtcc.o: $(NATIVE_FILES)\r\n        $(CC) -fPIC -o $@ -c libtcc.c $(NATIVE_TARGET) $(CFLAGS)\r\n\r\nlibtcc.a: libtcc.o\r\n        $(AR) rcs $@ $^\r\n\r\nlibtcc.so: libtcc.o\r\n        $(CC) -shared -Wl,-soname,libtcc.so.1 -o $@ libtcc.o<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Previously, in &#8220;Thoughts on Thoughts on Drizzle&#8221; I theorized that one of the major reasons why we did not see lots of people jumping at stored procedures in MySQL was that it wasn&#8217;t in their native language (for lack of &hellip; <a href=\"https:\/\/www.flamingspork.com\/blog\/2010\/03\/17\/stored-proceduresfunctions-for-drizzle\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[76,75,14],"tags":[138,70,262,264,260,261,263],"class_list":["post-1855","post","type-post","status-publish","format-standard","hentry","category-code","category-drizzle-work-et-al","category-mysql","tag-c","tag-drizzle","tag-evil","tag-libtcc","tag-stored-function","tag-stored-procedure","tag-tcc"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5a6n8-tV","jetpack-related-posts":[{"id":1847,"url":"https:\/\/www.flamingspork.com\/blog\/2010\/03\/15\/thoughts-on-thoughts-on-drizzle\/","url_meta":{"origin":1855,"position":0},"title":"Thoughts on Thoughts on Drizzle :)","author":"Stewart Smith","date":"2010-03-15","format":false,"excerpt":"Mark has some good thoughts on drizzle. I think they're all valid... and have some extra thoughts too: \"I have problems to solve today\". This is (of course) an active concern in my brain... If we don't have something out that solves some set of problems with reasonable stability and\u2026","rel":"","context":"In &quot;drizzle&quot;","block_context":{"text":"drizzle","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/drizzle-work-et-al\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1409,"url":"https:\/\/www.flamingspork.com\/blog\/2009\/02\/20\/improving-the-storage-engine-api\/","url_meta":{"origin":1855,"position":1},"title":"Improving the Storage Engine &#8220;API&#8221;","author":"Stewart Smith","date":"2009-02-20","format":false,"excerpt":"I increasingly enclose the API part of \"Storage Engine API\" in quotes as it does score a rather large number on the API Design Rusty levels (Coined by Rusty Russell). I give it a 15 (out of 18. lower is better) in this case \"The obvious use is wrong\". The\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1738,"url":"https:\/\/www.flamingspork.com\/blog\/2009\/10\/14\/return-of-the-top-5-mysql-wishlist-and-looking-at-drizzle\/","url_meta":{"origin":1855,"position":2},"title":"Return of the &#8220;Top 5 MySQL Wishlist&#8221; and looking at Drizzle","author":"Stewart Smith","date":"2009-10-14","format":false,"excerpt":"It's coming up on a year since I started working full time on Drizzle. So, I got a bit reflective... Have we done things that I (and others) really wanted done? Back in 2007, I wrote my top 5 wishlist for the MySQL Server. I am not going to pretend\u2026","rel":"","context":"In &quot;drizzle&quot;","block_context":{"text":"drizzle","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/drizzle-work-et-al\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1879,"url":"https:\/\/www.flamingspork.com\/blog\/2010\/05\/24\/using-the-row-buffer-in-drizzle-and-mysql\/","url_meta":{"origin":1855,"position":3},"title":"Using the row buffer in Drizzle (and MySQL)","author":"Stewart Smith","date":"2010-05-24","format":false,"excerpt":"Here's another bit of the API you may need to use in your storage engine (it also seems to be a rather unknown. I believe the only place where this has really been documented is ha_ndbcluster.cc, so here goes.... Drizzle (through inheritance from MySQL) has its own (in memory) row\u2026","rel":"","context":"In &quot;drizzle&quot;","block_context":{"text":"drizzle","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/drizzle-work-et-al\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.flamingspork.com\/blog\/wp-content\/uploads\/2010\/04\/row-300x85.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1650,"url":"https:\/\/www.flamingspork.com\/blog\/2009\/05\/27\/pluggable-metadata-stores-or-the-revenge-of-table-discovery\/","url_meta":{"origin":1855,"position":4},"title":"Pluggable Metadata stores (or&#8230; the revenge of table discovery)","author":"Stewart Smith","date":"2009-05-27","format":false,"excerpt":"Users of the ARCHIVE or NDB storage engines in MySQL may be aware of a MySQL feature known as \"table discovery\". For ARCHIVE, you can copy the archive data file around between servers and it magically works (you don't need to copy the FRM). For MySQL Cluster (NDB) it works\u2026","rel":"","context":"In &quot;drizzle&quot;","block_context":{"text":"drizzle","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/drizzle-work-et-al\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1860,"url":"https:\/\/www.flamingspork.com\/blog\/2010\/03\/17\/a-md5-stored-procedure-for-drizzle-in-c\/","url_meta":{"origin":1855,"position":5},"title":"A MD5 stored procedure for Drizzle&#8230; in C","author":"Stewart Smith","date":"2010-03-17","format":false,"excerpt":"So, just in case that wasn't evil enough for you... perhaps you have something you want to know the MD5 checksum of. So, you could just do this: drizzle> select md5('Hello World!'); +----------------------------------+ | md5('Hello World!') | +----------------------------------+ | ed076287532e86365e841e92bfc50d8c | +----------------------------------+ 1 row in set (0 sec) But that\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/1855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/comments?post=1855"}],"version-history":[{"count":7,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/1855\/revisions"}],"predecessor-version":[{"id":3834,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/1855\/revisions\/3834"}],"wp:attachment":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/media?parent=1855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/categories?post=1855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/tags?post=1855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}