Below is the list of changes that have just been committed into a local
5.1 repository of antony. When antony does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-22 17:05:36-08:00, antony@stripped +149 -0
backport from 6.0-wl820 tree
BUILD/autorun.sh@stripped, 2008-02-22 17:05:04-08:00, antony@stripped +11 -0
backport from 6.0-wl820 tree
BUILD/compile-amd64-debug@stripped, 2008-02-22 17:05:28-08:00, antony@stripped +12 -0
New BitKeeper file ``BUILD/compile-amd64-debug''
BUILD/compile-amd64-debug@stripped, 2008-02-22 17:05:28-08:00, antony@stripped +0 -0
config/ac-macros/compiler_flag.m4@stripped, 2008-02-22 17:05:04-08:00, antony@stripped +22 -0
backport from 6.0-wl820 tree
config/ac-macros/java.m4@stripped, 2008-02-22 17:05:28-08:00, antony@stripped +477 -0
New BitKeeper file ``config/ac-macros/java.m4''
config/ac-macros/java.m4@stripped, 2008-02-22 17:05:28-08:00, antony@stripped +0 -0
configure.in@stripped, 2008-02-22 17:05:03-08:00, antony@stripped +3 -0
backport from 6.0-wl820 tree
include/mysql.h@stripped, 2008-02-22 17:05:04-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
include/mysql/plugin.h@stripped, 2008-02-22 17:05:04-08:00, antony@stripped +128 -1
backport from 6.0-wl820 tree
libmysqld/Makefile.am@stripped, 2008-02-22 17:05:04-08:00, antony@stripped +1 -0
backport from 6.0-wl820 tree
libmysqld/emb_qcache.cc@stripped, 2008-02-22 17:05:05-08:00, antony@stripped +3 -3
backport from 6.0-wl820 tree
libmysqld/lib_sql.cc@stripped, 2008-02-22 17:05:05-08:00, antony@stripped +36 -29
backport from 6.0-wl820 tree
mysql-test/include/have_psmexample_plugin.inc@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +16 -0
New BitKeeper file ``mysql-test/include/have_psmexample_plugin.inc''
mysql-test/include/have_psmexample_plugin.inc@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +0 -0
mysql-test/include/have_psmjava_plugin.inc@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +4 -0
New BitKeeper file ``mysql-test/include/have_psmjava_plugin.inc''
mysql-test/include/have_psmjava_plugin.inc@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +0 -0
mysql-test/include/have_psmperl_plugin.inc@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +4 -0
New BitKeeper file ``mysql-test/include/have_psmperl_plugin.inc''
mysql-test/include/have_psmperl_plugin.inc@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +0 -0
mysql-test/mysql-test-run.pl@stripped, 2008-02-22 17:05:05-08:00, antony@stripped +43 -0
backport from 6.0-wl820 tree
mysql-test/r/have_psmexample_plugin.require@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +2 -0
New BitKeeper file ``mysql-test/r/have_psmexample_plugin.require''
mysql-test/r/have_psmexample_plugin.require@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +0 -0
mysql-test/r/information_schema.result@stripped, 2008-02-22 17:05:05-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
mysql-test/r/plugin_psm.result@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +11 -0
New BitKeeper file ``mysql-test/r/plugin_psm.result''
mysql-test/r/plugin_psm.result@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +0 -0
mysql-test/r/plugin_psm_java.result@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +17 -0
New BitKeeper file ``mysql-test/r/plugin_psm_java.result''
mysql-test/r/plugin_psm_java.result@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +0 -0
mysql-test/r/plugin_psm_perl.result@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +91 -0
New BitKeeper file ``mysql-test/r/plugin_psm_perl.result''
mysql-test/r/plugin_psm_perl.result@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/r/plugin_psm_perl_dbi.result@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +12 -0
New BitKeeper file ``mysql-test/r/plugin_psm_perl_dbi.result''
mysql-test/r/plugin_psm_perl_dbi.result@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/r/system_mysql_db.result@stripped, 2008-02-22 17:05:05-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
mysql-test/t/plugin_psm-master.opt@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +1 -0
New BitKeeper file ``mysql-test/t/plugin_psm-master.opt''
mysql-test/t/plugin_psm-master.opt@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm.test@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +16 -0
New BitKeeper file ``mysql-test/t/plugin_psm.test''
mysql-test/t/plugin_psm.test@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm_java-master.opt@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +3 -0
New BitKeeper file ``mysql-test/t/plugin_psm_java-master.opt''
mysql-test/t/plugin_psm_java-master.opt@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm_java.test@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +27 -0
New BitKeeper file ``mysql-test/t/plugin_psm_java.test''
mysql-test/t/plugin_psm_java.test@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm_perl-master.opt@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +3 -0
New BitKeeper file ``mysql-test/t/plugin_psm_perl-master.opt''
mysql-test/t/plugin_psm_perl-master.opt@stripped, 2008-02-22 17:05:12-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm_perl.test@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +88 -0
New BitKeeper file ``mysql-test/t/plugin_psm_perl.test''
mysql-test/t/plugin_psm_perl.test@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm_perl_dbi-master.opt@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +3 -0
New BitKeeper file ``mysql-test/t/plugin_psm_perl_dbi-master.opt''
mysql-test/t/plugin_psm_perl_dbi-master.opt@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +0 -0
mysql-test/t/plugin_psm_perl_dbi.test@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +30 -0
New BitKeeper file ``mysql-test/t/plugin_psm_perl_dbi.test''
mysql-test/t/plugin_psm_perl_dbi.test@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +0 -0
plugin/example_udf/Makefile.am@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +58 -0
New BitKeeper file ``plugin/example_udf/Makefile.am''
plugin/example_udf/Makefile.am@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +0 -0
plugin/example_udf/plug.in@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +4 -0
New BitKeeper file ``plugin/example_udf/plug.in''
plugin/example_udf/plug.in@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +0 -0
plugin/example_udf/psm_example.c@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +337 -0
New BitKeeper file ``plugin/example_udf/psm_example.c''
plugin/example_udf/psm_example.c@stripped, 2008-02-22 17:05:13-08:00, antony@stripped +0 -0
plugin/java_udf/Makefile.am@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +143 -0
New BitKeeper file ``plugin/java_udf/Makefile.am''
plugin/java_udf/Makefile.am@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/Makefile.eric@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +133 -0
New BitKeeper file ``plugin/java_udf/Makefile.eric''
plugin/java_udf/Makefile.eric@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/jnitest/TestObject.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +110 -0
New BitKeeper file ``plugin/java_udf/com/mysql/jnitest/TestObject.java''
plugin/java_udf/com/mysql/jnitest/TestObject.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/Context.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +15 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/Context.java''
plugin/java_udf/com/mysql/udf/Context.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/DataMarshal.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +247 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/DataMarshal.java''
plugin/java_udf/com/mysql/udf/DataMarshal.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/FunctionDescriptor.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +132 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/FunctionDescriptor.java''
plugin/java_udf/com/mysql/udf/FunctionDescriptor.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/InternalType.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +57 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/InternalType.java''
plugin/java_udf/com/mysql/udf/InternalType.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/Invoker.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +40 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/Invoker.java''
plugin/java_udf/com/mysql/udf/Invoker.java@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/LifeCycle.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +7 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/LifeCycle.java''
plugin/java_udf/com/mysql/udf/LifeCycle.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/MysqlIOtype2.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +205 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/MysqlIOtype2.java''
plugin/java_udf/com/mysql/udf/MysqlIOtype2.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/NativeRow.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +123 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/NativeRow.java''
plugin/java_udf/com/mysql/udf/NativeRow.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/NativeRowData.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +95 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/NativeRowData.java''
plugin/java_udf/com/mysql/udf/NativeRowData.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/NativeUDFCallback.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +192 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/NativeUDFCallback.java''
plugin/java_udf/com/mysql/udf/NativeUDFCallback.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/ParameterClassFinder.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +32 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/ParameterClassFinder.java''
plugin/java_udf/com/mysql/udf/ParameterClassFinder.java@stripped, 2008-02-22 17:05:20-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/ParsedFunction.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +110 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/ParsedFunction.java''
plugin/java_udf/com/mysql/udf/ParsedFunction.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/UDFCallback.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +42 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/UDFCallback.java''
plugin/java_udf/com/mysql/udf/UDFCallback.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/UDFException.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +20 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/UDFException.java''
plugin/java_udf/com/mysql/udf/UDFException.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/UDFModule.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +41 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/UDFModule.java''
plugin/java_udf/com/mysql/udf/UDFModule.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/example/PigLatin.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +111 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/example/PigLatin.java''
plugin/java_udf/com/mysql/udf/example/PigLatin.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/example/Primes.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +43 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/example/Primes.java''
plugin/java_udf/com/mysql/udf/example/Primes.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/example/Reverse.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +14 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/example/Reverse.java''
plugin/java_udf/com/mysql/udf/example/Reverse.java@stripped, 2008-02-22 17:05:21-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/Exploder.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +9 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/Exploder.java''
plugin/java_udf/com/mysql/udf/test/Exploder.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/FunctionDescriptorTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +23 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/FunctionDescriptorTest.java''
plugin/java_udf/com/mysql/udf/test/FunctionDescriptorTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/InvokerTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +52 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/InvokerTest.java''
plugin/java_udf/com/mysql/udf/test/InvokerTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/JniSimulationTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +136 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/JniSimulationTest.java''
plugin/java_udf/com/mysql/udf/test/JniSimulationTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/ParameterClassFinderTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +33 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/ParameterClassFinderTest.java''
plugin/java_udf/com/mysql/udf/test/ParameterClassFinderTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/ParsedFunctionTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +59 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/ParsedFunctionTest.java''
plugin/java_udf/com/mysql/udf/test/ParsedFunctionTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/PigLatinTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +39 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/PigLatinTest.java''
plugin/java_udf/com/mysql/udf/test/PigLatinTest.java@stripped, 2008-02-22 17:05:22-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/PrimesTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +69 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/PrimesTest.java''
plugin/java_udf/com/mysql/udf/test/PrimesTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/QuickAffirmationsTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +78 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/QuickAffirmationsTest.java''
plugin/java_udf/com/mysql/udf/test/QuickAffirmationsTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/ReverseTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +19 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/ReverseTest.java''
plugin/java_udf/com/mysql/udf/test/ReverseTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/TestCallback.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +144 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/TestCallback.java''
plugin/java_udf/com/mysql/udf/test/TestCallback.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/TestFunction.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +16 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/TestFunction.java''
plugin/java_udf/com/mysql/udf/test/TestFunction.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/UDFModuleTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +32 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/UDFModuleTest.java''
plugin/java_udf/com/mysql/udf/test/UDFModuleTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/example/PigLatinTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +39 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/example/PigLatinTest.java''
plugin/java_udf/com/mysql/udf/test/example/PigLatinTest.java@stripped, 2008-02-22 17:05:23-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/example/PrimesTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +69 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/example/PrimesTest.java''
plugin/java_udf/com/mysql/udf/test/example/PrimesTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/example/ReverseTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +19 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/example/ReverseTest.java''
plugin/java_udf/com/mysql/udf/test/example/ReverseTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/util/MiscTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +22 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/util/MiscTest.java''
plugin/java_udf/com/mysql/udf/test/util/MiscTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/test/util/SimpleResultSetTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +55 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/test/util/SimpleResultSetTest.java''
plugin/java_udf/com/mysql/udf/test/util/SimpleResultSetTest.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/util/Misc.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +49 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/util/Misc.java''
plugin/java_udf/com/mysql/udf/util/Misc.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/util/NotImplementedException.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +41 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/util/NotImplementedException.java''
plugin/java_udf/com/mysql/udf/util/NotImplementedException.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/util/SimpleResultSet.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +150 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/util/SimpleResultSet.java''
plugin/java_udf/com/mysql/udf/util/SimpleResultSet.java@stripped, 2008-02-22 17:05:24-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/util/ThrowingResultSet.java@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +822 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/util/ThrowingResultSet.java''
plugin/java_udf/com/mysql/udf/util/ThrowingResultSet.java@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/java_udf/com/mysql/udf/util/ThrowingResultSetMetaData.java@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +92 -0
New BitKeeper file ``plugin/java_udf/com/mysql/udf/util/ThrowingResultSetMetaData.java''
plugin/java_udf/com/mysql/udf/util/ThrowingResultSetMetaData.java@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/java_udf/grokjni.pl@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +25 -0
New BitKeeper file ``plugin/java_udf/grokjni.pl''
plugin/java_udf/grokjni.pl@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/java_context.cc@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +1193 -0
New BitKeeper file ``plugin/java_udf/java_context.cc''
plugin/java_udf/java_context.cc@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/java_context.h@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +170 -0
New BitKeeper file ``plugin/java_udf/java_context.h''
plugin/java_udf/java_context.h@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/java_context_test.cc@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +588 -0
New BitKeeper file ``plugin/java_udf/java_context_test.cc''
plugin/java_udf/java_context_test.cc@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/java_object_parameter.cc@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +10 -0
New BitKeeper file ``plugin/java_udf/java_object_parameter.cc''
plugin/java_udf/java_object_parameter.cc@stripped, 2008-02-22 17:05:14-08:00, antony@stripped +0 -0
plugin/java_udf/java_object_parameter.h@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +16 -0
New BitKeeper file ``plugin/java_udf/java_object_parameter.h''
plugin/java_udf/java_object_parameter.h@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/java_udf.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +303 -0
New BitKeeper file ``plugin/java_udf/java_udf.cc''
plugin/java_udf/java_udf.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/java_util_arraylist.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +33 -0
New BitKeeper file ``plugin/java_udf/java_util_arraylist.cc''
plugin/java_udf/java_util_arraylist.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/java_util_arraylist.h@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +23 -0
New BitKeeper file ``plugin/java_udf/java_util_arraylist.h''
plugin/java_udf/java_util_arraylist.h@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/jbyte_array.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +45 -0
New BitKeeper file ``plugin/java_udf/jbyte_array.cc''
plugin/java_udf/jbyte_array.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/jbyte_array.h@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +27 -0
New BitKeeper file ``plugin/java_udf/jbyte_array.h''
plugin/java_udf/jbyte_array.h@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/jbyte_array_test.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +81 -0
New BitKeeper file ``plugin/java_udf/jbyte_array_test.cc''
plugin/java_udf/jbyte_array_test.cc@stripped, 2008-02-22 17:05:15-08:00, antony@stripped +0 -0
plugin/java_udf/jnicallback.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +244 -0
New BitKeeper file ``plugin/java_udf/jnicallback.cc''
plugin/java_udf/jnicallback.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jniutils.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +25 -0
New BitKeeper file ``plugin/java_udf/jniutils.cc''
plugin/java_udf/jniutils.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jniutils.h@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +25 -0
New BitKeeper file ``plugin/java_udf/jniutils.h''
plugin/java_udf/jniutils.h@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jobject_wrapper.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +30 -0
New BitKeeper file ``plugin/java_udf/jobject_wrapper.cc''
plugin/java_udf/jobject_wrapper.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jobject_wrapper.h@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +26 -0
New BitKeeper file ``plugin/java_udf/jobject_wrapper.h''
plugin/java_udf/jobject_wrapper.h@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jvm_interface.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +10 -0
New BitKeeper file ``plugin/java_udf/jvm_interface.cc''
plugin/java_udf/jvm_interface.cc@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jvm_interface.h@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +23 -0
New BitKeeper file ``plugin/java_udf/jvm_interface.h''
plugin/java_udf/jvm_interface.h@stripped, 2008-02-22 17:05:16-08:00, antony@stripped +0 -0
plugin/java_udf/jvm_options.cnf.in@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +2 -0
New BitKeeper file ``plugin/java_udf/jvm_options.cnf.in''
plugin/java_udf/jvm_options.cnf.in@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +0 -0
plugin/java_udf/jvm_singleton.cc@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +60 -0
New BitKeeper file ``plugin/java_udf/jvm_singleton.cc''
plugin/java_udf/jvm_singleton.cc@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +0 -0
plugin/java_udf/jvm_singleton.h@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +25 -0
New BitKeeper file ``plugin/java_udf/jvm_singleton.h''
plugin/java_udf/jvm_singleton.h@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +0 -0
plugin/java_udf/jvm_singleton_test.cc@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +19 -0
New BitKeeper file ``plugin/java_udf/jvm_singleton_test.cc''
plugin/java_udf/jvm_singleton_test.cc@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +0 -0
plugin/java_udf/makejars.sh@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +19 -0
New BitKeeper file ``plugin/java_udf/makejars.sh''
plugin/java_udf/makejars.sh@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +0 -0
plugin/java_udf/mysql-connector-java-6.0-nightly-bin.jar@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +15463 -0
New BitKeeper file ``plugin/java_udf/mysql-connector-java-6.0-nightly-bin.jar''
plugin/java_udf/mysql-connector-java-6.0-nightly-bin.jar@stripped, 2008-02-22 17:05:17-08:00, antony@stripped +0 -0
plugin/java_udf/native_jvm.cc@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +113 -0
New BitKeeper file ``plugin/java_udf/native_jvm.cc''
plugin/java_udf/native_jvm.cc@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +0 -0
plugin/java_udf/native_jvm.h@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +27 -0
New BitKeeper file ``plugin/java_udf/native_jvm.h''
plugin/java_udf/native_jvm.h@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +0 -0
plugin/java_udf/native_jvm_test.cc@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +18 -0
New BitKeeper file ``plugin/java_udf/native_jvm_test.cc''
plugin/java_udf/native_jvm_test.cc@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +0 -0
plugin/java_udf/plug.in@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +37 -0
New BitKeeper file ``plugin/java_udf/plug.in''
plugin/java_udf/plug.in@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +0 -0
plugin/java_udf/test_utils.cc@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +86 -0
New BitKeeper file ``plugin/java_udf/test_utils.cc''
plugin/java_udf/test_utils.cc@stripped, 2008-02-22 17:05:18-08:00, antony@stripped +0 -0
plugin/java_udf/test_utils.h@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +36 -0
New BitKeeper file ``plugin/java_udf/test_utils.h''
plugin/java_udf/test_utils.h@stripped, 2008-02-22 17:05:19-08:00, antony@stripped +0 -0
plugin/legacy_udf/Makefile.am@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +44 -0
New BitKeeper file ``plugin/legacy_udf/Makefile.am''
plugin/legacy_udf/Makefile.am@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/legacy_udf/plug.in@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +4 -0
New BitKeeper file ``plugin/legacy_udf/plug.in''
plugin/legacy_udf/plug.in@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/legacy_udf/psm_udf.c@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +586 -0
New BitKeeper file ``plugin/legacy_udf/psm_udf.c''
plugin/legacy_udf/psm_udf.c@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/perl_udf/Makefile.am@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +62 -0
New BitKeeper file ``plugin/perl_udf/Makefile.am''
plugin/perl_udf/Makefile.am@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/perl_udf/MyDBIExample.pm@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +98 -0
New BitKeeper file ``plugin/perl_udf/MyDBIExample.pm''
plugin/perl_udf/MyDBIExample.pm@stripped, 2008-02-22 17:05:25-08:00, antony@stripped +0 -0
plugin/perl_udf/MySQLUDF.pm@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +408 -0
New BitKeeper file ``plugin/perl_udf/MySQLUDF.pm''
plugin/perl_udf/MySQLUDF.pm@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/MyUDFExample.pm@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +218 -0
New BitKeeper file ``plugin/perl_udf/MyUDFExample.pm''
plugin/perl_udf/MyUDFExample.pm@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/configure.in@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +57 -0
New BitKeeper file ``plugin/perl_udf/configure.in''
plugin/perl_udf/configure.in@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/perl_init.cc@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +65 -0
New BitKeeper file ``plugin/perl_udf/perl_init.cc''
plugin/perl_udf/perl_init.cc@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/perl_init.h@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +19 -0
New BitKeeper file ``plugin/perl_udf/perl_init.h''
plugin/perl_udf/perl_init.h@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/perl_udf.xs@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +665 -0
New BitKeeper file ``plugin/perl_udf/perl_udf.xs''
plugin/perl_udf/perl_udf.xs@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/plug.in@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +43 -0
New BitKeeper file ``plugin/perl_udf/plug.in''
plugin/perl_udf/plug.in@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/perl_udf/typemap@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +53 -0
New BitKeeper file ``plugin/perl_udf/typemap''
plugin/perl_udf/typemap@stripped, 2008-02-22 17:05:26-08:00, antony@stripped +0 -0
plugin/xmlrpc_udf/Makefile.am@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +43 -0
New BitKeeper file ``plugin/xmlrpc_udf/Makefile.am''
plugin/xmlrpc_udf/Makefile.am@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +0 -0
plugin/xmlrpc_udf/plug.in@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +75 -0
New BitKeeper file ``plugin/xmlrpc_udf/plug.in''
plugin/xmlrpc_udf/plug.in@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +0 -0
plugin/xmlrpc_udf/xmlrpc.c@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +1318 -0
New BitKeeper file ``plugin/xmlrpc_udf/xmlrpc.c''
plugin/xmlrpc_udf/xmlrpc.c@stripped, 2008-02-22 17:05:27-08:00, antony@stripped +0 -0
scripts/mysql_system_tables.sql@stripped, 2008-02-22 17:05:06-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
scripts/mysql_system_tables_fix.sql@stripped, 2008-02-22 17:05:06-08:00, antony@stripped +1 -0
backport from 6.0-wl820 tree
sql-common/client.c@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +32 -0
backport from 6.0-wl820 tree
sql/Makefile.am@stripped, 2008-02-22 17:05:06-08:00, antony@stripped +2 -1
backport from 6.0-wl820 tree
sql/handler.cc@stripped, 2008-02-22 17:05:06-08:00, antony@stripped +5 -2
backport from 6.0-wl820 tree
sql/lex.h@stripped, 2008-02-22 17:05:06-08:00, antony@stripped +6 -0
backport from 6.0-wl820 tree
sql/lock.cc@stripped, 2008-02-22 17:05:07-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
sql/log_event.h@stripped, 2008-02-22 17:05:07-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
sql/mysql_priv.h@stripped, 2008-02-22 17:05:07-08:00, antony@stripped +8 -5
backport from 6.0-wl820 tree
sql/protocol.cc@stripped, 2008-02-22 17:05:07-08:00, antony@stripped +52 -54
backport from 6.0-wl820 tree
sql/protocol.h@stripped, 2008-02-22 17:05:07-08:00, antony@stripped +161 -29
backport from 6.0-wl820 tree
sql/set_var.cc@stripped, 2008-02-22 17:05:08-08:00, antony@stripped +2 -2
backport from 6.0-wl820 tree
sql/sp.cc@stripped, 2008-02-22 17:05:08-08:00, antony@stripped +31 -1
backport from 6.0-wl820 tree
sql/sp_external.cc@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +2546 -0
New BitKeeper file ``sql/sp_external.cc''
sql/sp_external.cc@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +0 -0
sql/sp_external.h@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +104 -0
New BitKeeper file ``sql/sp_external.h''
sql/sp_external.h@stripped, 2008-02-22 17:05:11-08:00, antony@stripped +0 -0
sql/sp_head.cc@stripped, 2008-02-22 17:05:08-08:00, antony@stripped +30 -2
backport from 6.0-wl820 tree
sql/sp_rcontext.h@stripped, 2008-02-22 17:05:08-08:00, antony@stripped +1 -0
backport from 6.0-wl820 tree
sql/sql_class.cc@stripped, 2008-02-22 17:05:08-08:00, antony@stripped +25 -4
backport from 6.0-wl820 tree
sql/sql_class.h@stripped, 2008-02-22 17:05:09-08:00, antony@stripped +69 -37
backport from 6.0-wl820 tree
sql/sql_lex.h@stripped, 2008-02-22 17:05:09-08:00, antony@stripped +2 -0
backport from 6.0-wl820 tree
sql/sql_parse.cc@stripped, 2008-02-22 17:05:09-08:00, antony@stripped +4 -3
backport from 6.0-wl820 tree
sql/sql_plugin.cc@stripped, 2008-02-22 17:05:09-08:00, antony@stripped +107 -44
backport from 6.0-wl820 tree
sql/sql_plugin.h@stripped, 2008-02-22 17:05:10-08:00, antony@stripped +1 -1
backport from 6.0-wl820 tree
sql/sql_prepare.cc@stripped, 2008-02-22 17:05:10-08:00, antony@stripped +6 -6
backport from 6.0-wl820 tree
sql/sql_string.h@stripped, 2008-02-22 17:05:10-08:00, antony@stripped +1 -0
backport from 6.0-wl820 tree
sql/sql_yacc.yy@stripped, 2008-02-22 17:05:10-08:00, antony@stripped +181 -12
backport from 6.0-wl820 tree
diff -Nrup a/BUILD/autorun.sh b/BUILD/autorun.sh
--- a/BUILD/autorun.sh 2007-10-29 14:48:18 -07:00
+++ b/BUILD/autorun.sh 2008-02-22 17:05:04 -08:00
@@ -20,6 +20,17 @@ do
done
IFS="$save_ifs"
+if test -d "plugin/perl_udf"; then
+( cd plugin/perl_udf
+ aclocal || die "Can't execute aclocal"
+ # --force means overwrite ltmain.sh script if it already exists
+ $LIBTOOLIZE --automake --force --copy || die "Can't execute libtoolize"
+ # --add-missing instructs automake to install missing auxiliary files
+ # and --force to overwrite them if they already exist
+ automake --add-missing --force --copy || die "Can't execute automake"
+ autoconf || die "Can't execute autoconf" ;)
+fi
+
aclocal || die "Can't execute aclocal"
autoheader || die "Can't execute autoheader"
# --force means overwrite ltmain.sh script if it already exists
diff -Nrup a/BUILD/compile-amd64-debug b/BUILD/compile-amd64-debug
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/BUILD/compile-amd64-debug 2008-02-22 17:05:28 -08:00
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+path=`dirname $0`
+set -- "$@" --with-debug=full
+. "$path/SETUP.sh"
+
+extra_flags="$amd64_cflags $debug_cflags"
+extra_configs="$amd64_configs $debug_configs $static_link"
+
+extra_configs="$extra_configs "
+CC="$CC --pipe"
+. "$path/FINISH.sh"
diff -Nrup a/config/ac-macros/compiler_flag.m4 b/config/ac-macros/compiler_flag.m4
--- a/config/ac-macros/compiler_flag.m4 2007-05-27 14:16:56 -07:00
+++ b/config/ac-macros/compiler_flag.m4 2008-02-22 17:05:04 -08:00
@@ -60,3 +60,25 @@ EOF
CCASFLAGS="$CCASFLAGS -Wa,--noexecstack"
fi
])
+
+AC_DEFUN([AC_CHECK_C_WEAK_SUPPORT],
+[
+ AC_CACHE_CHECK([for weak function attribute support],
+ mysql_cv_weak_attribute,[
+ mysql_cv_weak_attribute=no
+ AC_TRY_LINK([extern void foobaritus() __attribute__ ((weak));],
+ [foobaritus();], [mysql_cv_weak_attribute=gcc],[
+ AC_TRY_LINK([extern void foobaritus();
+#pragma weak foobaritus],
+ [foobaritus();], [mysql_cv_weak_attribute=pragma])
+ ])
+ ])
+ case "$mysql_cv_weak_attribute" in
+ gcc)
+ AC_DEFINE([HAVE_CC_WEAK_ATTRIBUTE], [1], [GCC style weak attribute support])
+ ;;
+ pragma)
+ AC_DEFINE([HAVE_CC_WEAK_PRAGMA], [1], [Pragma style weak attribute support])
+ ;;
+ esac
+])
diff -Nrup a/config/ac-macros/java.m4 b/config/ac-macros/java.m4
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/config/ac-macros/java.m4 2008-02-22 17:05:28 -08:00
@@ -0,0 +1,477 @@
+dnl ===========================================================================
+dnl Autoconf Support for Java
+dnl ===========================================================================
+
+
+AC_DEFUN([AC_CHECK_JAVA_HOME], [
+ AC_REQUIRE([AC_EXEEXT])
+
+ AC_CACHE_CHECK([for JAVA_HOME environment], ac_cv_java_home_env,[
+ if test -z "$JAVA_HOME"; then
+ ac_cv_java_home_env="no"
+ else
+ ac_cv_java_home_env="$JAVA_HOME"
+ fi
+ ])
+
+ if test "$ac_cv_java_home_env" = no; then
+ AC_PATH_PROG([JAVAC_PATH],[javac$EXEEXT],[no])
+ if test "$JAVAC_PATH" != "no"; then
+ JAVA_HOME="$JAVAC_PATH";
+
+ # Unwind symlinks found. This can experience infinite loop
+ # so we throw in a sleep so that it won't be a cpu hog.
+
+ while test -L "$JAVA_HOME"; do
+ sleep 1
+ JAVA_HOME="`readlink -n "$JAVA_HOME"`"
+ done
+
+ JAVA_HOME="`$ECHO -n "$JAVA_HOME" | sed 's%/[[^/]]*/[[^/]]*$%%'`"
+ fi
+ else
+ JAVA_HOME="$ac_cv_java_home_env"
+ fi
+
+ AC_SUBST(JAVA_HOME)
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_CHECK_JAVA_VENDOR], [
+ AC_REQUIRE([AC_CHECK_JAVA_HOME])
+
+ AC_CACHE_CHECK([style of JDK environment], ac_cv_java_style,[
+ ac_cv_java_style="unknown"
+ if test -d "$JAVA_HOME/../Commands" -a \
+ -d "$JAVA_HOME/../Headers" -a \
+ -d "$JAVA_HOME/../Libraries"; then
+ ac_cv_java_style="Apple"
+ elif test -d "$JAVA_HOME/Commands" -a \
+ -d "$JAVA_HOME/Headers" -a \
+ -d "$JAVA_HOME/Libraries"; then
+ ac_cv_java_style="Apple"
+ elif test -d "$JAVA_HOME/../CurrentJDK/Commands" -a \
+ -d "$JAVA_HOME/../CurrentJDK/Headers" -a \
+ -d "$JAVA_HOME/../CurrentJDK/Libraries"; then
+ ac_cv_java_style="Apple"
+ elif test -d "$JAVA_HOME/bin" -a \
+ -d "$JAVA_HOME/include"; then
+ if test -d "$JAVA_HOME/jre/lib"; then
+ ac_cv_java_style="Sun"
+ elif test -d "$JAVA_HOME/jre/bin"; then
+ ac_cv_java_style="IBM"
+ fi
+ fi
+ ])
+
+ case "$ac_cv_java_style" in
+ IBM)
+ JAVA_BIN="$JAVA_HOME/bin"
+ JAVA_INC="$JAVA_HOME/include"
+ JAVA_LIB="$JAVA_HOME/jre/bin"
+ ;;
+ Sun)
+ JAVA_BIN="$JAVA_HOME/bin"
+ JAVA_INC="$JAVA_HOME/include"
+ JAVA_LIB="$JAVA_HOME/jre/lib"
+ ;;
+ Apple)
+ if test -d "$JAVA_HOME/Commands" -a \
+ -d "$JAVA_HOME/Headers" -a \
+ -d "$JAVA_HOME/Libraries"; then
+ JAVA_BIN="$JAVA_HOME/Commands"
+ JAVA_INC="$JAVA_HOME/Headers"
+ JAVA_LIB="$JAVA_HOME/Libraries"
+ elif test -d "$JAVA_HOME/../CurrentJDK/Commands" -a \
+ -d "$JAVA_HOME/../CurrentJDK/Headers" -a \
+ -d "$JAVA_HOME/../CurrentJDK/Libraries"; then
+ JAVA_BIN="$JAVA_HOME/../CurrentJDK/Commands"
+ JAVA_INC="$JAVA_HOME/../CurrentJDK/Headers"
+ JAVA_LIB="$JAVA_HOME/../CurrentJDK/Libraries"
+ else
+ JAVA_BIN="$JAVA_HOME/../Commands"
+ JAVA_INC="$JAVA_HOME/../Headers"
+ JAVA_LIB="$JAVA_HOME/../Libraries"
+ fi
+ ;;
+ *)
+ AC_MSG_WARN([Unknown or unsupported JDK])
+ ;;
+ esac
+
+ JAVAPREFIX="$JAVA_BIN"
+
+ AC_SUBST(JAVA_BIN)
+ AC_SUBST(JAVA_INC)
+ AC_SUBST(JAVA_LIB)
+
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_CHECK_JAVA_LDFLAGS], [
+ AC_REQUIRE([AC_CHECK_JAVA_VENDOR])
+
+ AC_CACHE_CHECK([for linker flags for JNI], ac_cv_java_ldflags,[
+ case "$ac_cv_java_style" in
+ IBM)
+ ac_cv_java_ldflags="-L$JAVA_LIB -ljava -lhpi -ljsig"
+ ;;
+ Apple)
+ ac_cv_java_ldflags="-L$JAVA_LIB -lverify -ljvm -framework JavaVM"
+ ;;
+ *)
+ if test -d "$JAVA_HOME/jre/lib/$host_cpu"; then
+ ac_cv_java_ldflags="-L$JAVA_HOME/jre/lib/$host_cpu -ljava -lverify -ljsig"
+ else
+ case $host_cpu in
+ i*86)
+ ac_cv_java_ldflags="-L$JAVA_HOME/jre/lib/i386 -ljava -lverify -ljsig"
+ ;;
+ x86_64)
+ ac_cv_java_ldflags="-L$JAVA_HOME/jre/lib/amd64 -ljava -lverify -ljsig"
+ ;;
+ *)
+ if test -d "$JAVA_LIB/server"; then
+ ac_cv_java_ldflags="$ac_cv_java_ldflags -L$JAVA_LIB/server -ljvm"
+ elif test -d "$JAVA_LIB/client"; then
+ ac_cv_java_ldflags="$ac_cv_java_ldflags -L$JAVA_LIB/client -ljvm"
+ elif test -d "$JAVA_LIB/classic"; then
+ ac_cv_java_ldflags="$ac_cv_java_ldflags -L$JAVA_LIB/classic -ljvm"
+ else
+ AC_MSG_RESULT([unknown])
+ AC_MSG_WARN([Failed to identify your JVM])
+ fi
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ])
+
+ JAVA_LDFLAGS="$ac_cv_java_ldflags"
+ AC_SUBST(JAVA_LDFLAGS)
+
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_CHECK_JAVA_CXXFLAGS], [
+ AC_REQUIRE([AC_CHECK_JAVA_VENDOR])
+
+ AC_CACHE_CHECK([for compile flags for JNI], ac_cv_java_cxxflags,[
+ case "$ac_cv_java_style-$host_os" in
+ Sun-linux*)
+ ac_cv_java_cxxflags="-I$JAVA_INC -I$JAVA_INC/linux"
+ ;;
+ Sun-freebsd* | Sun-kfreebsd*-gnu | Sun-dragonfly*)
+ ac_cv_java_cxxflags="-I$JAVA_INC -I$JAVA_INC/freebsd"
+ ;;
+ *)
+ ac_cv_java_cxxflags="-I$JAVA_INC"
+ ;;
+ esac
+ ])
+
+ JAVA_CXXFLAGS="$ac_cv_java_cxxflags"
+ AC_SUBST(JAVA_CXXFLAGS)
+
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_PROG_JAVA], [
+ AC_REQUIRE([AC_EXEEXT])
+ AC_REQUIRE([AC_CHECK_JAVA_VENDOR])
+
+ AC_PATH_PROG([JAVA], [java$EXEEXT], [no], [$JAVA_BIN])
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_PROG_JAVAC], [
+ AC_REQUIRE([AC_EXEEXT])
+ AC_REQUIRE([AC_CHECK_JAVA_VENDOR])
+
+ AC_PATH_PROG([JAVAC], [javac$EXEEXT], [no], [$JAVA_BIN])
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_PROG_JAVAH], [
+ AC_REQUIRE([AC_EXEEXT])
+ AC_REQUIRE([AC_CHECK_JAVA_VENDOR])
+
+ AC_PATH_PROG([JAVAH], [javah$EXEEXT], [no], [$JAVA_BIN])
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_PROG_JAR], [
+ AC_REQUIRE([AC_EXEEXT])
+ AC_REQUIRE([AC_CHECK_JAVA_VENDOR])
+
+ AC_PATH_PROG([JAR],[jar$EXEEXT],[no],[$JAVA_BIN])
+AC_PROVIDE([$0])dnl
+])
+
+
+AC_DEFUN([AC_CHECK_JNI_COMPILE], [
+ AC_REQUIRE([AC_CHECK_JAVA_LDFLAGS])
+ AC_REQUIRE([AC_CHECK_JAVA_CXXFLAGS])
+
+ AC_CACHE_CHECK([JNI headers and libraries works], ac_cv_jni_works,[
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ ac_save_LDFLAGS="$LDFLAGS"
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ CXXFLAGS="$CXXFLAGS $JAVA_CXXFLAGS"
+ LDFLAGS="$LDFLAGS $JAVA_LDFLAGS"
+
+ AC_TRY_LINK(
+ [#include <jni.h>],[
+ JavaVM *vm;
+ JNIEnv *env;
+ JavaVMInitArgs args;
+ jint res;
+
+ args.version= JNI_VERSION_1_2;
+ args.options= NULL;
+ args.nOptions= 0;
+
+ res= JNI_CreateJavaVM(&vm, (void **) &env, (void *) &args);
+ ], ac_cv_jni_works=yes, ac_cv_jni_works=no)
+
+ AC_LANG_RESTORE
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ LDFLAGS="$ac_save_LDFLAGS"
+ ])
+ if test "$ac_cv_jni_works" != yes; then
+ AC_MSG_WARN([
+Linking a simple JNI test program failed. Something is wrong with the JDK
+configuration or your installed JDK is not supported yet.])
+ fi
+AC_PROVIDE([$0])dnl
+])
+
+
+
+##### http://autoconf-archive.cryp.to/ac_prog_java_works.html
+#
+# SYNOPSIS
+#
+# AC_PROG_JAVA_WORKS
+#
+# DESCRIPTION
+#
+# Internal use ONLY.
+#
+# Note: This is part of the set of autoconf M4 macros for Java
+# programs. It is VERY IMPORTANT that you download the whole set,
+# some macros depend on other. Unfortunately, the autoconf archive
+# does not support the concept of set of macros, so I had to break it
+# for submission. The general documentation, as well as the sample
+# configure.in, is included in the AC_PROG_JAVA macro.
+#
+# LAST MODIFICATION
+#
+# 2000-07-19
+#
+# COPYLEFT
+#
+# Copyright (c) 2000 Stephane Bortzmeyer <bortzmeyer@stripped>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# As a special exception, the respective Autoconf Macro's copyright
+# owner gives unlimited permission to copy, distribute and modify the
+# configure scripts that are the output of Autoconf when processing
+# the Macro. You need not follow the terms of the GNU General Public
+# License when using or distributing such scripts, even though
+# portions of the text of the Macro appear in them. The GNU General
+# Public License (GPL) does govern all other use of the material that
+# constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the
+# Autoconf Macro released by the Autoconf Macro Archive. When you
+# make and distribute a modified version of the Autoconf Macro, you
+# may extend this special exception to the GPL to apply to your
+# modified version as well.
+
+AC_DEFUN([AC_PROG_JAVA_WORKS], [
+AC_CHECK_PROG(uudecode, uudecode$EXEEXT, yes)
+if test x$uudecode = xyes; then
+AC_CACHE_CHECK([if uudecode can decode base 64 file], ac_cv_prog_uudecode_base64, [
+dnl /**
+dnl * Test.java: used to test if java compiler works.
+dnl */
+dnl public class Test
+dnl {
+dnl
+dnl public static void
+dnl main( String[] argv )
+dnl {
+dnl System.exit (0);
+dnl }
+dnl
+dnl }
+cat << \EOF > Test.uue
+begin-base64 644 Test.class
+yv66vgADAC0AFQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE
+bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51
+bWJlclRhYmxlDAAKAAsBAARleGl0AQAEKEkpVgoADQAJBwAOAQAQamF2YS9s
+YW5nL1N5c3RlbQEABjxpbml0PgEAAygpVgwADwAQCgADABEBAApTb3VyY2VG
+aWxlAQAJVGVzdC5qYXZhACEAAQADAAAAAAACAAkABQAGAAEABwAAACEAAQAB
+AAAABQO4AAyxAAAAAQAIAAAACgACAAAACgAEAAsAAQAPABAAAQAHAAAAIQAB
+AAEAAAAFKrcAErEAAAABAAgAAAAKAAIAAAAEAAQABAABABMAAAACABQ=
+====
+EOF
+if uudecode$EXEEXT Test.uue; then
+ ac_cv_prog_uudecode_base64=yes
+else
+ echo "configure: __oline__: uudecode had trouble decoding base 64 file 'Test.uue'" >&AC_FD_CC
+ echo "configure: failed file was:" >&AC_FD_CC
+ cat Test.uue >&AC_FD_CC
+ ac_cv_prog_uudecode_base64=no
+fi
+rm -f Test.uue])
+fi
+if test x$ac_cv_prog_uudecode_base64 != xyes; then
+ rm -f Test.class
+ AC_MSG_WARN([I have to compile Test.class from scratch])
+ if test x$ac_cv_prog_javac_works = xno; then
+ AC_MSG_WARN([Cannot compile java source. $JAVAC does not work properly])
+ else
+ if test x$ac_cv_prog_javac_works = x; then
+ AC_PROG_JAVAC
+ fi
+ fi
+fi
+AC_CACHE_CHECK(if $JAVA works, ac_cv_prog_java_works, [
+JAVA_TEST=Test.java
+CLASS_TEST=Test.class
+TEST=Test
+changequote(, )dnl
+cat << \EOF > $JAVA_TEST
+/* [#]line __oline__ "configure" */
+public class Test {
+public static void main (String args[]) {
+ System.exit (0);
+} }
+EOF
+changequote([, ])dnl
+if test x$ac_cv_prog_uudecode_base64 != xyes; then
+ if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) && test -s $CLASS_TEST; then
+ :
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat $JAVA_TEST >&AC_FD_CC
+ AC_MSG_WARN(The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?))
+ fi
+fi
+if AC_TRY_COMMAND($JAVA $JAVAFLAGS $TEST) >/dev/null 2>&1; then
+ ac_cv_prog_java_works=yes
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat $JAVA_TEST >&AC_FD_CC
+ AC_MSG_WARN(The Java VM $JAVA failed (see config.log, check the CLASSPATH?))
+fi
+rm -fr $JAVA_TEST $CLASS_TEST Test.uue
+])
+AC_PROVIDE([$0])dnl
+]
+)
+
+
+
+##### http://autoconf-archive.cryp.to/ac_prog_javac_works.html
+#
+# SYNOPSIS
+#
+# AC_PROG_JAVAC_WORKS
+#
+# DESCRIPTION
+#
+# Internal use ONLY.
+#
+# Note: This is part of the set of autoconf M4 macros for Java
+# programs. It is VERY IMPORTANT that you download the whole set,
+# some macros depend on other. Unfortunately, the autoconf archive
+# does not support the concept of set of macros, so I had to break it
+# for submission. The general documentation, as well as the sample
+# configure.in, is included in the AC_PROG_JAVA macro.
+#
+# LAST MODIFICATION
+#
+# 2000-07-19
+#
+# COPYLEFT
+#
+# Copyright (c) 2000 Stephane Bortzmeyer <bortzmeyer@stripped>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# As a special exception, the respective Autoconf Macro's copyright
+# owner gives unlimited permission to copy, distribute and modify the
+# configure scripts that are the output of Autoconf when processing
+# the Macro. You need not follow the terms of the GNU General Public
+# License when using or distributing such scripts, even though
+# portions of the text of the Macro appear in them. The GNU General
+# Public License (GPL) does govern all other use of the material that
+# constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the
+# Autoconf Macro released by the Autoconf Macro Archive. When you
+# make and distribute a modified version of the Autoconf Macro, you
+# may extend this special exception to the GPL to apply to your
+# modified version as well.
+
+AC_DEFUN([AC_PROG_JAVAC_WORKS],[
+AC_REQUIRE([AC_PROG_JAVAC])
+AC_CACHE_CHECK([if $JAVAC works], ac_cv_prog_javac_works, [
+JAVA_TEST=Test.java
+CLASS_TEST=Test.class
+cat << \EOF > $JAVA_TEST
+/* [#]line __oline__ "configure" */
+public class Test {
+}
+EOF
+if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) >/dev/null 2>&1; then
+ ac_cv_prog_javac_works=yes
+else
+ AC_MSG_WARN([The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)])
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat $JAVA_TEST >&AC_FD_CC
+fi
+rm -f $JAVA_TEST $CLASS_TEST
+])
+AC_PROVIDE([$0])dnl
+])
diff -Nrup a/configure.in b/configure.in
--- a/configure.in 2008-02-11 09:10:34 -08:00
+++ b/configure.in 2008-02-22 17:05:03 -08:00
@@ -46,6 +46,7 @@ sinclude(config/ac-macros/misc.m4)
sinclude(config/ac-macros/readline.m4)
sinclude(config/ac-macros/ssl.m4)
sinclude(config/ac-macros/zlib.m4)
+sinclude(config/ac-macros/java.m4)
# Remember to add a directory sql/share/LANGUAGE
AVAILABLE_LANGUAGES="\
@@ -528,6 +529,8 @@ if test "$am_cv_prog_cc_stdc" = "no"
then
AC_MSG_ERROR([MySQL requires an ANSI C compiler (and a C++ compiler). Try gcc. See the Installation chapter in the Reference Manual.])
fi
+
+AC_CHECK_C_WEAK_SUPPORT
NOINST_LDFLAGS="-static"
diff -Nrup a/include/mysql/plugin.h b/include/mysql/plugin.h
--- a/include/mysql/plugin.h 2007-08-30 23:19:49 -07:00
+++ b/include/mysql/plugin.h 2008-02-22 17:05:04 -08:00
@@ -65,7 +65,8 @@ typedef struct st_mysql_xid MYSQL_XID;
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
-#define MYSQL_MAX_PLUGIN_TYPE_NUM 5 /* The number of plugin types */
+#define MYSQL_PSMLANGUAGE_PLUGIN 5 /* Stored Procedure Language */
+#define MYSQL_MAX_PLUGIN_TYPE_NUM 6 /* The number of plugin types */
/* We use the following strings to define licenses for plugins */
#define PLUGIN_LICENSE_PROPRIETARY 0
@@ -135,6 +136,7 @@ typedef int (*mysql_show_var_func)(MYSQL
#define PLUGIN_VAR_STR 0x0005
#define PLUGIN_VAR_ENUM 0x0006
#define PLUGIN_VAR_SET 0x0007
+#define PLUGIN_VAR_OPAQUE 0x0008
#define PLUGIN_VAR_UNSIGNED 0x0080
#define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */
#define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */
@@ -367,6 +369,12 @@ DECLARE_MYSQL_THDVAR_TYPELIB(name, unsig
PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
#name, comment, check, update, -1, def, NULL, typelib }
+#define MYSQL_THDVAR_OPAQUE(name, type) \
+DECLARE_MYSQL_THDVAR_BASIC(name, __typeof__ (type *)) = { \
+ PLUGIN_VAR_OPAQUE | PLUGIN_VAR_THDLOCAL | \
+ PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT, #name, \
+ NULL, NULL, NULL, -1, NULL, NULL }
+
/* accessor macros */
#define SYSVAR(name) \
@@ -641,6 +649,122 @@ struct st_mysql_information_schema
};
+/*************************************************************************
+ API for PSM Language plugin. (MYSQL_PSM_LANGUAGE_PLUGIN)
+*/
+
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_PSM_LANGUAGE_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
+
+
+typedef struct st_mysql_psmroutine *MYSQL_PSM_ROUTINE;
+
+typedef struct st_mysql_psmcontext *MYSQL_PSM_CONTEXT;
+
+struct st_mysql_time;
+
+struct st_mysql_psmcallbacks
+{
+ /* store with idx == -1 for function results */
+ int (*store_null)(MYSQL_PSM_CONTEXT, int idx);
+ int (*store_string)(MYSQL_PSM_CONTEXT, int idx,
+ const char *str, int length, struct charset_info_st *cs);
+ int (*store_double)(MYSQL_PSM_CONTEXT, int idx, double nr, int precision);
+ int (*store_integer)(MYSQL_PSM_CONTEXT, int idx, long long nr, char unsigned_val);
+ int (*store_time)(MYSQL_PSM_CONTEXT, int idx, struct st_mysql_time *ltime);
+
+ int (*val_null)(MYSQL_PSM_CONTEXT, int idx);
+ const char *(*val_string)(MYSQL_PSM_CONTEXT, int idx,
+ char *str, int *length,
+ struct charset_info_st **cs);
+ long long (*val_integer)(MYSQL_PSM_CONTEXT, int idx);
+ double (*val_double)(MYSQL_PSM_CONTEXT, int idx);
+
+ int (*field_ptr)(MYSQL_PSM_CONTEXT, int idx,
+ int *field_type, void **ptr, int *length);
+
+ int (*row_field)(MYSQL_PSM_CONTEXT, const char *title,
+ int field_type, int size, int precision);
+ int (*row_prepare)(MYSQL_PSM_CONTEXT);
+ int (*row_send)(MYSQL_PSM_CONTEXT);
+ int (*row_send_eof)(MYSQL_PSM_CONTEXT);
+
+ int (*field_metadata)(MYSQL_PSM_CONTEXT, int idx,
+ int *max_length, char *maybe_null,
+ char *const_item, char *arg_type,
+ const char **attributes, int *attribute_length);
+};
+
+
+struct st_mysql_psmcontext
+{
+ const struct st_mysql_psmcallbacks *cb;
+ MYSQL_THD thd;
+ int arg_count;
+ int psm_phase;
+
+#ifdef __cplusplus
+public:
+ st_mysql_psmcontext() {}
+ inline int store_null(int idx)
+ { return cb->store_null(this, idx); }
+ inline int store_string(int idx, const char *str, int length,
+ struct charset_info_st *cs)
+ { return cb->store_string(this, idx, str, length, cs); }
+ inline int store_double(int idx, double nr, int precision)
+ { return cb->store_double(this, idx, nr, precision); }
+ inline int store_integer(int idx, long long nr, char unsigned_val)
+ { return cb->store_integer(this, idx, nr, unsigned_val); }
+ inline int store_time(int idx, struct st_mysql_time *ltime)
+ { return cb->store_time(this, idx, ltime); }
+ inline int val_null(int idx)
+ { return cb->val_null(this, idx); }
+ inline const char *val_string(int idx, char *str, int *length,
+ struct charset_info_st **cs)
+ { return cb->val_string(this, idx, str, length, cs); }
+ inline long long val_integer(int idx)
+ { return cb->val_integer(this, idx); }
+ inline double val_double(int idx)
+ { return cb->val_double(this, idx); }
+
+ inline int field_ptr(int idx, int *field_type, void **ptr, int *length)
+ { return cb->field_ptr(this, idx, field_type, ptr, length); }
+
+ inline int row_field(const char *title, int field_type,
+ int size, int precision)
+ { return cb->row_field(this, title, field_type, size, precision); }
+ inline int row_prepare()
+ { return cb->row_prepare(this); }
+ inline int row_send()
+ { return cb->row_send(this); }
+ inline int row_send_eof()
+ { return cb->row_send_eof(this); }
+
+ inline int field_metadata(int idx,
+ int *max_length, char *maybe_null,
+ char *const_item, char *arg_type,
+ const char **attributes, int *attribute_length)
+ { return cb->field_metadata(this, idx, max_length, maybe_null, const_item,
+ arg_type, attributes, attribute_length); }
+#endif
+};
+
+
+/*
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
+*/
+
+struct st_mysql_psmlanguage
+{
+ int interface_version;
+ int (*find)(MYSQL_PSM_ROUTINE *handle, const char *name, int name_length);
+ int (*release)(MYSQL_PSM_ROUTINE handle);
+ int (*execute)(MYSQL_PSM_ROUTINE handle, MYSQL_PSM_CONTEXT context);
+
+};
+
+
/*
st_mysql_value struct for reading values from mysqld.
Used by server variables framework to parse user-provided values.
@@ -684,6 +808,8 @@ char *thd_security_context(MYSQL_THD thd
/* Increments the row counter, see THD::row_count */
void thd_inc_row_count(MYSQL_THD thd);
+const char *mysqld_errmsg(unsigned int err);
+
/**
Create a temporary file.
@@ -713,6 +839,7 @@ int mysql_tmpfile(const char *prefix);
@retval 1 the connection has been killed
*/
int thd_killed(const MYSQL_THD thd);
+int *thd_killed_ptr(const MYSQL_THD thd);
/**
Allocate memory in the connection's local memory pool
diff -Nrup a/include/mysql.h b/include/mysql.h
--- a/include/mysql.h 2007-11-26 10:09:34 -08:00
+++ b/include/mysql.h 2008-02-22 17:05:04 -08:00
@@ -167,7 +167,7 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_USE_INLINE_CONNECTION
};
struct st_mysql_options {
diff -Nrup a/libmysqld/Makefile.am b/libmysqld/Makefile.am
--- a/libmysqld/Makefile.am 2007-10-31 13:43:44 -07:00
+++ b/libmysqld/Makefile.am 2008-02-22 17:05:04 -08:00
@@ -71,6 +71,7 @@ sqlsources = derror.cc field.cc field_co
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
+ sp_external.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
event_scheduler.cc events.cc event_data_objects.cc \
event_queue.cc event_db_repository.cc \
diff -Nrup a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
--- a/libmysqld/emb_qcache.cc 2007-12-14 05:01:09 -08:00
+++ b/libmysqld/emb_qcache.cc 2008-02-22 17:05:05 -08:00
@@ -313,7 +313,7 @@ uint emb_count_querycache_size(THD *thd)
result+= field->def_length;
}
- if (thd->protocol == &thd->protocol_binary)
+ if (thd->protocol == thd->protocol_binary)
{
result+= (uint) (4*n_rows);
for (; cur_row; cur_row=cur_row->next)
@@ -376,7 +376,7 @@ void emb_store_querycache_result(Queryca
dst->store_safe_str(field->def, field->def_length);
}
- if (thd->protocol == &thd->protocol_binary)
+ if (thd->protocol == thd->protocol_binary)
{
for (; cur_row; cur_row=cur_row->next)
dst->store_str((char *) cur_row->data, cur_row->length);
@@ -444,7 +444,7 @@ int emb_load_querycache_result(THD *thd,
data->rows= rows;
if (!rows)
goto return_ok;
- if (thd->protocol == &thd->protocol_binary)
+ if (thd->protocol == thd->protocol_binary)
{
uint length;
row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS));
diff -Nrup a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
--- a/libmysqld/lib_sql.cc 2007-12-20 12:24:01 -08:00
+++ b/libmysqld/lib_sql.cc 2008-02-22 17:05:05 -08:00
@@ -238,7 +238,8 @@ static my_bool emb_read_query_result(MYS
{
THD *thd= (THD*) mysql->thd;
MYSQL_DATA *res= thd->first_data;
- DBUG_ASSERT(!thd->cur_data);
+
+ DBUG_ASSERT(res && !thd->cur_data);
thd->first_data= res->embedded_info->next;
if (res->embedded_info->last_errno &&
!res->embedded_info->fields_list)
@@ -784,9 +785,8 @@ MYSQL_DATA *THD::alloc_new_dataset()
@note Should be called after we get the recordset-result.
*/
-static
void
-write_eof_packet(THD *thd, uint server_status, uint total_warn_count)
+Transport_embedded::write_eof_packet(THD *thd, uint server_status, uint total_warn_count)
{
if (!thd->mysql) // bootstrap file handling
return;
@@ -811,14 +811,14 @@ write_eof_packet(THD *thd, uint server_s
allocs new query result and initialises Protocol::alloc
SYNOPSIS
- Protocol::begin_dataset()
+ Protocol_embedded::begin_dataset()
RETURN
0 if success
1 if memory allocation failed
*/
-int Protocol::begin_dataset()
+int Transport_embedded::begin_dataset(THD *thd)
{
MYSQL_DATA *data= thd->alloc_new_dataset();
if (!data)
@@ -834,7 +834,7 @@ int Protocol::begin_dataset()
remove last row of current recordset
SYNOPSIS
- Protocol_text::remove_last_row()
+ Protocol_emb_text::remove_last_row()
NOTES
does the loop from the beginning of the current recordset to
@@ -842,7 +842,7 @@ int Protocol::begin_dataset()
Not supposed to be frequently called.
*/
-void Protocol_text::remove_last_row()
+void Protocol_emb_text::remove_last_row()
{
MYSQL_DATA *data= thd->cur_data;
MYSQL_ROWS **last_row_hook= &data->data;
@@ -859,7 +859,7 @@ void Protocol_text::remove_last_row()
}
-bool Protocol::send_fields(List<Item> *list, uint flags)
+bool Transport_embedded::send_fields(THD *thd, List<Item> *list, uint flags)
{
List_iterator_fast<Item> it(*list);
Item *item;
@@ -868,20 +868,21 @@ bool Protocol::send_fields(List<Item> *l
CHARSET_INFO *thd_cs= thd->variables.character_set_results;
CHARSET_INFO *cs= system_charset_info;
MYSQL_DATA *data;
- DBUG_ENTER("send_fields");
+ DBUG_ENTER("Transport_embedded::send_fields");
if (!thd->mysql) // bootstrap file handling
DBUG_RETURN(0);
- if (begin_dataset())
+ if (begin_dataset(thd))
goto err;
data= thd->cur_data;
- data->fields= field_count= list->elements;
+ data->fields= protocol->field_count= list->elements;
field_alloc= &data->alloc;
if (!(client_field= data->embedded_info->fields_list=
- (MYSQL_FIELD*)alloc_root(field_alloc, sizeof(MYSQL_FIELD)*field_count)))
+ (MYSQL_FIELD*)alloc_root(field_alloc,
+ sizeof(MYSQL_FIELD)*protocol->field_count)))
goto err;
while ((item= it++))
@@ -958,16 +959,17 @@ bool Protocol::send_fields(List<Item> *l
++client_field;
}
- if (flags & SEND_EOF)
+ if (flags & Protocol::SEND_EOF)
write_eof_packet(thd, thd->server_status, thd->total_warn_count);
- DBUG_RETURN(prepare_for_send(list));
+ DBUG_RETURN(protocol->prepare_for_send(list));
err:
my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
-bool Protocol::write()
+
+bool Transport_embedded::write(THD *thd)
{
if (!thd->mysql) // bootstrap file handling
return false;
@@ -976,8 +978,10 @@ bool Protocol::write()
return false;
}
-bool Protocol_binary::write()
+
+bool Transport_emb_binary::write(THD *thd)
{
+ String *const packet= protocol->packet;
MYSQL_ROWS *cur;
MYSQL_DATA *data= thd->cur_data;
@@ -1018,13 +1022,13 @@ bool Protocol_binary::write()
*/
void
-net_send_ok(THD *thd,
+Transport_embedded::send_ok(THD *thd,
uint server_status, uint total_warn_count,
ha_rows affected_rows, ulonglong id, const char *message)
{
- DBUG_ENTER("emb_net_send_ok");
MYSQL_DATA *data;
MYSQL *mysql= thd->mysql;
+ DBUG_ENTER("Transport_embedded::send_ok");
if (!mysql) // bootstrap file handling
DBUG_VOID_RETURN;
@@ -1051,14 +1055,14 @@ net_send_ok(THD *thd,
*/
void
-net_send_eof(THD *thd, uint server_status, uint total_warn_count)
+Transport_embedded::send_eof(THD *thd, uint server_status, uint total_warn_count)
{
write_eof_packet(thd, server_status, total_warn_count);
thd->cur_data= 0;
}
-void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
+void Transport_embedded::send_error_packet(THD *thd, uint sql_errno, const char *err)
{
MYSQL_DATA *data= thd->cur_data ? thd->cur_data : thd->alloc_new_dataset();
struct embedded_query_result *ei= data->embedded_info;
@@ -1071,17 +1075,19 @@ void net_send_error_packet(THD *thd, uin
}
-void Protocol_text::prepare_for_resend()
+void Protocol_emb_text::prepare_for_resend()
{
MYSQL_ROWS *cur;
MYSQL_DATA *data= thd->cur_data;
- DBUG_ENTER("send_data");
+ Transport_embedded *const trans= (Transport_embedded *) transport;
+ DBUG_ENTER("Protocol_emb_text::send_data");
if (!thd->mysql) // bootstrap file handling
DBUG_VOID_RETURN;
data->rows++;
- if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
+ if (!(cur= (MYSQL_ROWS *)alloc_root(trans->alloc,
+ sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
{
my_error(ER_OUT_OF_RESOURCES,MYF(0));
DBUG_VOID_RETURN;
@@ -1090,20 +1096,21 @@ void Protocol_text::prepare_for_resend()
*data->embedded_info->prev_ptr= cur;
data->embedded_info->prev_ptr= &cur->next;
- next_field=cur->data;
- next_mysql_field= data->embedded_info->fields_list;
+ trans->next_field=cur->data;
+ trans->next_mysql_field= data->embedded_info->fields_list;
DBUG_VOID_RETURN;
}
-bool Protocol_text::store_null()
+bool Protocol_emb_text::store_null()
{
- *(next_field++)= NULL;
- ++next_mysql_field;
+ Transport_embedded *trans= (Transport_embedded *) transport;
+ *(trans->next_field++)= NULL;
+ ++trans->next_mysql_field;
return false;
}
-bool Protocol::net_store_data(const uchar *from, size_t length)
+bool Transport_embedded::store_data(THD *thd, const uchar *from, size_t length)
{
char *field_buf;
if (!thd->mysql) // bootstrap file handling
diff -Nrup a/mysql-test/include/have_psmexample_plugin.inc b/mysql-test/include/have_psmexample_plugin.inc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/include/have_psmexample_plugin.inc 2008-02-22 17:05:27 -08:00
@@ -0,0 +1,16 @@
+#
+# Check if server has support for loading udf's
+# i.e it will support dlopen
+#
+--require r/have_dynamic_loading.require
+disable_query_log;
+show variables like "have_dynamic_loading";
+enable_query_log;
+
+#
+# Check if the variable PSMEXAMPLE_PLUGIN is set
+#
+--require r/have_psmexample_plugin.require
+disable_query_log;
+eval select LENGTH("$PSMEXAMPLE_PLUGIN") > 0 as "have_psmexample_plugin";
+enable_query_log;
diff -Nrup a/mysql-test/include/have_psmjava_plugin.inc b/mysql-test/include/have_psmjava_plugin.inc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/include/have_psmjava_plugin.inc 2008-02-22 17:05:27 -08:00
@@ -0,0 +1,4 @@
+disable_query_log;
+--require r/true.require
+select plugin_status = 'Active' as `TRUE` from information_schema.plugins where plugin_name = 'Java' and plugin_type = 'PSM LANGUAGE';
+enable_query_log;
diff -Nrup a/mysql-test/include/have_psmperl_plugin.inc b/mysql-test/include/have_psmperl_plugin.inc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/include/have_psmperl_plugin.inc 2008-02-22 17:05:27 -08:00
@@ -0,0 +1,4 @@
+disable_query_log;
+--require r/true.require
+select plugin_status = 'Active' as `TRUE` from information_schema.plugins where plugin_name = 'Perl' and plugin_type = 'PSM LANGUAGE';
+enable_query_log;
diff -Nrup a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
--- a/mysql-test/mysql-test-run.pl 2008-02-13 11:51:55 -08:00
+++ b/mysql-test/mysql-test-run.pl 2008-02-22 17:05:05 -08:00
@@ -172,6 +172,9 @@ our $exe_my_print_defaults;
our $exe_perror;
our $lib_udf_example;
our $lib_example_plugin;
+our $lib_psmexample_plugin;
+our $lib_psmjava_plugin;
+our $lib_psmperl_plugin;
our $exe_libtool;
our $opt_bench= 0;
@@ -1700,6 +1703,20 @@ sub executable_setup () {
mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'),
"$glob_basedir/storage/example/.libs/ha_example.so",);
+ # Look for the psm_example library
+ $lib_psmexample_plugin=
+ mtr_file_exists(vs_config_dirs('plugin/example_udf', 'psm_example.dll'),
+ "$glob_basedir/plugin/example_udf/.libs/psm_example.so",);
+
+ # Look for the psm_java library
+ $lib_psmjava_plugin=
+ mtr_file_exists(vs_config_dirs('plugin/java_udf', 'psm_java.dll'),
+ "$glob_basedir/plugin/java_udf/.libs/psm_java.so",);
+
+ # Look for the psm_perl library
+ $lib_psmperl_plugin=
+ mtr_file_exists(vs_config_dirs('plugin/perl_udf', 'psm_perl.dll'),
+ "$glob_basedir/plugin/perl_udf/.libs/psm_perl.so",);
}
# Look for mysqltest executable
@@ -2171,6 +2188,32 @@ sub environment_setup () {
($lib_example_plugin ? basename($lib_example_plugin) : "");
$ENV{'EXAMPLE_PLUGIN_OPT'}=
($lib_example_plugin ? "--plugin_dir=" . dirname($lib_example_plugin) : "");
+
+ # ----------------------------------------------------
+ # Add the path where mysqld will find psm_example.so
+ # ----------------------------------------------------
+ $ENV{'PSMEXAMPLE_PLUGIN'}=
+ ($lib_psmexample_plugin ? basename($lib_psmexample_plugin) : "");
+ $ENV{'PSMEXAMPLE_PLUGIN_OPT'}=
+ ($lib_psmexample_plugin ? "--plugin_dir=" . dirname($lib_psmexample_plugin) : "");
+
+ # ----------------------------------------------------
+ # Add the path where mysqld will find psm_java.so
+ # ----------------------------------------------------
+ $ENV{'PSMJAVA_PLUGIN'}=
+ ($lib_psmjava_plugin ? basename($lib_psmjava_plugin) : "");
+ $ENV{'PSMJAVA_PLUGIN_OPT'}=
+ ($lib_psmjava_plugin ? "--plugin_dir=" . dirname($lib_psmjava_plugin) : "");
+ $ENV{'PSMJAVA_PLUGIN_DIR'}= "$glob_basedir/plugin/java_udf";
+
+ # ----------------------------------------------------
+ # Add the path where mysqld will find psm_perl.so
+ # ----------------------------------------------------
+ $ENV{'PSMPERL_PLUGIN'}=
+ ($lib_psmperl_plugin ? basename($lib_psmperl_plugin) : "");
+ $ENV{'PSMPERL_PLUGIN_OPT'}=
+ ($lib_psmperl_plugin ? "--plugin_dir=" . dirname($lib_psmperl_plugin) : "");
+ $ENV{'PSMPERL_PLUGIN_DIR'}= "$glob_basedir/plugin/perl_udf";
# ----------------------------------------------------
# Setup env so childs can execute myisampack and myisamchk
diff -Nrup a/mysql-test/r/have_psmexample_plugin.require b/mysql-test/r/have_psmexample_plugin.require
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/have_psmexample_plugin.require 2008-02-22 17:05:11 -08:00
@@ -0,0 +1,2 @@
+have_psmexample_plugin
+1
diff -Nrup a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
--- a/mysql-test/r/information_schema.result 2008-02-07 02:47:37 -08:00
+++ b/mysql-test/r/information_schema.result 2008-02-22 17:05:05 -08:00
@@ -578,7 +578,7 @@ proc db char(64)
proc name char(64)
proc type enum('FUNCTION','PROCEDURE')
proc specific_name char(64)
-proc language enum('SQL')
+proc language char(64)
proc sql_data_access enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
proc is_deterministic enum('YES','NO')
proc security_type enum('INVOKER','DEFINER')
diff -Nrup a/mysql-test/r/plugin_psm.result b/mysql-test/r/plugin_psm.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/plugin_psm.result 2008-02-22 17:05:11 -08:00
@@ -0,0 +1,11 @@
+INSTALL PLUGIN Deep_Thought SONAME 'psm_example.so';
+CREATE PROCEDURE test.UltimateAnswer()
+DYNAMIC RESULT SETS 1
+LANGUAGE Deep_Thought EXTERNAL NAME 'compute';
+CALL test.UltimateAnswer();
+Answer to Life, the Universe and Everything
+Forty-Two
+DROP PROCEDURE test.UltimateAnswer;
+UNINSTALL PLUGIN Deep_Thought;
+UNINSTALL PLUGIN Deep_Thought;
+ERROR 42000: PLUGIN Deep_Thought does not exist
diff -Nrup a/mysql-test/r/plugin_psm_java.result b/mysql-test/r/plugin_psm_java.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/plugin_psm_java.result 2008-02-22 17:05:11 -08:00
@@ -0,0 +1,17 @@
+CREATE FUNCTION test.JavaReverse(source TEXT) RETURNS TEXT
+LANGUAGE Java NO SQL
+EXTERNAL NAME 'com.mysql.udf.example.Reverse.go';
+SELECT test.JavaReverse("Hello World") FROM DUAL;
+test.JavaReverse("Hello World")
+dlroW olleH
+DROP FUNCTION test.JavaReverse;
+CREATE FUNCTION test.PigLatin(source TEXT) RETURNS TEXT
+LANGUAGE Java NO SQL
+EXTERNAL NAME 'com.mysql.udf.example.PigLatin.toPigLatin';
+SELECT test.PigLatin("Hello World") FROM DUAL;
+test.PigLatin("Hello World")
+Ellohay Orldway
+SELECT test.PigLatin("A simple test of Java user defined functions") AS foo;
+foo
+Away implesay esttay ofway Avajay userway efinedday unctionsfay
+DROP FUNCTION test.PigLatin;
diff -Nrup a/mysql-test/r/plugin_psm_perl.result b/mysql-test/r/plugin_psm_perl.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/plugin_psm_perl.result 2008-02-22 17:05:12 -08:00
@@ -0,0 +1,91 @@
+CREATE FUNCTION test.PerlReverse(source TEXT) RETURNS TEXT
+LANGUAGE Perl NO SQL
+EXTERNAL NAME 'MyUDFExample::my_reverse';
+SELECT test.PerlReverse("Hello World") FROM DUAL;
+test.PerlReverse("Hello World")
+dlroW olleH
+DROP FUNCTION test.PerlReverse;
+CREATE PROCEDURE test.PerlReverse2(INOUT source TEXT)
+LANGUAGE Perl NO SQL
+EXTERNAL NAME 'MyUDFExample::my_reverseproc';
+SET @testvar='Another test';
+CALL test.PerlReverse2(@testvar);
+SELECT @testvar;
+@testvar
+tset rehtonA
+DROP PROCEDURE test.PerlReverse2;
+CREATE PROCEDURE test.TestHashResults()
+LANGUAGE Perl NO SQL
+DYNAMIC RESULT SETS 1
+EXTERNAL NAME 'MyUDFExample::testhashresults';
+CALL test.TestHashResults();
+bar foo
+bar data foo data
+DROP PROCEDURE test.TestHashResults;
+CREATE PROCEDURE test.TestArrayHashResults()
+LANGUAGE Perl NO SQL
+DYNAMIC RESULT SETS 1
+EXTERNAL NAME 'MyUDFExample::testarrayhashresults';
+CALL test.TestArrayHashResults();
+bar foo wibble
+bar data foo data NULL
+NULL foo data ding
+3 1 2
+DROP PROCEDURE test.TestArrayHashResults;
+CREATE PROCEDURE test.PerlPrimes1(top_limit INT)
+LANGUAGE Perl NO SQL
+DYNAMIC RESULT SETS 1
+EXTERNAL NAME 'MyUDFExample::testprimes';
+CALL test.PerlPrimes1(100);
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
+2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
+DROP PROCEDURE test.PerlPrimes1;
+CREATE PROCEDURE test.PerlPrimes2(top_limit INT)
+LANGUAGE Perl NO SQL
+DYNAMIC RESULT SETS 1
+EXTERNAL NAME 'MyUDFExample::testprimes_vertical';
+CALL test.PerlPrimes2(100);
+prime
+2
+3
+5
+7
+11
+13
+17
+19
+23
+29
+31
+37
+41
+43
+47
+53
+59
+61
+67
+71
+73
+79
+83
+89
+97
+DROP PROCEDURE test.PerlPrimes2;
+CREATE PROCEDURE test.matrix(top_limit INT)
+LANGUAGE Perl NO SQL
+DYNAMIC RESULT SETS 1
+EXTERNAL NAME 'MyUDFExample::testmatrix';
+CALL test.matrix(10);
+0 1 2 3 4 5 6 7 8 9
+1 0 0 0 0 0 0 0 0 0
+1 1 0 0 0 0 0 0 0 0
+1 2 1 0 0 0 0 0 0 0
+1 3 3 1 0 0 0 0 0 0
+1 4 6 4 1 0 0 0 0 0
+1 5 10 10 5 1 0 0 0 0
+1 6 15 20 15 6 1 0 0 0
+1 7 21 35 35 21 7 1 0 0
+1 8 28 56 70 56 28 8 1 0
+1 9 36 84 126 126 84 36 9 1
+DROP PROCEDURE test.matrix;
diff -Nrup a/mysql-test/r/plugin_psm_perl_dbi.result b/mysql-test/r/plugin_psm_perl_dbi.result
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/plugin_psm_perl_dbi.result 2008-02-22 17:05:12 -08:00
@@ -0,0 +1,12 @@
+CREATE TABLE test.t1 (seq INT NOT NULL AUTO_INCREMENT PRIMARY KEY, txt VARCHAR(128));
+CREATE PROCEDURE test.test1()
+LANGUAGE Perl MODIFIES SQL DATA
+EXTERNAL NAME 'MyDBIExample::test1';
+LOCK TABLE test.t1 WRITE;
+CALL test.test1();
+UNLOCK TABLES;
+SELECT * from test.t1;
+seq txt
+1 hello world
+DROP PROCEDURE test.test1;
+DROP TABLE test.t1;
diff -Nrup a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
--- a/mysql-test/r/system_mysql_db.result 2008-02-07 02:47:37 -08:00
+++ b/mysql-test/r/system_mysql_db.result 2008-02-22 17:05:05 -08:00
@@ -191,7 +191,7 @@ proc CREATE TABLE `proc` (
`name` char(64) NOT NULL DEFAULT '',
`type` enum('FUNCTION','PROCEDURE') NOT NULL,
`specific_name` char(64) NOT NULL DEFAULT '',
- `language` enum('SQL') NOT NULL DEFAULT 'SQL',
+ `language` char(64) NOT NULL DEFAULT 'SQL',
`sql_data_access` enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') NOT NULL DEFAULT 'CONTAINS_SQL',
`is_deterministic` enum('YES','NO') NOT NULL DEFAULT 'NO',
`security_type` enum('INVOKER','DEFINER') NOT NULL DEFAULT 'DEFINER',
diff -Nrup a/mysql-test/t/plugin_psm-master.opt b/mysql-test/t/plugin_psm-master.opt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm-master.opt 2008-02-22 17:05:12 -08:00
@@ -0,0 +1 @@
+$PSMEXAMPLE_PLUGIN_OPT
diff -Nrup a/mysql-test/t/plugin_psm.test b/mysql-test/t/plugin_psm.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm.test 2008-02-22 17:05:12 -08:00
@@ -0,0 +1,16 @@
+--source include/have_psmexample_plugin.inc
+
+INSTALL PLUGIN Deep_Thought SONAME 'psm_example.so';
+
+CREATE PROCEDURE test.UltimateAnswer()
+ DYNAMIC RESULT SETS 1
+ LANGUAGE Deep_Thought EXTERNAL NAME 'compute';
+
+# Let's do some advanced ops with the example engine :)
+CALL test.UltimateAnswer();
+
+DROP PROCEDURE test.UltimateAnswer;
+
+UNINSTALL PLUGIN Deep_Thought;
+--error 1305
+UNINSTALL PLUGIN Deep_Thought;
diff -Nrup a/mysql-test/t/plugin_psm_java-master.opt b/mysql-test/t/plugin_psm_java-master.opt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm_java-master.opt 2008-02-22 17:05:12 -08:00
@@ -0,0 +1,3 @@
+$PSMJAVA_PLUGIN_OPT
+--loose-plugin-load=java=$PSMJAVA_PLUGIN
+--loose-plugin-java-config-file=$PSMJAVA_PLUGIN_DIR/jvm_options.cnf
diff -Nrup a/mysql-test/t/plugin_psm_java.test b/mysql-test/t/plugin_psm_java.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm_java.test 2008-02-22 17:05:12 -08:00
@@ -0,0 +1,27 @@
+--source include/have_psmjava_plugin.inc
+
+CREATE FUNCTION test.JavaReverse(source TEXT) RETURNS TEXT
+ LANGUAGE Java NO SQL
+ EXTERNAL NAME 'com.mysql.udf.example.Reverse.go';
+
+SELECT test.JavaReverse("Hello World") FROM DUAL;
+
+DROP FUNCTION test.JavaReverse;
+
+CREATE FUNCTION test.PigLatin(source TEXT) RETURNS TEXT
+ LANGUAGE Java NO SQL
+ EXTERNAL NAME 'com.mysql.udf.example.PigLatin.toPigLatin';
+
+SELECT test.PigLatin("Hello World") FROM DUAL;
+SELECT test.PigLatin("A simple test of Java user defined functions") AS foo;
+
+DROP FUNCTION test.PigLatin;
+
+#CREATE PROCEDURE test.JavaPrimes(top_limit INT)
+# LANGUAGE Java NO SQL
+# DYNAMIC RESULT SETS 1
+# EXTERNAL NAME 'com.mysql.udf.example.Primes.upTo';
+#
+#CALL test.JavaPrimes(100);
+#
+#DROP PROCEDURE test.JavaPrimes;
diff -Nrup a/mysql-test/t/plugin_psm_perl-master.opt b/mysql-test/t/plugin_psm_perl-master.opt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm_perl-master.opt 2008-02-22 17:05:12 -08:00
@@ -0,0 +1,3 @@
+$PSMPERL_PLUGIN_OPT
+--loose-plugin-load=perl=$PSMPERL_PLUGIN
+--loose-plugin-perl-module-path=$PSMPERL_PLUGIN_DIR
diff -Nrup a/mysql-test/t/plugin_psm_perl.test b/mysql-test/t/plugin_psm_perl.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm_perl.test 2008-02-22 17:05:13 -08:00
@@ -0,0 +1,88 @@
+--source include/have_psmperl_plugin.inc
+
+# Simple test of passing and returning a value
+#
+CREATE FUNCTION test.PerlReverse(source TEXT) RETURNS TEXT
+ LANGUAGE Perl NO SQL
+ EXTERNAL NAME 'MyUDFExample::my_reverse';
+
+SELECT test.PerlReverse("Hello World") FROM DUAL;
+
+DROP FUNCTION test.PerlReverse;
+
+
+# Simple test of passing values by reference
+#
+CREATE PROCEDURE test.PerlReverse2(INOUT source TEXT)
+ LANGUAGE Perl NO SQL
+ EXTERNAL NAME 'MyUDFExample::my_reverseproc';
+SET @testvar='Another test';
+CALL test.PerlReverse2(@testvar);
+SELECT @testvar;
+DROP PROCEDURE test.PerlReverse2;
+
+
+#CREATE FUNCTION test.PigLatin(source TEXT) RETURNS TEXT
+# LANGUAGE Java NO SQL
+# EXTERNAL NAME 'MyUDFExample::toPigLatin';
+#
+#SELECT test.PigLatin("Hello World") FROM DUAL;
+#SELECT test.PigLatin("A simple test of Perl user defined functions") AS foo;
+#
+#DROP FUNCTION test.PigLatin;
+
+
+# Simple test for routine which returns a small hash of scalars
+#
+CREATE PROCEDURE test.TestHashResults()
+ LANGUAGE Perl NO SQL
+ DYNAMIC RESULT SETS 1
+ EXTERNAL NAME 'MyUDFExample::testhashresults';
+CALL test.TestHashResults();
+DROP PROCEDURE test.TestHashResults;
+
+
+# Simple test for routine which returns a small array of hashes
+#
+CREATE PROCEDURE test.TestArrayHashResults()
+ LANGUAGE Perl NO SQL
+ DYNAMIC RESULT SETS 1
+ EXTERNAL NAME 'MyUDFExample::testarrayhashresults';
+CALL test.TestArrayHashResults();
+DROP PROCEDURE test.TestArrayHashResults;
+
+
+# Test a Perl routine which returns an Array of Scalars
+#
+CREATE PROCEDURE test.PerlPrimes1(top_limit INT)
+ LANGUAGE Perl NO SQL
+ DYNAMIC RESULT SETS 1
+ EXTERNAL NAME 'MyUDFExample::testprimes';
+
+CALL test.PerlPrimes1(100);
+
+DROP PROCEDURE test.PerlPrimes1;
+
+
+# Test a Perl routine which returns an Array of Hashes
+#
+CREATE PROCEDURE test.PerlPrimes2(top_limit INT)
+ LANGUAGE Perl NO SQL
+ DYNAMIC RESULT SETS 1
+ EXTERNAL NAME 'MyUDFExample::testprimes_vertical';
+
+CALL test.PerlPrimes2(100);
+
+DROP PROCEDURE test.PerlPrimes2;
+
+
+# Test a Perl routine which returns an Array within an Array
+#
+CREATE PROCEDURE test.matrix(top_limit INT)
+ LANGUAGE Perl NO SQL
+ DYNAMIC RESULT SETS 1
+ EXTERNAL NAME 'MyUDFExample::testmatrix';
+
+CALL test.matrix(10);
+
+DROP PROCEDURE test.matrix;
diff -Nrup a/mysql-test/t/plugin_psm_perl_dbi-master.opt b/mysql-test/t/plugin_psm_perl_dbi-master.opt
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm_perl_dbi-master.opt 2008-02-22 17:05:13 -08:00
@@ -0,0 +1,3 @@
+$PSMPERL_PLUGIN_OPT
+--loose-plugin-load=perl=$PSMPERL_PLUGIN
+--loose-plugin-perl-module-path=$PSMPERL_PLUGIN_DIR
diff -Nrup a/mysql-test/t/plugin_psm_perl_dbi.test b/mysql-test/t/plugin_psm_perl_dbi.test
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/plugin_psm_perl_dbi.test 2008-02-22 17:05:13 -08:00
@@ -0,0 +1,30 @@
+--source include/have_psmperl_plugin.inc
+
+# Detect if DBD::mysql is available
+
+disable_query_log;
+CREATE FUNCTION test.have_dbd_mysql() RETURNS INT
+ LANGUAGE Perl NO SQL
+ EXTERNAL NAME 'MySQLUDF::test_dbd_mysql';
+--require r/true.require
+SELECT test.have_dbd_mysql() = '1' AS `TRUE`;
+DROP FUNCTION test.have_dbd_mysql;
+enable_query_log;
+
+# Now for the actual test
+
+CREATE TABLE test.t1 (seq INT NOT NULL AUTO_INCREMENT PRIMARY KEY, txt VARCHAR(128));
+
+CREATE PROCEDURE test.test1()
+ LANGUAGE Perl MODIFIES SQL DATA
+ EXTERNAL NAME 'MyDBIExample::test1';
+
+#if this doesn't work as expected, it will deadlock
+LOCK TABLE test.t1 WRITE;
+CALL test.test1();
+UNLOCK TABLES;
+
+SELECT * from test.t1;
+
+DROP PROCEDURE test.test1;
+DROP TABLE test.t1;
diff -Nrup a/plugin/example_udf/Makefile.am b/plugin/example_udf/Makefile.am
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/example_udf/Makefile.am 2008-02-22 17:05:13 -08:00
@@ -0,0 +1,58 @@
+# Copyright (C) 2007 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#called from the top level Makefile
+
+if THREAD_SAFE_CLIENT
+LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql_r/libmysqlclient_r.la
+else
+LIBMYSQLCLIENT_LA = $(top_builddir)/libmysql/libmysqlclient.la
+endif
+
+MYSQLDATAdir = $(localstatedir)
+MYSQLSHAREdir = $(pkgdatadir)
+MYSQLBASEdir= $(prefix)
+MYSQLLIBdir= $(pkglibdir)
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/regex \
+ -I$(top_srcdir)/sql \
+ -I$(srcdir)
+WRAPLIBS=
+
+LDADD =
+
+DEFS = @DEFS@
+
+noinst_HEADERS =
+
+EXTRA_LTLIBRARIES = psm_example.la
+pkglib_LTLIBRARIES = @plugin_psmlang_example_shared_target@
+psm_example_la_LDFLAGS =-module -rpath $(MYSQLLIBdir)
+psm_example_la_LIBADD = $(LDADD) $(LIBMYSQLCLIENT_LA)
+psm_example_la_CXXFLAGS=$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+psm_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+psm_example_la_SOURCES =psm_example.c
+
+
+EXTRA_LIBRARIES = libpsmexample.a
+noinst_LIBRARIES = @plugin_psmlang_example_static_target@
+libpsmexample_a_CXXFLAGS =$(AM_CFLAGS)
+libpsmexample_a_CFLAGS =$(AM_CFLAGS)
+libpsmexample_a_SOURCES=psm_example.c
+
+
+EXTRA_DIST = plug.in
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff -Nrup a/plugin/example_udf/plug.in b/plugin/example_udf/plug.in
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/example_udf/plug.in 2008-02-22 17:05:13 -08:00
@@ -0,0 +1,4 @@
+MYSQL_PLUGIN(psmlang_example, [Simple PSM Language Example],
+ [External Language Stored Procedure Demonstration plugin])
+MYSQL_PLUGIN_DYNAMIC(psmlang_example, [psm_example.la])
+MYSQL_PLUGIN_STATIC(psmlang_example, [libpsmexample.la])
diff -Nrup a/plugin/example_udf/psm_example.c b/plugin/example_udf/psm_example.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/example_udf/psm_example.c 2008-02-22 17:05:13 -08:00
@@ -0,0 +1,337 @@
+/* Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_ctype.h>
+#include <m_string.h>
+#include <mysql.h>
+#include <mysql/plugin.h>
+#include <mysqld_error.h>
+
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __attribute__(A)
+#endif
+
+typedef int (*dispatch_ptr)(MYSQL_PSM_ROUTINE handle, MYSQL_PSM_CONTEXT context);
+
+struct st_mysql_psmroutine
+{
+ dispatch_ptr dispatch;
+ char answer[64];
+};
+
+static char *ultimate_answer;
+
+static MYSQL_THDVAR_ULONG(call_count,
+ PLUGIN_VAR_RQCMDARG,
+ "Count of executions",
+ NULL, NULL, 0L, 0L, ~0L, 0);
+
+static long number_of_finds= 0; /* for SHOW STATUS, see below */
+
+
+static int test_func_1(MYSQL_PSM_ROUTINE handle, MYSQL_PSM_CONTEXT context);
+static int test_func_2(MYSQL_PSM_ROUTINE handle, MYSQL_PSM_CONTEXT context);
+
+
+/*
+ Initialize the PSM plugin at server start or plugin installation.
+
+ SYNOPSIS
+ simple_psm_plugin_init()
+
+ DESCRIPTION
+ Does nothing.
+
+ RETURN VALUE
+ 0 success
+ 1 failure (cannot happen)
+*/
+
+static int simple_psm_plugin_init(void *arg __attribute__((unused)))
+{
+ if (mysql_library_init(0,0,0))
+ return(-1);
+ return(0);
+}
+
+
+/*
+ Terminate the PSM plugin at server shutdown or plugin deinstallation.
+
+ SYNOPSIS
+ simple_psm_plugin_deinit()
+ Does nothing.
+
+ RETURN VALUE
+ 0 success
+ 1 failure (cannot happen)
+
+*/
+
+static int simple_psm_plugin_deinit(void *arg __attribute__((unused)))
+{
+ /*mysql_library_end();*/
+ return(0);
+}
+
+
+static int simple_psm_find(MYSQL_PSM_ROUTINE *handle,
+ const char *name, int name_length)
+{
+ dispatch_ptr dispatch= NULL;
+ number_of_finds++;
+
+ if (name_length == 7 && !strncasecmp(name, "compute", 7))
+ dispatch= test_func_1;
+ if (name_length == 8 && !strncasecmp(name, "loopback", 8))
+ dispatch= test_func_2;
+
+ if (dispatch)
+ {
+ *handle= (MYSQL_PSM_ROUTINE) malloc(sizeof(struct st_mysql_psmroutine));
+ bzero(*handle, sizeof(struct st_mysql_psmroutine));
+ strxnmov((*handle)->answer, sizeof((*handle)->answer) - 1,
+ ultimate_answer, NullS);
+ (*handle)->dispatch= dispatch;
+ return 0;
+ }
+ return -1;
+}
+
+
+static int simple_psm_execute(MYSQL_PSM_ROUTINE handle,
+ MYSQL_PSM_CONTEXT context)
+{
+ int result;
+ THDVAR(context->thd, call_count)++;
+
+ result= handle->dispatch(handle, context);
+
+ return result;
+}
+
+static int simple_psm_release(MYSQL_PSM_ROUTINE handle)
+{
+ free(handle);
+ return 0;
+};
+
+
+static int test_func_1(MYSQL_PSM_ROUTINE handle, MYSQL_PSM_CONTEXT context)
+{
+ if (context->cb->row_field(context,
+ "Answer to Life, the Universe and Everything",
+ MYSQL_TYPE_STRING, 64, 0))
+ goto err;
+
+ if (context->cb->row_prepare(context))
+ goto err;
+
+ context->cb->store_string(context, -1, handle->answer,
+ strlen(handle->answer), NULL);
+ context->cb->row_send(context);
+ context->cb->row_send_eof(context);
+
+ return 0;
+err:
+ return -1;
+}
+
+
+static int test_func_2(MYSQL_PSM_ROUTINE handle __attribute__ ((unused)),
+ MYSQL_PSM_CONTEXT context)
+{
+ MYSQL mysql;
+ MYSQL_RES *res= 0;
+ MYSQL_FIELD *fields;
+ MYSQL_ROW row;
+ unsigned int num_fields, i;
+ int result= -1;
+
+ if (!mysql_init(&mysql))
+ {
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "Failed during call to mysql_init, should not happen");
+ goto err;
+ }
+
+ mysql_options(&mysql, MYSQL_OPT_USE_INLINE_CONNECTION, NULL);
+
+ if (context->arg_count == 1)
+ {
+ char buffer[FN_REFLEN+1];
+ const char *query;
+ unsigned int query_length= sizeof(buffer) - 1;
+ CHARSET_INFO *cs;
+
+ query= context->cb->val_string(context, 0, buffer, &query_length, &cs);
+ if (query != buffer && query_length < sizeof(buffer) - 1)
+ {
+ strmake(buffer, query, query_length);
+ query= buffer;
+ }
+
+ if (query != buffer)
+ {
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "Query too large");
+ goto err;
+ }
+
+ if (!mysql_real_connect(&mysql, 0, 0, 0, 0, 0, 0, CLIENT_MULTI_STATEMENTS))
+ {
+ my_error(mysql_errno(&mysql), MYF(0), mysql_error(&mysql));
+ goto err;
+ }
+
+ if (mysql_query(&mysql, query))
+ {
+ my_error(mysql_errno(&mysql), MYF(0), mysql_error(&mysql));
+ goto err;
+ }
+ }
+ else
+ {
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "Only 1 parameter accepted");
+ goto err;
+ }
+
+ for (;;)
+ {
+ if (!(res= mysql_store_result(&mysql)))
+ break;
+
+ num_fields= mysql_num_fields(res);
+ fields= mysql_fetch_fields(res);
+
+ for (i= 0; i < num_fields; i++)
+ {
+ if (context->cb->row_field(context, fields[i].name,
+ MYSQL_TYPE_STRING, fields[i].max_length, 0))
+ {
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "Failed during call to row_field()");
+ goto err;
+ }
+ }
+
+ while ((row= mysql_fetch_row(res)))
+ {
+ unsigned long *lengths;
+
+ if (context->cb->row_prepare(context))
+ {
+ my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+ "Failed during call to row_prepare()");
+ goto err;
+ }
+ lengths= mysql_fetch_lengths(res);
+
+ for (i= 0; i < num_fields; i++)
+ {
+ if (!row[i])
+ context->cb->store_null(context, -1);
+ else
+ {
+ CHARSET_INFO *cs= &my_charset_latin1;
+ context->cb->store_string(context, -1, row[i], lengths[i], cs);
+ }
+ }
+
+ context->cb->row_send(context);
+ }
+
+ context->cb->row_send_eof(context);
+
+ if (!mysql_more_results(&mysql))
+ break;
+
+ mysql_free_result(res);
+ res= NULL;
+
+ if (mysql_next_result(&mysql))
+ break;
+ }
+
+ result= 0;
+
+err:
+ mysql_free_result(res);
+ mysql_close(&mysql);
+ return result;
+}
+
+
+/*
+ Plugin type-specific descriptor
+*/
+
+static struct st_mysql_psmlanguage simple_psm_descriptor=
+{
+ MYSQL_PSM_LANGUAGE_INTERFACE_VERSION, /* interface version */
+ simple_psm_find, /* function resolution function */
+ simple_psm_release, /* function release function */
+ simple_psm_execute /* execute function */
+};
+
+/*
+ Plugin status variables for SHOW STATUS
+*/
+
+static struct st_mysql_show_var simple_status[]=
+{
+ {"find_count", (char *)&number_of_finds, SHOW_LONG},
+ {0,0,0}
+};
+
+/*
+ Plugin system variables.
+*/
+
+static MYSQL_SYSVAR_STR(response, ultimate_answer,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "The answer of Deep Thought's calculation",
+ NULL, NULL, "Forty-Two");
+
+static struct st_mysql_sys_var* system_variables[]= {
+ MYSQL_SYSVAR(call_count),
+ MYSQL_SYSVAR(response),
+ NULL
+};
+
+/*
+ Plugin library descriptor
+*/
+
+mysql_declare_plugin(ftexample)
+{
+ MYSQL_PSMLANGUAGE_PLUGIN, /* type */
+ &simple_psm_descriptor, /* descriptor */
+ "Deep_Thought", /* name */
+ "MySQL AB", /* author */
+ "Simple PSM Language Demo", /* description */
+ PLUGIN_LICENSE_GPL,
+ simple_psm_plugin_init, /* init function (when loaded) */
+ simple_psm_plugin_deinit, /* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ system_variables, /* system variables */
+ NULL
+}
+mysql_declare_plugin_end;
+
diff -Nrup a/plugin/java_udf/Makefile.am b/plugin/java_udf/Makefile.am
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/Makefile.am 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,143 @@
+# Copyright (C) 2007 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#called from the top level Makefile
+
+MYSQLDATAdir = $(localstatedir)
+MYSQLSHAREdir = $(pkgdatadir)
+MYSQLBASEdir= $(prefix)
+MYSQLLIBdir= $(pkglibdir)
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/regex \
+ -I$(top_srcdir)/sql \
+ -I$(srcdir)
+WRAPLIBS=
+
+sourcesdir= $(srcdir)
+SOURCEPATH= -sourcepath $(srcdir)
+CLASSPATH= -classpath $(builddir):$(srcdir)/mysql-connector-java-6.0-nightly-bin.jar
+JAR= $(JAVA_BIN)/jar
+
+LDADD =
+
+DEFS = @DEFS@
+
+#noinst_PROGRAMS = jbyte_array_test jvm_singleton_test native_jvm_test \
+# java_context_test
+noinst_PROGRAMS = java_udf.jar java_udf_util.jar java_udf_example.jar
+noinst_HEADERS = java_context.h jbyte_array.h jvm_singleton.h \
+ java_object_parameter.h jobject_wrapper.h \
+ native_jvm.h java_util_arraylist.h \
+ jnilinkage.h jnicallback.h jniutils.h \
+ jvm_interface.h test_utils.h
+
+java_udf_source= java_udf.cc java_context.cc jbyte_array.cc \
+ native_jvm.cc java_object_parameter.cc \
+ jobject_wrapper.cc jvm_interface.cc \
+ java_util_arraylist.cc jvm_singleton.cc jnicallback.cc \
+ jniutils.cc
+
+EXTRA_LTLIBRARIES= psm_java.la
+pkglib_LTLIBRARIES= @plugin_java_udf_shared_target@
+psm_java_la_LDFLAGS= -module -rpath $(MYSQLLIBdir) $(JAVA_LDFLAGS)
+psm_java_la_CXXFLAGS= $(AM_CFLAGS) $(JAVA_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+psm_java_la_CFLAGS= $(AM_CFLAGS) $(JAVA_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+psm_java_la_SOURCES= $(java_udf_source)
+
+
+EXTRA_DIST = plug.in jvm_options.cnf.in grokjni.pl
+BUILT_SOURCES= jnilinkage.h jnicallback.h
+
+java_udf_example_jar_sources= \
+ com/mysql/udf/example/Primes.java \
+ com/mysql/udf/example/PigLatin.java \
+ com/mysql/udf/example/Reverse.java
+
+java_udf_util_jar_sources= \
+ com/mysql/udf/util/ThrowingResultSet.java \
+ com/mysql/udf/util/ThrowingResultSetMetaData.java \
+ com/mysql/udf/util/SimpleResultSet.java \
+ com/mysql/udf/util/Misc.java \
+ com/mysql/udf/util/NotImplementedException.java
+
+java_udf_jar_sources= \
+ com/mysql/udf/NativeRow.java \
+ com/mysql/udf/NativeRowData.java \
+ com/mysql/udf/MysqlIOtype2.java \
+ com/mysql/udf/InternalType.java \
+ com/mysql/udf/FunctionDescriptor.java \
+ com/mysql/udf/Invoker.java \
+ com/mysql/udf/ParameterClassFinder.java \
+ com/mysql/udf/UDFException.java \
+ com/mysql/udf/NativeUDFCallback.java \
+ com/mysql/udf/DataMarshal.java \
+ com/mysql/udf/UDFCallback.java \
+ com/mysql/udf/Context.java \
+ com/mysql/udf/ParsedFunction.java \
+ com/mysql/udf/UDFModule.java \
+ com/mysql/udf/LifeCycle.java
+
+sources_JAVA= \
+ $(udf_java_jar_sources) $(udf_java_util_jar_sources) \
+ $(udf_java_example_jar_sources)
+
+java_udf_jar_classes= $(java_udf_jar_sources:.java=.class)
+java_udf_util_jar_classes= $(java_udf_util_jar_sources:.java=.class)
+java_udf_example_jar_classes= $(java_udf_example_jar_sources:.java=.class)
+
+
+jnicallback.h: com/mysql/udf/NativeUDFCallback.class
+ $(JAVAH) $(CLASSPATH) -jni -o $@ com.mysql.udf.NativeUDFCallback
+
+.java.class:
+ $(JAVAC) $(CLASSPATH) $(SOURCEPATH) $<
+
+java_udf.jar: $(java_udf_jar_classes)
+ $(JAR) cvf $@ com/mysql/udf/*.class
+
+java_udf_util.jar: $(java_udf_util_jar_classes)
+ $(JAR) cvf $@ com/mysql/udf/util/*.class
+
+java_udf_example.jar: $(java_udf_example_jar_classes)
+ $(JAR) cvf $@ com/mysql/udf/example/*.class
+
+jnilinkage.h: jnicallback.h
+ $(PERL) $(srcdir)/grokjni.pl < $< > $@
+
+test: jbyte_array_test jvm_singleton_test native_jvm_test java_context_test
+ ./jbyte_array_test
+ ./jvm_singleton_test
+ ./native_jvm_test
+ ./java_context_test $(JVM_OPTIONS_FILE)
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.InvokerTest
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.UDFModuleTest
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.JniSimulationTest
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.FunctionDescriptorTest
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.ParameterClassFinderTest
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.ParsedFunctionTest
+ $(JAVA) $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.QuickAffirmationsTest
+
+install-sourcesJAVA: classsources.stamp
+ $(INSTALL_DATA) java_udf.jar "$(DESTDIR)$(pkglibdir)/"
+ $(INSTALL_DATA) java_udf_util.jar "$(DESTDIR)$(pkglibdir)/"
+ $(INSTALL_DATA) java_udf_example.jar "$(DESTDIR)$(pkglibdir)/"
+
+
+clean-local:
+ -find $(builddir) -name '*.class' | xargs rm
+ -rm -f $(BUILT_SOURCES) $(noinst_PROGRAMS)
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff -Nrup a/plugin/java_udf/Makefile.eric b/plugin/java_udf/Makefile.eric
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/Makefile.eric 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,133 @@
+#/* Copyright (C) 2005 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+# ------
+# JDK
+# ------
+
+#OS X
+JDK=/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2
+export LD_LIBRARY_PATH=$(JDK)/home/lib
+JNI_CFLAGS=-I$(JDK)/Headers
+JNI_LFLAGS=-L$(JDK)/Libraries -lverify -ljvm
+MISC=-framework JavaVM
+
+#IBM JDK
+#JDK=/home/java/IBMJava2-141
+#export LD_LIBRARY_PATH=$(JDK)/jre/bin:$(JDK)/jre/bin/classic
+#JNI_CFLAGS=-I$(JDK)/include
+#JNI_LFLAGS=-L$(JDK)/jre/bin -ljava -lhpi -ljsig -L$(JDK)/jre/bin/classic -ljvm
+#MISC=
+
+#SUN JDK (server)
+#JDK=/home/java/j2sdk1.4.2_07
+#JDK=/home/java/jdk1.5.0_05
+#export LD_LIBRARY_PATH=$(JDK)/jre/lib/i386:$(JDK)/jre/lib/i386/server
+#JNI_CFLAGS=-I$(JDK)/include -I$(JDK)/include/linux
+#JNI_LFLAGS=-L$(JDK)/jre/lib/i386 -ljava -lverify -ljsig -L$(JDK)/jre/lib/i386/server -ljvm
+#MISC=
+
+#SUN JDK (client)
+#JDK=/home/java/j2sdk1.4.2_07
+#export LD_LIBRARY_PATH=$(JDK)/jre/lib/i386:$(JDK)/jre/lib/i386/client
+#JNI_CFLAGS=-I$(JDK)/include -I$(JDK)/include/linux
+#JNI_LFLAGS=-L$(JDK)/jre/lib/i386 -ljava -lverify -ljsig -L$(JDK)/jre/lib/i386/client -ljvm
+#MISC=
+
+#SUN JDK (client) FreeBSD
+#JDK=/usr/local/jdk1.4.2
+#export LD_LIBRARY_PATH=$(JDK)/jre/lib/i386:$(JDK)/jre/lib/i386/client
+#JNI_CFLAGS=-I$(JDK)/include -I$(JDK)/include/freebsd
+#JNI_LFLAGS=-L$(JDK)/jre/lib/i386 -ljava -lverify -ljsig -L$(JDK)/jre/lib/i386/client -ljvm -lpthread
+#MISC=
+
+# --------
+# END JDK
+# --------
+
+CC=g++
+CFLAGS_MISC=-g -Wall -Woverloaded-virtual -O0 -MMD -DUDFTEST
+LFLAGS_MISC=./test_util_lib.a ./jni_lib.a
+
+MYSQL_CFLAGS=-I/home/eric/src/mysql-5.2-eric+antony/include
+MYSQL_LFLAGS=
+
+CFLAGS=$(CFLAGS_MISC) $(JNI_CFLAGS) $(MYSQL_CFLAGS)
+LFLAGS=$(LFLAGS_MISC) $(JNI_LFLAGS) $(MYSQL_LFLAGS)
+
+JUNIT_JAR=/home/eric/libs/junit.jar
+CLASSPATH=-classpath .:$(JUNIT_JAR)
+JVM_OPTIONS_FILE=./jvm_options.cnf
+
+JNI_TARGET=jni_lib.a
+JNI_OBJS=jbyte_array.o java_context.o jvm_interface.o native_jvm.o jvm_singleton.o java_object_parameter.o jobject_wrapper.o
+
+TEST_LIB_TARGET=test_util_lib.a
+TEST_OBJS=test_utils.o java_util_arraylist.o
+
+#Dependency files are autogenerated
+#DEPS=$(JNI_OBJS:%.o=%.d) $(TEST_OBJS:%.o=%.d)
+
+PROGS=jbyte_array_test jvm_singleton_test native_jvm_test java_context_test
+# ------------------------------------------------------------
+all: clean java $(TEST_LIB_TARGET) $(JNI_TARGET) $(PROGS) test
+
+java:
+ javac $(CLASSPATH) com/mysql/jnitest/*.java
+ javac $(CLASSPATH) com/mysql/udf/*.java
+ javac $(CLASSPATH) com/mysql/udf/test/*.java
+ javah $(CLASSPATH) -jni com.mysql.udf.NativeUDFCallback
+
+$(TEST_LIB_TARGET): $(TEST_OBJS)
+ ar rc $@ $(TEST_OBJS)
+ ranlib $@
+
+$(JNI_TARGET): $(JNI_OBJS)
+ ar rc $@ $(JNI_OBJS)
+ ranlib $@
+
+
+%.o: %.cc # could include here also: ../include/%.h
+ $(CC) $(CFLAGS) -c $*.cc
+
+%: %.cc
+ $(CC) $(CFLAGS) $*.cc $(LFLAGS) -o $* $(MISC)
+
+#plugin:
+# #TODO: make java_udf.c into a c++ guy
+# gcc -c $(CFLAGS) java_udf.c $(LFLAGS) -o java_udf.o $(MISC)
+# ar rcs lib_java_udf.a java_udf.o
+
+clean:
+ rm -f *.d *.o *.a hs_err_pid*.log *~ $(PROGS) com_mysql_udf_NativeUDFCallback.h
+ (find . -name \*.class | xargs rm) || true
+
+test:
+ ./jbyte_array_test
+ ./jvm_singleton_test
+ ./native_jvm_test
+ ./java_context_test $(JVM_OPTIONS_FILE)
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.InvokerTest
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.UDFModuleTest
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.JniSimulationTest
+ # other Java Tests
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.FunctionDescriptorTest
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.ParameterClassFinderTest
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.ParsedFunctionTest
+ java $(CLASSPATH) junit.textui.TestRunner com.mysql.udf.test.QuickAffirmationsTest
+ #"TODO: write test harness and tests for java_udf.cc"
+
diff -Nrup a/plugin/java_udf/com/mysql/jnitest/TestObject.java b/plugin/java_udf/com/mysql/jnitest/TestObject.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/jnitest/TestObject.java 2008-02-22 17:05:19 -08:00
@@ -0,0 +1,110 @@
+package com.mysql.jnitest;
+
+public class TestObject extends Object {
+ public static final TestObject instance = new TestObject("Static");
+
+ private Object data0;
+
+ public TestObject() {
+ this("No Args");
+ }
+
+ public TestObject(String arg0) {
+ this.data0 = arg0;
+ }
+
+ public TestObject(TestObject arg0) {
+ this.data0 = arg0 == null ? null : arg0.getData();
+ }
+
+ public TestObject(TestObject arg0, String arg1, String arg2) {
+ this.data0 = "[" + arg0 + "] " + arg1 + " " + arg2;
+ }
+
+ public TestObject(TestObject arg0, String[] arg1, String arg2) {
+ this.data0 = "[" + arg0 + "] " + asString(arg1) + " " + arg2;
+ }
+
+ public TestObject(String arg0, String arg1, String arg2, String arg3) {
+ this.data0 = arg0 + " " + arg1 + " " + arg2 + " " + arg3;
+ }
+
+ public TestObject(long arg0) {
+ this.data0 = Long.toString(arg0);
+ }
+
+ private final StringBuffer asString(String[] strs) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("[");
+ for (int i = 0; i < strs.length; i++) {
+ if (i > 0) {
+ buf.append(", ");
+ }
+ buf.append(strs[i]);
+ }
+ buf.append("]");
+ return buf;
+ }
+
+ public Object getData() {
+ return data0;
+ }
+
+ public void resetData() {
+ setData("reset");
+ }
+
+ public void setData(String data) {
+ this.data0 = data;
+ }
+
+ public void setData(int arg0, byte[] arg1) {
+ this.data0 = "" + arg0 + new String(arg1);
+ }
+
+ public void setData(TestObject obj) {
+ setData("[" + obj + "]");
+ }
+
+ public void setData(String[] strs) {
+ setData(asString(strs).toString());
+ }
+
+ public void setData(boolean bool, String str1, String str2, TestObject obj) {
+ setData(bool + " " + str1 + " " + str2 + " [" + obj + "]");
+ }
+
+ public byte[] toBytes(String byteMe) {
+ return byteMe == null ? null : byteMe.getBytes();
+ }
+
+ public byte[] toBytes(int byteMe) {
+ return toBytes("" + byteMe);
+ }
+
+ public int dataLength() {
+ return toString().length();
+ }
+
+ public int dataLength(String chars) {
+ return (chars == null) ? -1 : chars.length();
+ }
+
+ public boolean even() {
+ return (toString().length() % 2) == 0;
+ }
+
+ public void copyBack(TestObject obj, String[] result, String arg) {
+ result[0] = "[" + obj + "] " + arg;
+ }
+
+ public String toString() {
+ new StringBuffer("").append("foo");
+ if (data0 == null) {
+ System.err.println("why is data null?");
+ } else if (data0.equals("")) {
+ System.err.println("why is data empty?");
+ }
+ return "" + data0;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/Context.java b/plugin/java_udf/com/mysql/udf/Context.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/Context.java 2008-02-22 17:05:19 -08:00
@@ -0,0 +1,15 @@
+package com.mysql.udf;
+
+public interface Context {
+ /*
+ * Antony sees us as eventually needing these funcitons, but I'm leaving
+ * them out for the moment.
+ *
+ * I agree with him, but for the moment it looks like complexity which is
+ * not pulling its weight.
+ */
+
+ // Object getAttribute(String name);
+ // List getAttributeNames();
+ // getMysqlVersion();
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/DataMarshal.java b/plugin/java_udf/com/mysql/udf/DataMarshal.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/DataMarshal.java 2008-02-22 17:05:19 -08:00
@@ -0,0 +1,247 @@
+package com.mysql.udf;
+
+import java.math.BigDecimal;
+
+public class DataMarshal {
+ private UDFCallback callback;
+
+ private FunctionDescriptor fd;
+
+ public DataMarshal(FunctionDescriptor fd, UDFCallback callback) {
+ this.callback = callback;
+ this.fd = fd;
+ fd.setArgumentCount(callback.getArgumentCount());
+ }
+
+ public Object newInstance() {
+ return fd.newInstance();
+ }
+
+ public Object invoke(Object instance) {
+ Object value;
+ Object[] callingArguments = getArgumentValues();
+ value = fd.invoke(instance, callingArguments);
+ setArguments(callingArguments);
+ return value;
+ }
+
+ private void setArguments(Object[] callingArguments) {
+ for (int i = 0; i < callingArguments.length; i++) {
+ setArgument(i, callingArguments[i]);
+ }
+ }
+
+ private Object[] getArgumentValues() {
+ // System.err.println("X");
+ Object[] args = new Object[fd.numberOfArguments()];
+ // System.err.println("args: " + args.length);
+ for (int i = 0; i < args.length; i++) {
+ // System.err.println("i");
+ args[i] = getArgument(i);
+ // System.err.println(args[i]);
+ }
+ return args;
+ }
+
+ private void setArgument(int i, Object arg) {
+ if (arg instanceof long[]) {
+ setArgumentInner(i, new Long(((long[]) arg)[0]));
+ } else if (arg instanceof int[]) {
+ setArgumentInner(i, new Long(((int[]) arg)[0]));
+ } else if (arg instanceof short[]) {
+ setArgumentInner(i, new Long(((short[]) arg)[0]));
+ } else if (arg instanceof byte[]) {
+ setArgumentInner(i, new Long(((byte[]) arg)[0]));
+ } else if (arg instanceof double[]) {
+ setArgumentInner(i, new Double(((double[]) arg)[0]));
+ } else if (arg instanceof float[]) {
+ setArgumentInner(i, new Double(((float[]) arg)[0]));
+ } else if (arg instanceof Object[]) {
+ setArgumentInner(i, ((Object[]) arg)[0]);
+ } else {
+ // not a OUT or IN/OUT parameter
+ }
+ }
+
+ private void setArgumentInner(int argIndex, Object value) {
+ if (value == null) {
+ callback.setNullArgument(argIndex);
+ } else if (value instanceof Byte || value instanceof Short
+ || value instanceof Integer || value instanceof Long) {
+ callback.setLongArgument(argIndex, ((Number) value).longValue());
+ } else if (value instanceof String) {
+ callback.setStringArgument(argIndex, value.toString());
+ } else if (value instanceof Double || value instanceof Float) {
+ callback
+ .setDoubleArgument(argIndex, ((Number) value).doubleValue());
+ } else if (value instanceof BigDecimal) {
+ callback.setBigDecimalArgument(argIndex, (BigDecimal) value);
+ } else {
+ callback.setStringArgument(argIndex, value.toString());
+ }
+ }
+
+ public void storeResult(Object value) {
+ if (value == null) {
+ callback.storeResultNull();
+ } else if (value instanceof Byte || value instanceof Short
+ || value instanceof Integer || value instanceof Long) {
+ callback.storeResultLong(((Number) value).longValue());
+ } else if (value instanceof String) {
+ callback.storeResultString((String) value);
+ } else if (value instanceof Double || value instanceof Float) {
+ callback.storeResultDouble(((Number) value).doubleValue());
+ } else if (value instanceof BigDecimal) {
+ callback.storeResultBigDecimal((BigDecimal) value);
+ } else {
+ callback.storeResultString(value.toString());
+ // throw new IllegalArgumentException(value + "is of type"
+ // + value.getClass());
+ }
+ }
+
+ private Object getArgument(int argIndex) {
+ // System.err.println("getArgument:" + argIndex);
+ Class argClass = fd.getArgumentClass(argIndex);
+
+ if (isArray(argClass)) {
+ return getArrayArgument(argIndex, argClass);
+ }
+
+ Object x = getArgument(argIndex, argClass);
+ // System.err.println("getArgument returns:" + x);
+
+ return x;
+ }
+
+ private Object getArrayArgument(int argIndex, Class argClass) {
+ if (argClass == long[].class) {
+ long[] arg = new long[1];
+ arg[0] = ((Long) getArgument(argIndex, Long.TYPE)).longValue();
+ return arg;
+ }
+ if (argClass == Long[].class) {
+ Long[] arg = new Long[1];
+ arg[0] = ((Long) getArgument(argIndex, Long.class));
+ return arg;
+ }
+ if (argClass == int[].class) {
+ int[] arg = new int[1];
+ arg[0] = ((Integer) getArgument(argIndex, Integer.TYPE)).intValue();
+ return arg;
+ }
+ if (argClass == Integer[].class) {
+ Integer[] arg = new Integer[1];
+ arg[0] = ((Integer) getArgument(argIndex, Integer.class));
+ return arg;
+ }
+ if (argClass == short[].class) {
+ short[] arg = new short[1];
+ arg[0] = ((Short) getArgument(argIndex, Short.TYPE)).shortValue();
+ return arg;
+ }
+ if (argClass == Short[].class) {
+ Short[] arg = new Short[1];
+ arg[0] = ((Short) getArgument(argIndex, Short.class));
+ return arg;
+ }
+ if (argClass == byte[].class) {
+ byte[] arg = new byte[1];
+ arg[0] = ((Byte) getArgument(argIndex, Byte.TYPE)).byteValue();
+ return arg;
+ }
+ if (argClass == Byte[].class) {
+ Byte[] arg = new Byte[1];
+ arg[0] = ((Byte) getArgument(argIndex, Byte.class));
+ return arg;
+ }
+
+ if (argClass == String[].class) {
+ String[] arg = new String[1];
+ arg[0] = ((String) getArgument(argIndex, String.class));
+ return arg;
+ }
+
+ if (argClass == double[].class) {
+ double[] arg = new double[1];
+ arg[0] = ((Double) getArgument(argIndex, Double.TYPE))
+ .doubleValue();
+ return arg;
+ }
+ if (argClass == Double[].class) {
+ Double[] arg = new Double[1];
+ arg[0] = ((Double) getArgument(argIndex, Double.class));
+ return arg;
+ }
+
+ if (argClass == float[].class) {
+ float[] arg = new float[1];
+ arg[0] = ((Float) getArgument(argIndex, Float.TYPE)).floatValue();
+ return arg;
+ }
+ if (argClass == Float[].class) {
+ Float[] arg = new Float[1];
+ arg[0] = ((Float) getArgument(argIndex, Float.class));
+ return arg;
+ }
+
+ if (argClass == BigDecimal[].class) {
+ BigDecimal[] arg = new BigDecimal[1];
+ arg[0] = ((BigDecimal) getArgument(argIndex, BigDecimal.class));
+ return arg;
+ }
+
+ if (argClass == Object[].class) {
+ Object[] arg = new Object[1];
+ arg[0] = getArgument(argIndex, Object.class);
+ return arg;
+ }
+
+ throw new UDFException("Unknown Array Type: " + argClass);
+ }
+
+ private boolean isArray(Class argClass) {
+ return argClass.getName().startsWith("[");
+ }
+
+ private Object getArgument(int argIndex, Class argClass) {
+ if (callback.isArgumentNull(argIndex)) {
+ return null;
+ }
+ if (argClass == Long.class || argClass == Long.TYPE) {
+ return new Long(callback.getLongArgument(argIndex));
+ }
+ if (argClass == Integer.class || argClass == Integer.TYPE) {
+ return new Integer((int) callback.getLongArgument(argIndex));
+ }
+ if (argClass == Short.class || argClass == Short.TYPE) {
+ return new Short((short) callback.getLongArgument(argIndex));
+ }
+ if (argClass == Byte.class || argClass == Byte.TYPE) {
+ return new Byte((byte) callback.getLongArgument(argIndex));
+ }
+
+ if (argClass == String.class) {
+ return callback.getStringArgument(argIndex);
+ }
+
+ if (argClass == Double.class || argClass == Double.TYPE) {
+ return new Double(callback.getDoubleArgument(argIndex));
+ }
+ if (argClass == Float.class || argClass == Float.TYPE) {
+ return new Float((float) callback.getDoubleArgument(argIndex));
+ }
+
+ if (argClass == BigDecimal.class) {
+ return callback.getBigDecimalArgument(argIndex);
+ }
+
+ if (argClass == Object.class) {
+ int typeCode = callback.getArgumentType(argIndex);
+ InternalType it = InternalType.get(typeCode);
+ return it.getArgument(argIndex, callback);
+ }
+
+ throw new UDFException("Unknown type: " + argClass);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/FunctionDescriptor.java b/plugin/java_udf/com/mysql/udf/FunctionDescriptor.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/FunctionDescriptor.java 2008-02-22 17:05:19 -08:00
@@ -0,0 +1,132 @@
+package com.mysql.udf;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FunctionDescriptor {
+
+ private ParsedFunction parsedFunction;
+
+ private Class functionClass;
+
+ private Method[] jmethods;
+
+ private int numberOfArgs;
+
+ private Method methodToExecute;
+
+ public FunctionDescriptor() {
+ // do we need a no-arg constructor?
+ }
+
+ public FunctionDescriptor(ParsedFunction parsedFunction) {
+ this.parsedFunction = parsedFunction;
+ if (this.parsedFunction.getArglist() == null) {
+ this.numberOfArgs = Integer.MIN_VALUE;
+ } else {
+ this.numberOfArgs = parsedFunction.getArglist().length;
+ }
+ }
+
+ public synchronized void setArgumentCount(int argumentCount) {
+ if (numberOfArgs < 0) {
+ numberOfArgs = argumentCount;
+ }
+ if (numberOfArgs != argumentCount) {
+ String msg = "Number of arguments expected: " + numberOfArgs
+ + " but was: " + argumentCount;
+ throw new UDFException(msg);
+ }
+ }
+
+ private synchronized Method getMethodToExecute() {
+ if (methodToExecute == null) {
+ List candidates = new ArrayList();
+ for (int i = 0; i < getMethods().length; i++) {
+ Method method = getMethods()[i];
+ if (numberOfArgs < 0
+ || numberOfArgs == method.getParameterTypes().length) {
+ candidates.add(method);
+ }
+ }
+ // should this be (candidates.size() != 1) ?
+ if (candidates.size() > 1) {
+ throw new UDFException("Not implemented");
+ }
+ methodToExecute = getMethods()[0];
+ }
+ return methodToExecute;
+ }
+
+ public Object newInstance() {
+ try {
+ return getCls().newInstance();
+ } catch (Exception e) {
+ throw UDFException.toRuntime(e);
+ }
+ }
+
+ public int numberOfArguments() {
+ int rv = getMethodToExecute().getParameterTypes().length;
+ // System.err.println("JAVA: FunctionDescriptor.numberOfArguments()=="
+ // + rv);
+ return rv;
+ }
+
+ public Class getArgumentClass(int argIndex) {
+ return getMethodToExecute().getParameterTypes()[argIndex];
+ }
+
+ private synchronized Class getCls() {
+ if (functionClass == null) {
+ try {
+ functionClass = Class.forName(parsedFunction.getClassName());
+ } catch (ClassNotFoundException e) {
+ throw new UDFException(e);
+ }
+ }
+ return functionClass;
+ }
+
+ private synchronized Method[] getMethods() {
+ if (jmethods == null) {
+ String methodName = parsedFunction.getMethodName();
+ if (parsedFunction.getArglist() != null) {
+ Method meth;
+ try {
+ Class[] argClasses = parsedFunction.argClasses();
+ meth = getCls().getMethod(methodName, argClasses);
+ } catch (Exception e) {
+ throw UDFException.toRuntime(e);
+ }
+ jmethods = new Method[] { meth };
+ } else {
+ Method[] allMethods = getCls().getMethods();
+ List methlist = new java.util.ArrayList();
+ for (int i = 0; i < allMethods.length; i++)
+ if (methodName.equals(allMethods[i].getName()))
+ methlist.add(allMethods[i]);
+ if (methlist.size() == 0) {
+ throw new UDFException("No methods found\n");
+ }
+ jmethods = (Method[]) methlist.toArray(new Method[methlist
+ .size()]);
+ }
+ }
+ return jmethods;
+ }
+
+ public Object invoke(Object instance, Object[] callingArguments) {
+ try {
+ return getMethodToExecute().invoke(instance, callingArguments);
+ } catch (Exception e) {
+ throw UDFException.toRuntime(e);
+ }
+ }
+
+ boolean isStatic() {
+ return Modifier.isStatic(getMethodToExecute().getModifiers());
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/InternalType.java b/plugin/java_udf/com/mysql/udf/InternalType.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/InternalType.java 2008-02-22 17:05:19 -08:00
@@ -0,0 +1,57 @@
+package com.mysql.udf;
+
+public abstract class InternalType {
+
+ public final static InternalType UNKNOWN = new InternalType(-1) {
+ public Object getArgument(int argIndex, UDFCallback callback) {
+ // I'm thinking that this should throw.
+ return null;
+ }
+ };
+
+ public final static InternalType STRING_TYPE = new InternalType(0) {
+ public Object getArgument(int argIndex, UDFCallback callback) {
+ return callback.getStringArgument(argIndex);
+ }
+ };
+
+ public final static InternalType REAL_TYPE = new InternalType(1) {
+ public Object getArgument(int argIndex, UDFCallback callback) {
+ return new Double(callback.getDoubleArgument(argIndex));
+ }
+ };
+
+ public final static InternalType INTEGER_TYPE = new InternalType(2) {
+ public Object getArgument(int argIndex, UDFCallback callback) {
+ return new Long(callback.getLongArgument(argIndex));
+ }
+ };
+
+ public final static InternalType DECIMAL_TYPE = new InternalType(3) {
+ public Object getArgument(int argIndex, UDFCallback callback) {
+ return callback.getBigDecimalArgument(argIndex);
+ }
+ };
+
+ public final int typeCode;
+
+ private InternalType(int typeCode) {
+ this.typeCode = typeCode;
+ }
+
+ public abstract Object getArgument(int argIndex, UDFCallback callback);
+
+ public static InternalType get(int typeCode) throws UDFException {
+ if (typeCode == UNKNOWN.typeCode)
+ return UNKNOWN;
+ if (typeCode == STRING_TYPE.typeCode)
+ return STRING_TYPE;
+ if (typeCode == REAL_TYPE.typeCode)
+ return REAL_TYPE;
+ if (typeCode == INTEGER_TYPE.typeCode)
+ return INTEGER_TYPE;
+ if (typeCode == DECIMAL_TYPE.typeCode)
+ return DECIMAL_TYPE;
+ throw new UDFException("Bad or illegal typeCode");
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/Invoker.java b/plugin/java_udf/com/mysql/udf/Invoker.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/Invoker.java 2008-02-22 17:05:19 -08:00
@@ -0,0 +1,40 @@
+package com.mysql.udf;
+
+public class Invoker implements Context {
+
+ private Object instance;
+
+ private DataMarshal marshal;
+
+ public Invoker(FunctionDescriptor fd, long ptr) {
+ this(fd, new NativeUDFCallback(ptr));
+ }
+
+ public Invoker(FunctionDescriptor fd, UDFCallback callback) {
+ // System.err.println("JAVA: invoker <init>");
+ this.marshal = new DataMarshal(fd, callback);
+ if (!fd.isStatic()) {
+ this.instance = marshal.newInstance();
+ }
+ }
+
+ public void init() {
+ // System.err.println("JAVA: invoker.init");
+ if (instance instanceof LifeCycle) {
+ ((LifeCycle) instance).init(this);
+ }
+ }
+
+ public void exec() {
+ // System.err.println("JAVA: invoker.exec");
+ Object result = marshal.invoke(instance);
+ marshal.storeResult(result);
+ }
+
+ public void fini() {
+ // System.err.println("JAVA: invoker.fini");
+ if (instance instanceof LifeCycle) {
+ ((LifeCycle) instance).destroy();
+ }
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/LifeCycle.java b/plugin/java_udf/com/mysql/udf/LifeCycle.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/LifeCycle.java 2008-02-22 17:05:20 -08:00
@@ -0,0 +1,7 @@
+package com.mysql.udf;
+
+public interface LifeCycle {
+ void init(Context context);
+
+ void destroy();
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/MysqlIOtype2.java b/plugin/java_udf/com/mysql/udf/MysqlIOtype2.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/MysqlIOtype2.java 2008-02-22 17:05:20 -08:00
@@ -0,0 +1,205 @@
+/*
+ Copyright (C) 2002-2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ There are special exceptions to the terms and conditions of the GPL
+ as it is applied to this software. View the full text of the
+ exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
+ software distribution.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+ */
+package com.mysql.udf;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Properties;
+
+import com.mysql.jdbc.Buffer;
+import com.mysql.jdbc.ConnectionImpl;
+import com.mysql.jdbc.Field;
+import com.mysql.jdbc.MysqlIO;
+import com.mysql.jdbc.ResultSetImpl;
+import com.mysql.jdbc.ResultSetInternalMethods;
+import com.mysql.jdbc.ResultSetRow;
+import com.mysql.jdbc.RowData;
+import com.mysql.jdbc.StatementImpl;
+
+
+/**
+ * This class is used by Connection for communicating with the MySQL server by
+ * wrapping the mysqllib.
+ *
+ */
+public class MysqlIOtype2 implements MysqlIO {
+ /**
+ * Constructor: Connect to the MySQL server and setup a stream connection.
+ *
+ * @param props the Properties from DriverManager.getConnection()
+ * @param conn the Connection that is creating us
+ *
+ * @throws IOException if an IOException occurs during connect.
+ * @throws SQLException if a database access error occurs.
+ */
+ public MysqlIOtype2(Properties props, ConnectionImpl conn)
+ throws IOException, SQLException {
+ }
+
+ public void changeUser(String userName, String password, String database)
+ throws SQLException {
+ }
+
+ public void checkForCharsetMismatch() {
+ }
+
+ public void clearInputStream() throws SQLException {
+ }
+
+ public void closeStreamer(RowData streamer) throws SQLException {
+ }
+
+ public void disableMultiQueries() throws SQLException {
+ }
+
+ public void doHandshake(String user, String password, String database)
+ throws SQLException {
+ }
+
+ public void enableMultiQueries() throws SQLException {
+ }
+
+ public List fetchRowsViaCursor(List fetchedRows, long statementId,
+ Field[] columnTypes, int fetchSize, boolean useBufferRowExplicit)
+ throws SQLException {
+ return null;
+ }
+
+ public void forceClose() {
+ }
+
+ public int getCommandCount() {
+ return 0;
+ }
+
+ public String getHost() {
+ return null;
+ }
+
+ public long getLastPacketSentTimeMs() {
+ return 0;
+ }
+
+ public int getServerMajorVersion() {
+ return 0;
+ }
+
+ public int getServerMinorVersion() {
+ return 0;
+ }
+
+ public int getServerStatus() {
+ return 0;
+ }
+
+ public int getServerSubMinorVersion() {
+ return 0;
+ }
+
+ public String getServerVersion() {
+ return null;
+ }
+
+ public Buffer getSharedSendPacket() {
+ return null;
+ }
+
+ public long getThreadId() {
+ return 0;
+ }
+
+ public boolean hasLongColumnInfo() {
+ return false;
+ }
+
+ public boolean inTransactionOnServer() {
+ return false;
+ }
+
+ public void initializeStatementInterceptors(String interceptorClasses,
+ Properties props) throws SQLException {
+ }
+
+ public boolean isDataAvailable() throws SQLException {
+ return false;
+ }
+
+ public boolean isSetNeededForAutoCommitMode(boolean autoCommitFlag) {
+ return false;
+ }
+
+ public ResultSetRow nextRow(Field[] fields, int columnCount,
+ boolean isBinaryEncoded, int resultSetConcurrency,
+ boolean useBufferRowIfPossible, boolean useBufferRowExplicit,
+ boolean canReuseRowPacketForBufferRow, Buffer existingRowPacket)
+ throws SQLException {
+ return null;
+ }
+
+ public void quit() throws SQLException {
+ }
+
+ public ResultSetImpl readAllResults(StatementImpl callingStatement,
+ int maxRows, int resultSetType, int resultSetConcurrency,
+ boolean streamResults, String catalog, Buffer resultPacket,
+ boolean isBinaryEncoded, long preSentColumnCount,
+ Field[] metadataFromCache) throws SQLException {
+ return null;
+ }
+
+ public void resetMaxBuf() {
+ }
+
+ public Buffer sendCommand(int command, String extraData,
+ Buffer queryPacket, boolean skipCheck, String extraDataCharEncoding)
+ throws SQLException {
+ return null;
+ }
+
+ public int serverCharsetIndex() {
+ return 0;
+ }
+
+ public void setServerCharsetIndex(int serverCharsetIndex) {
+ }
+
+ public ResultSetInternalMethods sqlQueryDirect(
+ StatementImpl callingStatement, String query,
+ String characterEncoding, Buffer queryPacket, int maxRows,
+ int resultSetType, int resultSetConcurrency, boolean streamResults,
+ String catalog, Field[] cachedMetadata) throws Exception {
+ return null;
+ }
+
+ public boolean tackOnMoreStreamingResults(ResultSetImpl addingTo)
+ throws SQLException {
+ return false;
+ }
+
+ public boolean versionMeetsMinimum(int major, int minor, int subminor) {
+ return false;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/NativeRow.java b/plugin/java_udf/com/mysql/udf/NativeRow.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/NativeRow.java 2008-02-22 17:05:20 -08:00
@@ -0,0 +1,123 @@
+package com.mysql.udf;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import com.mysql.jdbc.ConnectionImpl;
+import com.mysql.jdbc.ResultSetImpl;
+import com.mysql.jdbc.ResultSetRow;
+
+public class NativeRow extends ResultSetRow {
+
+ public void closeOpenStreams() {
+ }
+
+ public InputStream getBinaryInputStream(int columnIndex)
+ throws SQLException {
+ return null;
+ }
+
+ public byte[] getColumnValue(int index) throws SQLException {
+ return null;
+ }
+
+ public Date getDateFast(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs, Calendar targetCalendar) throws SQLException {
+ return null;
+ }
+
+ public int getInt(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public long getLong(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public Date getNativeDate(int columnIndex, ConnectionImpl conn,
+ ResultSetImpl rs) throws SQLException {
+ return null;
+ }
+
+ public Object getNativeDateTimeValue(int columnIndex,
+ Calendar targetCalendar, int jdbcType, int mysqlType, TimeZone tz,
+ boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ return null;
+ }
+
+ public double getNativeDouble(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public float getNativeFloat(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public int getNativeInt(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public long getNativeLong(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public short getNativeShort(int columnIndex) throws SQLException {
+ return 0;
+ }
+
+ public Time getNativeTime(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ return null;
+ }
+
+ public Timestamp getNativeTimestamp(int columnIndex,
+ Calendar targetCalendar, TimeZone tz, boolean rollForward,
+ ConnectionImpl conn, ResultSetImpl rs) throws SQLException {
+ return null;
+ }
+
+ public Reader getReader(int columnIndex) throws SQLException {
+ return null;
+ }
+
+ public String getString(int index, String encoding, ConnectionImpl conn)
+ throws SQLException {
+ return null;
+ }
+
+ public Time getTimeFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ return null;
+ }
+
+ public Timestamp getTimestampFast(int columnIndex, Calendar targetCalendar,
+ TimeZone tz, boolean rollForward, ConnectionImpl conn, ResultSetImpl rs)
+ throws SQLException {
+ return null;
+ }
+
+ public boolean isFloatingPointNumber(int index) throws SQLException {
+ return false;
+ }
+
+ public boolean isNull(int index) throws SQLException {
+ return false;
+ }
+
+ public long length(int index) throws SQLException {
+ return 0;
+ }
+
+ public void setColumnValue(int index, byte[] value) throws SQLException {
+ }
+
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/NativeRowData.java b/plugin/java_udf/com/mysql/udf/NativeRowData.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/NativeRowData.java 2008-02-22 17:05:20 -08:00
@@ -0,0 +1,95 @@
+package com.mysql.udf;
+
+import java.sql.SQLException;
+
+import com.mysql.jdbc.Field;
+import com.mysql.jdbc.ResultSetImpl;
+import com.mysql.jdbc.ResultSetInternalMethods;
+import com.mysql.jdbc.ResultSetRow;
+import com.mysql.jdbc.RowData;
+
+public class NativeRowData implements RowData {
+
+ public void addRow(ResultSetRow row) throws SQLException {
+ }
+
+ public void afterLast() throws SQLException {
+ }
+
+ public void beforeFirst() throws SQLException {
+ }
+
+ public void beforeLast() throws SQLException {
+ }
+
+ public void close() throws SQLException {
+ }
+
+ public ResultSetRow getAt(int index) throws SQLException {
+ return null;
+ }
+
+ public int getCurrentRowNumber() throws SQLException {
+ return 0; // do we need to maintain this in java? or will row tell.
+ }
+
+ public ResultSetInternalMethods getOwner() {
+ return null;
+ }
+
+ public boolean hasNext() throws SQLException {
+ return false;
+ }
+
+ public boolean isAfterLast() throws SQLException {
+ return false;
+ }
+
+ public boolean isBeforeFirst() throws SQLException {
+ return false;
+ }
+
+ public boolean isDynamic() throws SQLException {
+ return false;
+ }
+
+ public boolean isEmpty() throws SQLException {
+ return false;
+ }
+
+ public boolean isFirst() throws SQLException {
+ return false;
+ }
+
+ public boolean isLast() throws SQLException {
+ return false;
+ }
+
+ public void moveRowRelative(int rows) throws SQLException {
+ }
+
+ public ResultSetRow next() throws SQLException {
+ return null;
+ }
+
+ public void removeRow(int index) throws SQLException {
+ }
+
+ public void setCurrentRow(int rowNumber) throws SQLException {
+ }
+
+ public void setMetadata(Field[] metadata) {
+ }
+
+ public void setOwner(ResultSetImpl rs) {
+ }
+
+ public int size() throws SQLException {
+ return 0;
+ }
+
+ public boolean wasEmpty() {
+ return false;
+ }
+
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/NativeUDFCallback.java b/plugin/java_udf/com/mysql/udf/NativeUDFCallback.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/NativeUDFCallback.java 2008-02-22 17:05:20 -08:00
@@ -0,0 +1,192 @@
+package com.mysql.udf;
+
+import java.math.BigDecimal;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+public class NativeUDFCallback implements UDFCallback {
+
+ private static final int MYSQL_TYPE_STRING = 254;
+
+ private static final int RESULT_INDEX = -1;
+
+ private final long that;
+
+ public NativeUDFCallback(long ptr) {
+ this.that = ptr;
+ }
+
+ public long getPointer() {
+ return that;
+ }
+
+ public int getArgumentCount() {
+ int rv = get_argument_count(that);
+ // System.err
+ // .println("JAVA: NativeUDFCallback.getArgumentCount() = " + rv);
+ return rv;
+ }
+
+ public int getArgumentType(int argIndex) {
+ // System.err.println("JAVA: NativeUDFCallback.getArgumentType");
+ return get_argument_type(that, argIndex);
+ }
+
+ public boolean isArgumentNull(int argIndex) {
+ boolean rv = is_argument_null(that, argIndex);
+ // System.err.println("JAVA: NativeUDFCallback.isArgumentNull(" +
+ // argIndex + ") = " + rv);
+ return rv;
+ }
+
+ public void setNullArgument(int idx) {
+ // System.err.println("JAVA: NativeUDFCallback.setNullArgument");
+ set_null_argument(that, idx);
+ }
+
+ public long getLongArgument(int argIndex) {
+ // System.err.println("JAVA: NativeUDFCallback.getLongArgument");
+ return get_long_argument(that, argIndex);
+ }
+
+ public void setLongArgument(int idx, long value) {
+ // System.err.println("JAVA: NativeUDFCallback.setLongArgument");
+ set_long_argument(that, idx, value);
+ }
+
+ public String getStringArgument(int argIndex) {
+ // System.err.println("JAVA: NativeUDFCallback.getStringArgument");
+ return get_string_argument(that, argIndex);
+ }
+
+ public void setStringArgument(int idx, String value) {
+ // System.err.println("JAVA: NativeUDFCallback.setStringArgument");
+ set_string_argument(that, idx, value);
+ }
+
+ public double getDoubleArgument(int argIndex) {
+ // System.err.println("JAVA: NativeUDFCallback.getDoubleArgument");
+ return get_double_argument(that, argIndex);
+ }
+
+ public void setDoubleArgument(int idx, double value) {
+ // System.err.println("JAVA: NativeUDFCallback.setDoubleArgument");
+ set_double_argument(that, idx, value);
+ }
+
+ public BigDecimal getBigDecimalArgument(int argIndex) {
+ // System.err.println("JAVA: NativeUDFCallback.getBigDecimalArgument");
+ return new BigDecimal(get_big_decimal_argument(that, argIndex));
+ }
+
+ public void setBigDecimalArgument(int idx, BigDecimal value) {
+ // System.err.println("JAVA: NativeUDFCallback.setBigDecimalArgument");
+ set_big_decimal_argument(that, idx, value.toString());
+ }
+
+ public void storeResultNull() {
+ // System.err.println("JAVA: NativeUDFCallback.storeResultNull");
+ set_null_argument(that, RESULT_INDEX);
+ }
+
+ public void storeResultLong(long value) {
+ // System.err.println("JAVA: NativeUDFCallback.storeResultLong");
+ set_long_argument(that, RESULT_INDEX, value);
+ }
+
+ public void storeResultString(String value) {
+ // System.err.println("JAVA: NativeUDFCallback.storeResultString");
+ set_string_argument(that, RESULT_INDEX, value);
+ }
+
+ public void storeResultDouble(double value) {
+ // System.err.println("JAVA: NativeUDFCallback.storeResultDouble");
+ set_double_argument(that, RESULT_INDEX, value);
+ }
+
+ public void storeResultBigDecimal(BigDecimal value) {
+ // System.err.println("JAVA: NativeUDFCallback.storeResultBigDecimal");
+ set_big_decimal_argument(that, RESULT_INDEX, value.toString());
+ }
+
+ public void storeResultResultSet(java.sql.ResultSet rs) {
+ // System.err.println("JAVA: NativeUDFCallback.storeResultResultSet");
+ try {
+ int colcount;
+ final ResultSetMetaData metaData = rs.getMetaData();
+ colcount = metaData.getColumnCount();
+ for (int i = 1; i <= colcount; i++) {
+ String name = metaData.getColumnLabel(i);
+ int width = metaData.getColumnDisplaySize(i);
+ int mysql_type = MYSQL_TYPE_STRING;
+ int precision = 0;
+
+ row_field(that, name, mysql_type, width, precision);
+ }
+ while (rs.next()) {
+ row_prepare(that);
+ for (int i = 1; i <= colcount; i++) {
+ storeResultString(rs.getString(i));
+ }
+ row_send(that);
+ }
+ row_send_eof(that);
+ } catch (SQLException e) {
+ throw new UDFException(e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (Exception e) {
+ // just log this:
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private static native int get_argument_count(long that);
+
+ private static native int get_argument_type(long that, int arg_index);
+
+ private static native boolean is_argument_null(long that, int arg_index);
+
+ private static native void set_null_argument(long that, int idx);
+
+ private static native long get_long_argument(long that, int arg_index);
+
+ private static native void set_long_argument(long that, int idx, long value);
+
+ private static native String get_string_argument(long that, int arg_index);
+
+ private static native void set_string_argument(long that, int idx,
+ String value);
+
+ private static native double get_double_argument(long that, int arg_index);
+
+ private static native void set_double_argument(long that, int idx,
+ double value);
+
+ private static native String get_big_decimal_argument(long that,
+ int argIndex);
+
+ private static native void set_big_decimal_argument(long that, int idx,
+ String value);
+
+ /* The following are for result sets */
+
+ /* this method is called for each column in the result set to be constructed */
+ private static native int row_field(long that, String column_name,
+ int field_type, int column_width, int precision);
+
+ /* call row_prepare() before filling in the row */
+ private static native int row_prepare(long that);
+
+ /* call store for each column value */
+
+ /* call row_send for each row */
+ private static native int row_send(long that);
+
+ /* call row_send_eof after the last row */
+ private static native int row_send_eof(long that);
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/ParameterClassFinder.java b/plugin/java_udf/com/mysql/udf/ParameterClassFinder.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/ParameterClassFinder.java 2008-02-22 17:05:20 -08:00
@@ -0,0 +1,32 @@
+package com.mysql.udf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ParameterClassFinder {
+ private static Map primativeClasses;
+ static {
+ primativeClasses = new HashMap();
+ primativeClasses.put("int", Integer.TYPE);
+ primativeClasses.put("long", Long.TYPE);
+ primativeClasses.put("short", Short.TYPE);
+ primativeClasses.put("char", Character.TYPE);
+ primativeClasses.put("byte", Byte.TYPE);
+ primativeClasses.put("boolean", Boolean.TYPE);
+ primativeClasses.put("float", Float.TYPE);
+ primativeClasses.put("double", Double.TYPE);
+ }
+
+ public static Class getClassForType(String type) {
+ Class primativeClass = (Class) primativeClasses.get(type);
+ if (primativeClass != null) {
+ return primativeClass;
+ }
+
+ try {
+ return Class.forName(type);
+ } catch (ClassNotFoundException e) {
+ throw new UDFException(e);
+ }
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/ParsedFunction.java b/plugin/java_udf/com/mysql/udf/ParsedFunction.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/ParsedFunction.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,110 @@
+package com.mysql.udf;
+
+import java.lang.reflect.Array;
+
+public class ParsedFunction {
+ private String jarid;
+
+ public String className;
+
+ private String methodName;
+
+ private String[] arglist;
+
+ public ParsedFunction(String name) {
+ String remainder = parseJarId(name);
+ remainder = parseClassAndMethodName(remainder);
+ remainder = parseParams(remainder);
+ if (remainder.length() > 0) {
+ throw new UDFException("remaining text: " + remainder);
+ }
+ }
+
+ private String parseJarId(String name) {
+ int colonIndex = name.indexOf(':');
+ if (colonIndex != name.lastIndexOf(':')) {
+ throw new UDFException("invalid external name: " + name);
+ }
+ if (colonIndex > 0) {
+ jarid = name.substring(0, colonIndex);
+ }
+ return name.substring(colonIndex + 1);
+
+ }
+
+ private String parseClassAndMethodName(String name) {
+ int parenIndex = name.indexOf('(');
+ String classsNamePlusMethod;
+ if (parenIndex < 0) {
+ classsNamePlusMethod = name;
+ } else {
+ classsNamePlusMethod = name.substring(0, parenIndex);
+ }
+
+ int methodIdx = classsNamePlusMethod.lastIndexOf('.');
+ if (methodIdx <= 0 || methodIdx == classsNamePlusMethod.length()) {
+ String msg = "can't parse class and method name: "
+ + classsNamePlusMethod;
+ throw new UDFException(msg);
+ }
+ className = classsNamePlusMethod.substring(0, methodIdx);
+ methodName = classsNamePlusMethod.substring(methodIdx + 1);
+
+ return parenIndex < 0 ? "" : name.substring(parenIndex);
+ }
+
+ private String parseParams(String remainder) {
+ int parenIndex = remainder.indexOf('(');
+ int closeIndex = remainder.indexOf(')');
+ if (parenIndex < 0 || closeIndex < 0) {
+ return remainder;
+ }
+
+ String stripParens = remainder.substring(parenIndex + 1, closeIndex);
+ if (stripParens.length() != 0) {
+ arglist = stripParens.split(",");
+ } else {
+ arglist = new String[0];
+ }
+ return remainder.substring(closeIndex + 1, remainder.length());
+ }
+
+ public String[] getArglist() {
+ return arglist;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getJarid() {
+ return jarid;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public Class[] argClasses() {
+ if (arglist == null) {
+ return null;
+ }
+ Class[] argClasses = new Class[arglist.length];
+ for (int i = 0; i < arglist.length; i++) {
+ String type = arglist[i];
+ int arrayCount = 0;
+ while (type.endsWith("[]")) {
+ arrayCount++;
+ type = type.substring(0, type.length() - 2);
+ }
+
+ argClasses[i] = ParameterClassFinder.getClassForType(type);
+
+ if (arrayCount > 0) {
+ argClasses[i] = Array.newInstance(argClasses[i],
+ new int[arrayCount]).getClass();
+ }
+ }
+ return argClasses;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/UDFCallback.java b/plugin/java_udf/com/mysql/udf/UDFCallback.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/UDFCallback.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,42 @@
+package com.mysql.udf;
+
+import java.math.BigDecimal;
+
+public interface UDFCallback {
+ int getArgumentCount();
+
+ int getArgumentType(int argIndex);
+
+ boolean isArgumentNull(int idx);
+
+ void setNullArgument(int idx);
+
+ long getLongArgument(int argIndex);
+
+ void setLongArgument(int idx, long value);
+
+ String getStringArgument(int argIndex);
+
+ void setStringArgument(int idx, String value);
+
+ double getDoubleArgument(int argIndex);
+
+ void setDoubleArgument(int idx, double value);
+
+ BigDecimal getBigDecimalArgument(int argIndex);
+
+ void setBigDecimalArgument(int idx, BigDecimal value);
+
+ void storeResultNull();
+
+ void storeResultLong(long returnValue);
+
+ void storeResultString(String returnValue);
+
+ void storeResultDouble(double returnValue);
+
+ void storeResultBigDecimal(BigDecimal returnValue);
+
+ void storeResultResultSet(java.sql.ResultSet returnValue);
+
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/UDFException.java b/plugin/java_udf/com/mysql/udf/UDFException.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/UDFException.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,20 @@
+package com.mysql.udf;
+
+public class UDFException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public UDFException(Throwable cause) {
+ super(cause);
+ }
+
+ public UDFException(String msg) {
+ super(msg);
+ }
+
+ public static RuntimeException toRuntime(Exception e) {
+ if (e instanceof RuntimeException) {
+ return (RuntimeException) e;
+ }
+ return new UDFException(e);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/UDFModule.java b/plugin/java_udf/com/mysql/udf/UDFModule.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/UDFModule.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,41 @@
+package com.mysql.udf;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class UDFModule {
+
+ private List initParams;
+
+ private Map invokers;
+
+ public UDFModule() {
+ this.invokers = new HashMap();
+ }
+
+ public void init(String[] params) {
+ initParams = Arrays.asList(params);
+ }
+
+ public synchronized FunctionDescriptor find(String sql03FuncName) {
+ FunctionDescriptor fd = (FunctionDescriptor) invokers
+ .get(sql03FuncName);
+ if (fd == null) {
+ ParsedFunction parsed = new ParsedFunction(sql03FuncName);
+ fd = new FunctionDescriptor(parsed);
+ invokers.put(sql03FuncName, fd);
+ }
+ return fd;
+ }
+
+ public void fini() {
+ // will this ever do anything?
+ }
+
+ public List getInitParams() {
+ return new ArrayList(initParams);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/example/PigLatin.java b/plugin/java_udf/com/mysql/udf/example/PigLatin.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/example/PigLatin.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,111 @@
+package com.mysql.udf.example;
+
+public class PigLatin {
+
+ public static String toPigLatin(String english) {
+ if (english == null) {
+ return null;
+ }
+ boolean allUpper = allUpper(english);
+
+ String[] words = english.split(" ");
+
+ StringBuffer pigLatin = new StringBuffer();
+
+ for (int i = 0; i < words.length; i++) {
+ pigLatin.append(pigLatinizeWord(words[i], allUpper));
+ pigLatin.append(" ");
+ }
+
+ return pigLatin.toString().trim();
+ }
+
+ private static boolean allUpper(String english) {
+ if (english.length() < 2) {
+ // "I" becomes 'Iway"
+ return false;
+ }
+ for (int i = 0; i < english.length(); i++) {
+ char c = english.charAt(i);
+ if (Character.isLetter(c) && Character.isLowerCase(c)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static String pigLatinizeWord(String word, boolean allUpper) {
+ if (word.length() == 0) {
+ return word;
+ }
+
+ String pre_punctuation = "";
+ while (word.length() > 0) {
+ char firstChar = word.charAt(0);
+ if (Character.isLetter(firstChar)) {
+ break;
+ }
+ pre_punctuation += word.charAt(0);
+ word = word.substring(1);
+ }
+
+ if (word.length() == 0) {
+ // this was pure punctuation String like "..." or "-" or "23"
+ return pre_punctuation;
+ }
+
+ String post_punctuation = "";
+ while (word.length() > 0) {
+ char lastChar = word.charAt(word.length() - 1);
+ if (Character.isLetter(lastChar)) {
+ break;
+ }
+ post_punctuation = word.charAt(word.length() - 1)
+ + post_punctuation;
+ word = word.substring(0, word.length() - 1);
+ }
+
+ boolean capitalize = false;
+ if (!allUpper) {
+ capitalize = Character.isUpperCase(word.charAt(0));
+ word = word.toLowerCase();
+ }
+
+ String vowels = "aeiouAEIOU"; // no 'y' as the first letter
+ int offset = 0;
+ while (vowels.indexOf(word.charAt(offset)) < 0) {
+ if (offset == 0) {
+ vowels += "yY"; // but is a vowel as the second letter;
+ }
+ offset++;
+ }
+
+ // queen -> eenquay
+ if (offset == 1 && word.length() > 2
+ && Character.toLowerCase(word.charAt(0)) == 'q'
+ && Character.toLowerCase(word.charAt(1)) == 'u') {
+ offset = 2;
+ }
+
+ String suffix;
+ if (offset == 0) {
+ suffix = (allUpper) ? "WAY" : "way";
+ } else {
+ suffix = (allUpper) ? "AY" : "ay";
+ }
+
+ String pigLatin = word.substring(offset) + word.substring(0, offset)
+ + suffix;
+
+ if (capitalize) {
+ pigLatin = Character.toUpperCase(pigLatin.charAt(0))
+ + pigLatin.substring(1);
+ }
+
+ return pre_punctuation + pigLatin + post_punctuation;
+ }
+
+ private PigLatin(String foo) {
+ // this constructor is here just to try to throw a spanner in the gears
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/example/Primes.java b/plugin/java_udf/com/mysql/udf/example/Primes.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/example/Primes.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,43 @@
+package com.mysql.udf.example;
+
+import java.sql.ResultSet;
+
+import com.mysql.udf.util.SimpleResultSet;
+
+public class Primes {
+
+ public static boolean isPrime(long candidate) {
+ if (candidate < 2) {
+ return false;
+ }
+ if (candidate == 2) {
+ return true;
+ }
+ if (candidate % 2 == 0) {
+ return false;
+ }
+ if (candidate < 9) {
+ return true;
+ }
+ long max = (long) (Math.sqrt(candidate) + 1);
+ for (long l = 3; l <= max; l += 2) {
+ if (candidate % l == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static ResultSet upTo(int max) {
+ SimpleResultSet primes = new SimpleResultSet(new String[] { "Primes" });
+ if (max >= 2) {
+ primes.addRow(new Object[] { new Integer(2) });
+ }
+ for (int candidate = 3; candidate <= max; candidate += 2) {
+ if (isPrime(candidate)) {
+ primes.addRow(new Object[] { new Integer(candidate) });
+ }
+ }
+ return primes;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/example/Reverse.java b/plugin/java_udf/com/mysql/udf/example/Reverse.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/example/Reverse.java 2008-02-22 17:05:21 -08:00
@@ -0,0 +1,14 @@
+package com.mysql.udf.example;
+
+public class Reverse {
+ public String go(String str) {
+ if (str == null) {
+ return null;
+ }
+ StringBuffer sb = new StringBuffer(str.length());
+ for (int i = str.length() - 1; i >= 0; i--) {
+ sb.append(str.charAt(i));
+ }
+ return sb.toString();
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/Exploder.java b/plugin/java_udf/com/mysql/udf/test/Exploder.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/Exploder.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,9 @@
+package com.mysql.udf.test;
+
+import java.io.IOException;
+
+public class Exploder {
+ public static String thisMethodWillExplode(String str) throws IOException {
+ throw new IOException("BOOM: " + str);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/FunctionDescriptorTest.java b/plugin/java_udf/com/mysql/udf/test/FunctionDescriptorTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/FunctionDescriptorTest.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,23 @@
+package com.mysql.udf.test;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.FunctionDescriptor;
+import com.mysql.udf.ParsedFunction;
+
+public class FunctionDescriptorTest extends TestCase {
+
+ public void testParseEquals() {
+ ParsedFunction pf = new ParsedFunction("java.lang.Object.equals");
+ FunctionDescriptor fd = new FunctionDescriptor(pf);
+ assertEquals(Object.class, fd.getArgumentClass(0));
+ }
+
+ public void testParseSimple() {
+ ParsedFunction pf = new ParsedFunction(
+ "java.lang.Object.equals(java.lang.Object)");
+ FunctionDescriptor fd = new FunctionDescriptor(pf);
+ assertEquals(Object.class, fd.getArgumentClass(0));
+ }
+
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/InvokerTest.java b/plugin/java_udf/com/mysql/udf/test/InvokerTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/InvokerTest.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,52 @@
+package com.mysql.udf.test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mysql.udf.FunctionDescriptor;
+import com.mysql.udf.Invoker;
+import com.mysql.udf.ParsedFunction;
+
+import junit.framework.TestCase;
+
+public class InvokerTest extends TestCase {
+
+ public void testSimulation() throws Exception {
+ TestCallback callback = new TestCallback();
+
+ String funcName = TestFunction.class.getName() + ".foo";
+ ParsedFunction parsed = new ParsedFunction(funcName);
+ FunctionDescriptor fd = new FunctionDescriptor(parsed);
+
+ Invoker invoker = new Invoker(fd, callback);
+ invoker.init();
+
+ List args = new ArrayList();
+
+ args.add("WOOT!");
+ args.add(new Long(3));
+ args.add(null);
+ args.add(new Double(1.5));
+ args.add(new BigDecimal(7));
+
+ callback.setArgs(args);
+ invoker.exec();
+
+ assertEquals("Foo: 'WOOT!' 3 'null' 1.5 7", callback.resultAsString());
+
+ args.clear();
+ args.add("Bang!");
+ args.add(new Long(7));
+ args.add("Pow!");
+ args.add(null);
+ args.add(null);
+
+ callback.setArgs(args);
+ invoker.exec();
+
+ assertEquals("Foo: 'Bang!' 7 'Pow!' null null", callback
+ .resultAsString());
+
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/JniSimulationTest.java b/plugin/java_udf/com/mysql/udf/test/JniSimulationTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/JniSimulationTest.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,136 @@
+package com.mysql.udf.test;
+
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.FunctionDescriptor;
+import com.mysql.udf.Invoker;
+import com.mysql.udf.UDFModule;
+import com.mysql.udf.example.PigLatin;
+
+public class JniSimulationTest extends TestCase {
+
+ public void testSimpleCase() {
+ String key = "system.class.path";
+ String value = System.getProperty(key);
+ String cp = key + "=" + value;
+ String[] moduleInitParams = new String[] { cp };
+
+ // module init
+ UDFModule module = new UDFModule();
+ module.init(moduleInitParams);
+
+ // function find
+ String functionName = TestFunction.class.getName() + "." + "bar";
+ FunctionDescriptor fd = module.find(functionName);
+
+ // function init
+ TestCallback callback = new TestCallback();
+ Invoker invoker = new Invoker(fd, callback);
+ invoker.init();
+
+ // function execute
+ callback.setArgs(Collections.singletonList("one"));
+ invoker.exec();
+ assertEquals("Bar: 'one'", callback.resultAsString());
+
+ callback.setArgs(Collections.singletonList("two"));
+ invoker.exec();
+ assertEquals("Bar: 'two'", callback.resultAsString());
+
+ // function fini
+ invoker.fini();
+ invoker = null; // delete local ref
+
+ // Module fini
+ module.fini();
+ module = null;
+ }
+
+ public void testStaticMethodCase() {
+ String key = "system.class.path";
+ String value = System.getProperty(key);
+ String cp = key + "=" + value;
+ String[] moduleInitParams = new String[] { cp };
+
+ // module init
+ UDFModule module = new UDFModule();
+ module.init(moduleInitParams);
+
+ // function find
+ String functionName = PigLatin.class.getName() + "." + "toPigLatin";
+ FunctionDescriptor fd = module.find(functionName);
+
+ // function init
+ TestCallback callback = new TestCallback();
+ Invoker invoker = new Invoker(fd, callback);
+ invoker.init();
+
+ // function execute
+ callback.setArgs(Collections.singletonList("trivial example"));
+ invoker.exec();
+ assertEquals("ivialtray exampleway", callback.resultAsString());
+
+ callback.setArgs(Collections.singletonList("Pig Latin."));
+ invoker.exec();
+ assertEquals("Igpay Atinlay.", callback.resultAsString());
+
+ // function fini
+ invoker.fini();
+ invoker = null; // delete local ref
+
+ // Module fini
+ module.fini();
+ module = null;
+ }
+
+ public void testExploder() {
+ String key = "system.class.path";
+ String value = System.getProperty(key);
+ String cp = key + "=" + value;
+ String[] moduleInitParams = new String[] { cp };
+
+ // module init
+ UDFModule module = new UDFModule();
+ module.init(moduleInitParams);
+
+ // function find
+ String functionName = Exploder.class.getName() + "."
+ + "thisMethodWillExplode";
+ FunctionDescriptor fd = module.find(functionName);
+
+ // function init
+ TestCallback callback = new TestCallback();
+ Invoker invoker = new Invoker(fd, callback);
+ invoker.init();
+
+ // function execute
+ callback.setArgs(Collections.singletonList("here goes"));
+ Exception expected = null;
+ try {
+ invoker.exec();
+ } catch (Exception e) {
+ expected = e;
+ }
+ assertNotNull(expected);
+
+ callback.setArgs(Collections.singletonList("try again?"));
+ expected = null;
+ try {
+ invoker.exec();
+ } catch (Exception e) {
+ expected = e;
+ }
+ assertNotNull(expected);
+
+ // function fini
+ invoker.fini();
+ invoker = null; // delete local ref
+
+ // Module fini
+ module.fini();
+ module = null;
+ }
+
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/ParameterClassFinderTest.java b/plugin/java_udf/com/mysql/udf/test/ParameterClassFinderTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/ParameterClassFinderTest.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,33 @@
+package com.mysql.udf.test;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.ParameterClassFinder;
+import com.mysql.udf.UDFException;
+
+public class ParameterClassFinderTest extends TestCase {
+
+ private void checkClassForType(Class type, String typeStr) {
+ assertEquals(type, ParameterClassFinder.getClassForType(typeStr));
+ }
+
+ public void testTypeLookup() {
+ checkClassForType(Integer.TYPE, "int");
+ checkClassForType(Long.TYPE, "long");
+ checkClassForType(Short.TYPE, "short");
+ checkClassForType(Character.TYPE, "char");
+ checkClassForType(Byte.TYPE, "byte");
+ checkClassForType(Boolean.TYPE, "boolean");
+ checkClassForType(Float.TYPE, "float");
+ checkClassForType(Double.TYPE, "double");
+ checkClassForType(String.class, "java.lang.String");
+
+ Exception expected = null;
+ try {
+ ParameterClassFinder.getClassForType("bogus.class.Name");
+ } catch (UDFException e) {
+ expected = e;
+ }
+ assertNotNull(expected);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/ParsedFunctionTest.java b/plugin/java_udf/com/mysql/udf/test/ParsedFunctionTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/ParsedFunctionTest.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,59 @@
+package com.mysql.udf.test;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.ParsedFunction;
+
+public class ParsedFunctionTest extends TestCase {
+
+ public void testParseSimple() {
+ String methodName = "java.lang.Object.equals";
+ ParsedFunction pf = new ParsedFunction(methodName);
+ assertNull("Jar ID", pf.getJarid());
+ assertEquals("ClassName", "java.lang.Object", pf.getClassName());
+ assertEquals("MethodName", "equals", pf.getMethodName());
+ assertNull("Arglist", pf.getArglist());
+ }
+
+ public void testParseObjectEquals() {
+ String methodName = "java.lang.Object.equals(java.lang.Object)";
+ ParsedFunction pf = new ParsedFunction(methodName);
+ assertNull("Jar ID", pf.getJarid());
+ assertEquals("ClassName", "java.lang.Object", pf.getClassName());
+ assertEquals("MethodName", "equals", pf.getMethodName());
+ assertNotNull("Arglist", pf.getArglist());
+ assertEquals("Arglist length", 1, pf.getArglist().length);
+ assertEquals("arg[0] type", "java.lang.Object", pf.getArglist()[0]);
+ }
+
+ public void testParseBogus() {
+ String methodName = "jarid:bogus.FakeCls.myMethod(int,java.lang.String)";
+ ParsedFunction pf = new ParsedFunction(methodName);
+ assertEquals("Jar ID", "jarid", pf.getJarid());
+ assertEquals("ClassName", "bogus.FakeCls", pf.getClassName());
+ assertEquals("MethodName", "myMethod", pf.getMethodName());
+ assertNotNull("Arglist", pf.getArglist());
+ assertEquals("Arglist length", 2, pf.getArglist().length);
+ assertEquals("arg[0] type", "int", pf.getArglist()[0]);
+ assertEquals("arg[1] type", "java.lang.String", pf.getArglist()[1]);
+ }
+
+ public void testParseJarClassMethodNoParens() {
+ String methodName = "jarid:bogus.FakeCls.myMethod";
+ ParsedFunction pf = new ParsedFunction(methodName);
+ assertEquals("Jar ID", "jarid", pf.getJarid());
+ assertEquals("ClassName", "bogus.FakeCls", pf.getClassName());
+ assertEquals("MethodName", "myMethod", pf.getMethodName());
+ assertNull("Arglist", pf.getArglist());
+ }
+
+ public void testParseBogusEmpty() {
+ String methodName = "jarid:bogus.FakeCls.myMethod()";
+ ParsedFunction pf = new ParsedFunction(methodName);
+ assertEquals("Jar ID", "jarid", pf.getJarid());
+ assertEquals("ClassName", "bogus.FakeCls", pf.getClassName());
+ assertEquals("MethodName", "myMethod", pf.getMethodName());
+ assertNotNull("Arglist", pf.getArglist());
+ assertEquals("Arglist length", 0, pf.getArglist().length);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/PigLatinTest.java b/plugin/java_udf/com/mysql/udf/test/PigLatinTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/PigLatinTest.java 2008-02-22 17:05:22 -08:00
@@ -0,0 +1,39 @@
+package com.mysql.udf.test;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.example.PigLatin;
+
+public class PigLatinTest extends TestCase {
+
+ private void check(String english, String pigLatin) {
+ assertEquals(pigLatin, PigLatin.toPigLatin(english));
+ }
+
+ public void testPigLatin() {
+ check("foo", "oofay");
+
+ check("I", "Iway");
+ check("is an", "isway anway");
+
+ check("slow", "owslay");
+ check("pnumonia", "umoniapnay");
+ check("knock", "ockknay");
+ check("write", "itewray");
+ check("string", "ingstray");
+ check("question", "estionquay");
+ check("you system", "ouyay ystemsay");
+
+ check("Pig Latin", "Igpay Atinlay");
+ check("Pig Latin.", "Igpay Atinlay.");
+ check("Pig ... Latin.", "Igpay ... Atinlay.");
+ check("be 40 Pig ... Latin.", "ebay 40 Igpay ... Atinlay.");
+
+ check("THIS IS A TEST", "ISTHAY ISWAY AWAY ESTTAY");
+
+ // from: http://en.wikipedia.org/wiki/Pig_Latin
+ String english = "This is an example of Pig Latin. As you can see, it is silly, but sort of fun for children.";
+ String pigLatin = "Isthay isway anway exampleway ofway Igpay Atinlay. Asway ouyay ancay eesay, itway isway illysay, utbay ortsay ofway unfay orfay ildrenchay.";
+ check(english, pigLatin);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/PrimesTest.java b/plugin/java_udf/com/mysql/udf/test/PrimesTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/PrimesTest.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,69 @@
+package com.mysql.udf.test;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mysql.udf.example.Primes;
+import com.mysql.udf.util.Misc;
+
+import junit.framework.TestCase;
+
+public class PrimesTest extends TestCase {
+
+ public void testIsPrime() {
+ assertEquals(false, Primes.isPrime(-3));
+ assertEquals(false, Primes.isPrime(-2));
+ assertEquals(false, Primes.isPrime(-1));
+ assertEquals(false, Primes.isPrime(0));
+ assertEquals(false, Primes.isPrime(1));
+ assertEquals(true, Primes.isPrime(2));
+ assertEquals(true, Primes.isPrime(3));
+ assertEquals(false, Primes.isPrime(4));
+ assertEquals(true, Primes.isPrime(5));
+ assertEquals(false, Primes.isPrime(6));
+ assertEquals(true, Primes.isPrime(7));
+ assertEquals(false, Primes.isPrime(8));
+ assertEquals(false, Primes.isPrime(9));
+ assertEquals(false, Primes.isPrime(10));
+ assertEquals(true, Primes.isPrime(11));
+ assertEquals(false, Primes.isPrime(12));
+ assertEquals(true, Primes.isPrime(13));
+ assertEquals(true, Primes.isPrime(1723));
+ assertEquals(false, Primes.isPrime(2317));
+ assertEquals(true, Primes.isPrime(4211));
+ }
+
+ public void testPrimesLessThan() throws SQLException {
+ ResultSet rs = Primes.upTo(100);
+
+ final ResultSetMetaData metaData = rs.getMetaData();
+ int colcount = metaData.getColumnCount();
+ assertEquals(1, colcount);
+ assertEquals("Primes", metaData.getColumnLabel(1));
+ assertEquals(2, metaData.getColumnDisplaySize(1));
+
+ List primes = new ArrayList();
+ while (rs.next()) {
+ primes.add(rs.getString(1));
+ }
+
+ String sprimes = Misc.collectionToString(primes);
+
+ assertEquals(sprimes, 25, primes.size());
+ assertEquals(sprimes, true, primes.contains("2"));
+ assertEquals(sprimes, true, primes.contains("3"));
+ assertEquals(sprimes, true, primes.contains("5"));
+ assertEquals(sprimes, true, primes.contains("7"));
+ assertEquals(sprimes, true, primes.contains("97"));
+
+ assertEquals(sprimes, false, primes.contains(null));
+ assertEquals(sprimes, false, primes.contains("1"));
+ assertEquals(sprimes, false, primes.contains("4"));
+ assertEquals(sprimes, false, primes.contains("9"));
+ assertEquals(sprimes, false, primes.contains("99"));
+ assertEquals(sprimes, false, primes.contains("100"));
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/QuickAffirmationsTest.java b/plugin/java_udf/com/mysql/udf/test/QuickAffirmationsTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/QuickAffirmationsTest.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,78 @@
+package com.mysql.udf.test;
+
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+public class QuickAffirmationsTest extends TestCase {
+ public int addOneToInt(int i) {
+ return i + 1;
+ }
+
+ public void testReflectionOfPrimatives() throws Exception {
+ Method[] methods = this.getClass().getMethods();
+ Method method = null;
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].getName().equals("addOneToInt")) {
+ method = methods[i];
+ }
+ }
+ assertNotNull(method);
+ assertEquals(Integer.TYPE, method.getParameterTypes()[0]);
+ Object[] args = new Object[] { new Integer(3) };
+ Object result = method.invoke(this, args);
+ assertEquals(Integer.class, result.getClass());
+ assertEquals(new Integer(4), result);
+ }
+
+ public void testStringArrayCasting() throws Exception {
+ Object stringArray = new String[] { "foo" };
+ assertEquals(String[].class, stringArray.getClass());
+ assertTrue(stringArray instanceof String[]);
+ assertTrue(stringArray instanceof Object[]);
+ assertEquals("[Ljava.lang.String;", stringArray.getClass().getName());
+ assertEquals("java.lang.Object", stringArray.getClass().getSuperclass()
+ .getName());
+ }
+
+ public void testIntArrayCasting() throws Exception {
+ Object intArray = new int[] { 3 };
+ assertEquals("[I", intArray.getClass().getName());
+ assertEquals("java.lang.Object", intArray.getClass().getSuperclass()
+ .getName());
+ assertTrue(intArray instanceof int[]);
+ assertEquals(int[].class, intArray.getClass());
+ assertFalse(intArray instanceof long[]);
+ assertFalse(intArray instanceof Object[]);
+
+ }
+
+ public void testIntegerArrayCasting() throws Exception {
+ Integer obj = new Integer(3);
+ Object integerArray = new Integer[] { obj };
+ assertEquals(Integer[].class, integerArray.getClass());
+ assertTrue(integerArray instanceof Integer[]);
+ assertTrue(integerArray instanceof Number[]);
+ assertTrue(integerArray instanceof Object[]);
+ assertEquals("[Ljava.lang.Integer;", integerArray.getClass().getName());
+ assertEquals(Object.class, integerArray.getClass().getSuperclass());
+ assertEquals(Number.class, obj.getClass().getSuperclass());
+ }
+
+ public void testCustomArrayCasting() throws Exception {
+ class Foo {
+ // just for test.
+ }
+ class Bar extends Foo {
+ // just for test.
+ }
+ Bar bar = new Bar();
+ Object barArray = new Bar[] { bar };
+ assertEquals(Bar[].class, barArray.getClass());
+ assertTrue(barArray instanceof Bar[]);
+ assertTrue(barArray instanceof Foo[]);
+ assertTrue(barArray instanceof Object[]);
+ assertEquals(Foo.class, bar.getClass().getSuperclass());
+ assertEquals(Object.class, barArray.getClass().getSuperclass());
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/ReverseTest.java b/plugin/java_udf/com/mysql/udf/test/ReverseTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/ReverseTest.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,19 @@
+package com.mysql.udf.test;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.example.Reverse;
+
+public class ReverseTest extends TestCase {
+
+ private void check(String forward, String reversed) {
+ assertEquals(reversed, new Reverse().go(forward));
+ }
+
+ public void testReverse() {
+ check("foo", "oof");
+ check("Hello World", "dlroW olleH");
+ check("", "");
+ check(null, null);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/TestCallback.java b/plugin/java_udf/com/mysql/udf/test/TestCallback.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/TestCallback.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,144 @@
+/**
+ *
+ */
+package com.mysql.udf.test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mysql.udf.InternalType;
+import com.mysql.udf.UDFCallback;
+
+public class TestCallback implements UDFCallback {
+
+ private List args;
+
+ private int count = Integer.MIN_VALUE;
+
+ private Object result;
+
+ void setArgCount(int count) {
+ this.count = count;
+ }
+
+ public void setArgs(List args) {
+ if (count == Integer.MIN_VALUE) {
+ count = args.size();
+ }
+ if (count != args.size()) {
+ throw new IllegalArgumentException("argcount should be " + count
+ + " but was " + args.size());
+ }
+ this.args = new ArrayList(args);
+ }
+
+ public int getArgumentCount() {
+ return count;
+ }
+
+ public int getArgumentType(int argIndex) {
+ Object arg = args.get(argIndex);
+ if (arg == null) {
+ return InternalType.UNKNOWN.typeCode;
+ }
+ if (arg.getClass() == Long.class || arg.getClass() == Integer.class
+ || arg.getClass() == Short.class
+ || arg.getClass() == Byte.class
+ || arg.getClass() == Long[].class
+ || arg.getClass() == Integer[].class
+ || arg.getClass() == Short[].class
+ || arg.getClass() == Byte[].class
+ || arg.getClass() == long[].class
+ || arg.getClass() == int[].class
+ || arg.getClass() == short[].class
+ || arg.getClass() == byte[].class) {
+ return InternalType.INTEGER_TYPE.typeCode;
+ }
+ if (arg.getClass() == String.class || arg.getClass() == String[].class) {
+ return InternalType.STRING_TYPE.typeCode;
+ }
+ if (arg.getClass() == Double.class || arg.getClass() == Float.class
+ || arg.getClass() == Double[].class
+ || arg.getClass() == Float[].class
+ || arg.getClass() == double[].class
+ || arg.getClass() == float[].class) {
+ return InternalType.REAL_TYPE.typeCode;
+ }
+ if (arg.getClass() == BigDecimal.class
+ || arg.getClass() == BigDecimal[].class) {
+ return InternalType.DECIMAL_TYPE.typeCode;
+ }
+
+ throw new RuntimeException("Test framework does not support "
+ + arg.getClass().getName());
+ }
+
+ public boolean isArgumentNull(int argIndex) {
+ return args.get(argIndex) == null;
+ }
+
+ public void setNullArgument(int argIndex) {
+ args.set(argIndex, null);
+ }
+
+ public long getLongArgument(int argIndex) {
+ return ((Long) args.get(argIndex)).longValue();
+ }
+
+ public void setLongArgument(int argIndex, long value) {
+ args.set(argIndex, new Long(value));
+ }
+
+ public String getStringArgument(int argIndex) {
+ return ((String) args.get(argIndex));
+ }
+
+ public void setStringArgument(int argIndex, String value) {
+ args.set(argIndex, value);
+ }
+
+ public BigDecimal getBigDecimalArgument(int argIndex) {
+ return ((BigDecimal) args.get(argIndex));
+ }
+
+ public void setBigDecimalArgument(int argIndex, BigDecimal value) {
+ args.set(argIndex, value);
+ }
+
+ public double getDoubleArgument(int argIndex) {
+ return ((Double) args.get(argIndex)).doubleValue();
+ }
+
+ public void setDoubleArgument(int argIndex, double value) {
+ args.set(argIndex, new Double(value));
+ }
+
+ public void storeResultNull() {
+ this.result = null;
+ }
+
+ public void storeResultLong(long value) {
+ this.result = new Long(value);
+ }
+
+ public void storeResultString(String value) {
+ this.result = value;
+ }
+
+ public void storeResultDouble(double value) {
+ this.result = new Double(value);
+ }
+
+ public void storeResultBigDecimal(BigDecimal value) {
+ this.result = value;
+ }
+
+ public void storeResultResultSet(java.sql.ResultSet returnValue) {
+ this.result = returnValue;
+ }
+
+ String resultAsString() {
+ return "" + this.result;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/TestFunction.java b/plugin/java_udf/com/mysql/udf/test/TestFunction.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/TestFunction.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,16 @@
+/**
+ *
+ */
+package com.mysql.udf.test;
+
+import java.math.BigDecimal;
+
+public class TestFunction {
+ public String bar(String s1) {
+ return "Bar: '" + s1 + "'";
+ }
+
+ public String foo(String s1, Long i, String s2, Double d, BigDecimal bd) {
+ return "Foo: '" + s1 + "' " + i + " '" + s2 + "' " + d + " " + bd;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/UDFModuleTest.java b/plugin/java_udf/com/mysql/udf/test/UDFModuleTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/UDFModuleTest.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,32 @@
+package com.mysql.udf.test;
+
+import com.mysql.udf.FunctionDescriptor;
+import com.mysql.udf.UDFModule;
+
+import junit.framework.TestCase;
+
+public class UDFModuleTest extends TestCase {
+
+ public void testInit() {
+ UDFModule module = new UDFModule();
+ String key = "system.class.path";
+ String value = System.getProperty(key);
+ String cp = key + "=" + value;
+ module.init(new String[] { cp });
+
+ assertEquals(1, module.getInitParams().size());
+ assertEquals(cp, module.getInitParams().get(0));
+ }
+
+ public void testFind() {
+ UDFModule module = new UDFModule();
+
+ String functionName = TestFunction.class.getName() + "." + "foo";
+
+ FunctionDescriptor found1 = module.find(functionName);
+
+ FunctionDescriptor found2 = module.find(functionName);
+
+ assertSame(found1, found2);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/example/PigLatinTest.java b/plugin/java_udf/com/mysql/udf/test/example/PigLatinTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/example/PigLatinTest.java 2008-02-22 17:05:23 -08:00
@@ -0,0 +1,39 @@
+package com.mysql.udf.test.example;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.example.PigLatin;
+
+public class PigLatinTest extends TestCase {
+
+ private void check(String english, String pigLatin) {
+ assertEquals(pigLatin, PigLatin.toPigLatin(english));
+ }
+
+ public void testPigLatin() {
+ check("foo", "oofay");
+
+ check("I", "Iway");
+ check("is an", "isway anway");
+
+ check("slow", "owslay");
+ check("pnumonia", "umoniapnay");
+ check("knock", "ockknay");
+ check("write", "itewray");
+ check("string", "ingstray");
+ check("question", "estionquay");
+ check("you system", "ouyay ystemsay");
+
+ check("Pig Latin", "Igpay Atinlay");
+ check("Pig Latin.", "Igpay Atinlay.");
+ check("Pig ... Latin.", "Igpay ... Atinlay.");
+ check("be 40 Pig ... Latin.", "ebay 40 Igpay ... Atinlay.");
+
+ check("THIS IS A TEST", "ISTHAY ISWAY AWAY ESTTAY");
+
+ // from: http://en.wikipedia.org/wiki/Pig_Latin
+ String english = "This is an example of Pig Latin. As you can see, it is silly, but sort of fun for children.";
+ String pigLatin = "Isthay isway anway exampleway ofway Igpay Atinlay. Asway ouyay ancay eesay, itway isway illysay, utbay ortsay ofway unfay orfay ildrenchay.";
+ check(english, pigLatin);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/example/PrimesTest.java b/plugin/java_udf/com/mysql/udf/test/example/PrimesTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/example/PrimesTest.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,69 @@
+package com.mysql.udf.test.example;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.example.Primes;
+import com.mysql.udf.util.Misc;
+
+public class PrimesTest extends TestCase {
+
+ public void testIsPrime() {
+ assertEquals(false, Primes.isPrime(-3));
+ assertEquals(false, Primes.isPrime(-2));
+ assertEquals(false, Primes.isPrime(-1));
+ assertEquals(false, Primes.isPrime(0));
+ assertEquals(false, Primes.isPrime(1));
+ assertEquals(true, Primes.isPrime(2));
+ assertEquals(true, Primes.isPrime(3));
+ assertEquals(false, Primes.isPrime(4));
+ assertEquals(true, Primes.isPrime(5));
+ assertEquals(false, Primes.isPrime(6));
+ assertEquals(true, Primes.isPrime(7));
+ assertEquals(false, Primes.isPrime(8));
+ assertEquals(false, Primes.isPrime(9));
+ assertEquals(false, Primes.isPrime(10));
+ assertEquals(true, Primes.isPrime(11));
+ assertEquals(false, Primes.isPrime(12));
+ assertEquals(true, Primes.isPrime(13));
+ assertEquals(true, Primes.isPrime(1723));
+ assertEquals(false, Primes.isPrime(2317));
+ assertEquals(true, Primes.isPrime(4211));
+ }
+
+ public void testPrimesLessThan() throws SQLException {
+ ResultSet rs = Primes.upTo(100);
+
+ final ResultSetMetaData metaData = rs.getMetaData();
+ int colcount = metaData.getColumnCount();
+ assertEquals(1, colcount);
+ assertEquals("Primes", metaData.getColumnLabel(1));
+ assertEquals(2, metaData.getColumnDisplaySize(1));
+
+ List primes = new ArrayList();
+ while (rs.next()) {
+ primes.add(rs.getString(1));
+ }
+
+ String sprimes = Misc.collectionToString(primes);
+
+ assertEquals(sprimes, 25, primes.size());
+ assertEquals(sprimes, true, primes.contains("2"));
+ assertEquals(sprimes, true, primes.contains("3"));
+ assertEquals(sprimes, true, primes.contains("5"));
+ assertEquals(sprimes, true, primes.contains("7"));
+ assertEquals(sprimes, true, primes.contains("97"));
+
+ assertEquals(sprimes, false, primes.contains(null));
+ assertEquals(sprimes, false, primes.contains("1"));
+ assertEquals(sprimes, false, primes.contains("4"));
+ assertEquals(sprimes, false, primes.contains("9"));
+ assertEquals(sprimes, false, primes.contains("99"));
+ assertEquals(sprimes, false, primes.contains("100"));
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/example/ReverseTest.java b/plugin/java_udf/com/mysql/udf/test/example/ReverseTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/example/ReverseTest.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,19 @@
+package com.mysql.udf.test.example;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.example.Reverse;
+
+public class ReverseTest extends TestCase {
+
+ private void check(String forward, String reversed) {
+ assertEquals(reversed, new Reverse().go(forward));
+ }
+
+ public void testReverse() {
+ check("foo", "oof");
+ check("Hello World", "dlroW olleH");
+ check("", "");
+ check(null, null);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/util/MiscTest.java b/plugin/java_udf/com/mysql/udf/test/util/MiscTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/util/MiscTest.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,22 @@
+package com.mysql.udf.test.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.util.Misc;
+
+public class MiscTest extends TestCase {
+ public void testListToString() {
+ List l = new ArrayList();
+ l.add("one");
+ l.add(null);
+ l.add("three");
+ l.add(new Integer(4));
+
+ String expected = "[one, null, three, 4]";
+ String actual = Misc.collectionToString(l);
+ assertEquals(expected, actual);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/test/util/SimpleResultSetTest.java b/plugin/java_udf/com/mysql/udf/test/util/SimpleResultSetTest.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/test/util/SimpleResultSetTest.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,55 @@
+package com.mysql.udf.test.util;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+import junit.framework.TestCase;
+
+import com.mysql.udf.util.SimpleResultSet;
+
+public class SimpleResultSetTest extends TestCase {
+ public void testOurUsage() throws SQLException {
+ String[] columNames = new String[] { "a", "b", "c" };
+ SimpleResultSet rs = new SimpleResultSet(columNames);
+ rs.addRow(new Object[] { "foo", "bar", "baz" });
+ rs.addRow(new Object[] { "golly", "gee", "whiz" });
+
+ final ResultSetMetaData metaData = rs.getMetaData();
+ int colcount = metaData.getColumnCount();
+ for (int i = 1; i <= colcount; i++) {
+ String name = metaData.getColumnLabel(i);
+ assertEquals(columNames[i - 1], name);
+ int expectedWidth;
+ switch (i) {
+ case 1:
+ expectedWidth = 5;
+ break;
+ case 2:
+ expectedWidth = 3;
+ break;
+ case 3:
+ expectedWidth = 4;
+ break;
+ default:
+ throw new RuntimeException("?!");
+ }
+ int width = metaData.getColumnDisplaySize(i);
+ assertEquals(expectedWidth, width);
+ }
+
+ String[][] resultMatrix = new String[2][3];
+
+ for (int j = 0; rs.next(); j++) {
+ for (int i = 1; i <= colcount; i++) {
+ resultMatrix[j][i - 1] = rs.getString(i);
+ }
+ }
+
+ assertEquals("foo", resultMatrix[0][0]);
+ assertEquals("bar", resultMatrix[0][1]);
+ assertEquals("baz", resultMatrix[0][2]);
+ assertEquals("golly", resultMatrix[1][0]);
+ assertEquals("gee", resultMatrix[1][1]);
+ assertEquals("whiz", resultMatrix[1][2]);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/util/Misc.java b/plugin/java_udf/com/mysql/udf/util/Misc.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/util/Misc.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,49 @@
+package com.mysql.udf.util;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class Misc {
+
+ public static String arrayToString(Object[] objs) {
+ if (objs == null) {
+ return null;
+ }
+ // Arrays.asList(args).toString();
+ StringBuffer buf = new StringBuffer();
+ buf.append("[");
+ for (int i = 0; i < objs.length; i++) {
+ Object object = objs[i];
+ if (object instanceof Object[]) {
+ buf.append(arrayToString((Object[]) object));
+ } else if (object instanceof Collection) {
+ buf.append(collectionToString((Collection) object));
+ } else if (object instanceof Map) {
+ buf.append(mapToString((Map) object));
+ } else if (object instanceof Map.Entry) {
+ Map.Entry entry = (Map.Entry) object;
+ buf.append(entry.getKey());
+ buf.append('=');
+ buf.append(entry.getValue());
+ } else {
+ buf.append(object);
+ }
+ buf.append(", ");
+ }
+ return buf.substring(0, buf.length() - 2) + "]";
+ }
+
+ public static String collectionToString(Collection collection) {
+ if (collection == null) {
+ return null;
+ }
+ return arrayToString(collection.toArray());
+ }
+
+ public static String mapToString(Map map) {
+ if (map == null) {
+ return null;
+ }
+ return collectionToString(map.entrySet());
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/util/NotImplementedException.java b/plugin/java_udf/com/mysql/udf/util/NotImplementedException.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/util/NotImplementedException.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,41 @@
+package com.mysql.udf.util;
+
+import java.sql.SQLException;
+
+
+public class NotImplementedException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public NotImplementedException() {
+ super();
+ }
+
+ public NotImplementedException(Object[] args) {
+ super("args: " + args == null ? null : Misc.arrayToString(args));
+ }
+
+ public NotImplementedException(Object arg0) {
+ this(new Object[] { arg0 });
+ }
+
+ public NotImplementedException(Object arg0, Object arg1) {
+ this(new Object[] { arg0, arg1 });
+ }
+
+ public NotImplementedException(Object arg0, Object arg1, Object arg2) {
+ this(new Object[] { arg0, arg1, arg2 });
+ }
+
+ static class AsSQLException extends SQLException {
+ private static final long serialVersionUID = 1L;
+
+ public AsSQLException(Throwable t) {
+ super(t.getMessage());
+ initCause(t);
+ }
+ }
+
+ public SQLException asSQL() {
+ return new AsSQLException(this);
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/util/SimpleResultSet.java b/plugin/java_udf/com/mysql/udf/util/SimpleResultSet.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/util/SimpleResultSet.java 2008-02-22 17:05:24 -08:00
@@ -0,0 +1,150 @@
+package com.mysql.udf.util;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SimpleResultSet extends ThrowingResultSet {
+ private List columns;
+ private MetaData metaData;
+ private List rows;
+ private Iterator currentIterator;
+ private Object[] currentRow;
+ private String tostring;
+
+ public SimpleResultSet(String[] columns) {
+ if (columns == null) {
+ throw new IllegalArgumentException("null");
+ }
+ this.columns = Arrays.asList(columns);
+ this.metaData = new MetaData();
+ this.rows = new LinkedList();
+ }
+
+ public void addRow(Object[] row) {
+ if (row == null) {
+ throw new IllegalArgumentException("null");
+ }
+ if (row.length != columns.size()) {
+ throw new IllegalArgumentException("expected row length of "
+ + columns.size() + " but was " + row.length + ".");
+ }
+ rows.add(row);
+ tostring = null;
+ }
+
+ private Object currentRowValue(int index) {
+ if (currentRow == null) {
+ throw new IllegalStateException();
+ }
+ if (index < 0 || index >= currentRow.length) {
+ String msg = "adjusted index of " + index + " not between 0 and "
+ + (currentRow.length - 1);
+ throw new IllegalArgumentException(msg);
+ }
+ return currentRow[index];
+ }
+
+ private int nameToIndex(String columnName) {
+ int columnIndex = -1;
+ for (int i = 0; columnIndex < 0 && i < columns.size(); i++) {
+ String column = columns.get(i).toString();
+ if (column.equalsIgnoreCase(columnName)) {
+ columnIndex = i;
+ }
+ }
+ if (columnIndex < 0) {
+ String msg = columnName + " not in: "
+ + Misc.collectionToString(columns);
+ throw new IllegalArgumentException(msg);
+ }
+ return columnIndex;
+ }
+
+ // -----------------
+
+ public boolean next() throws SQLException {
+ if (currentIterator == null) {
+ currentIterator = rows.iterator();
+ }
+ if (currentIterator.hasNext()) {
+ currentRow = (Object[]) currentIterator.next();
+ } else {
+ currentRow = null;
+ }
+ return currentRow != null;
+ }
+
+ public void close() {
+ currentIterator = null;
+ currentRow = null;
+ }
+
+ public Object getObject(int columnIndex) throws SQLException {
+ return currentRowValue(columnIndex - 1);
+ }
+
+ public Object getObject(String columnName) throws SQLException {
+ return currentRowValue(nameToIndex(columnName));
+ }
+
+ public String getString(int columnIndex) throws SQLException {
+ Object val = getObject(columnIndex);
+ return val == null ? null : val.toString();
+ }
+
+ public String getString(String columnName) throws SQLException {
+ Object val = getObject(columnName);
+ return val == null ? null : val.toString();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return metaData;
+ }
+
+ class MetaData extends ThrowingResultSetMetaData {
+ public int getColumnCount() {
+ return columns.size();
+ }
+
+ public String getColumnLabel(int columnIndex) {
+ return columns.get(columnIndex - 1).toString();
+ }
+
+ public int getColumnDisplaySize(int columnIndex) throws SQLException {
+ int size = 0;
+ for (Iterator it = rows.iterator(); it.hasNext();) {
+ Object[] row = (Object[]) it.next();
+ Object colVal = row[columnIndex - 1];
+ int thisRowSize;
+ if (colVal == null) {
+ thisRowSize = ("" + null).length();
+ } else {
+ thisRowSize = colVal.toString().length();
+ }
+ if (size < thisRowSize) {
+ size = thisRowSize;
+ }
+ }
+ return size;
+ }
+ }
+
+ public String toString() {
+ if (tostring == null) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("Columns: ").append(Misc.collectionToString(columns));
+ buf.append("\n");
+ buf.append("Rows: \n");
+ for (Iterator it = rows.iterator(); it.hasNext();) {
+ buf.append(Misc.arrayToString((Object[]) it.next()));
+ buf.append("\n");
+ }
+ tostring = buf.toString();
+ }
+ return tostring;
+ }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/util/ThrowingResultSet.java b/plugin/java_udf/com/mysql/udf/util/ThrowingResultSet.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/util/ThrowingResultSet.java 2008-02-22 17:05:25 -08:00
@@ -0,0 +1,822 @@
+package com.mysql.udf.util;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+public class ThrowingResultSet implements ResultSet {
+
+ public boolean absolute(int row) throws SQLException {
+ throw new NotImplementedException(new Integer(row)).asSQL();
+ }
+
+ public void afterLast() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void beforeFirst() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void cancelRowUpdates() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void clearWarnings() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void close() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void deleteRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public int findColumn(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public boolean first() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public Array getArray(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Array getArray(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public InputStream getAsciiStream(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public InputStream getAsciiStream(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public BigDecimal getBigDecimal(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public BigDecimal getBigDecimal(int columnIndex, int scale)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex),
+ new Integer(scale)).asSQL();
+ }
+
+ public BigDecimal getBigDecimal(String columnName, int scale)
+ throws SQLException {
+ throw new NotImplementedException(columnName, new Integer(scale))
+ .asSQL();
+ }
+
+ public InputStream getBinaryStream(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public InputStream getBinaryStream(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Blob getBlob(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Blob getBlob(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public boolean getBoolean(int columnName) throws SQLException {
+ throw new NotImplementedException(new Integer(columnName)).asSQL();
+ }
+
+ public boolean getBoolean(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public byte getByte(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public byte getByte(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public byte[] getBytes(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public byte[] getBytes(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Reader getCharacterStream(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Reader getCharacterStream(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Clob getClob(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Clob getClob(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public int getConcurrency() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public String getCursorName() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public Date getDate(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Date getDate(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), cal)
+ .asSQL();
+ }
+
+ public Date getDate(String columnName, Calendar cal) throws SQLException {
+ throw new NotImplementedException(columnName, cal).asSQL();
+ }
+
+ public double getDouble(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public double getDouble(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public int getFetchDirection() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public int getFetchSize() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public float getFloat(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public float getFloat(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public int getInt(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public int getInt(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public long getLong(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public long getLong(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public Object getObject(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Object getObject(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Ref getRef(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Ref getRef(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public int getRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public short getShort(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public short getShort(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Statement getStatement() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public String getString(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public String getString(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Time getTime(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Time getTime(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), cal)
+ .asSQL();
+ }
+
+ public Time getTime(String columnName, Calendar cal) throws SQLException {
+ throw new NotImplementedException(columnName, cal).asSQL();
+ }
+
+ public Timestamp getTimestamp(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Timestamp getTimestamp(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public Timestamp getTimestamp(int columnIndex, Calendar cal)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), cal)
+ .asSQL();
+ }
+
+ public Timestamp getTimestamp(String columnName, Calendar cal)
+ throws SQLException {
+ throw new NotImplementedException(columnName, cal).asSQL();
+ }
+
+ public int getType() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public URL getURL(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public URL getURL(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public InputStream getUnicodeStream(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void insertRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean isAfterLast() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean isBeforeFirst() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean isFirst() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean isLast() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean last() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void moveToCurrentRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void moveToInsertRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean next() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean previous() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void refreshRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean relative(int rows) throws SQLException {
+ throw new NotImplementedException(new Integer(rows)).asSQL();
+ }
+
+ public boolean rowDeleted() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean rowInserted() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public boolean rowUpdated() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void setFetchDirection(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public void setFetchSize(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public void updateArray(int columnIndex, Array x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateArray(String columnName, Array x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateAsciiStream(int columnIndex, InputStream x, int length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Integer(length)).asSQL();
+ }
+
+ public void updateAsciiStream(String columnName, InputStream x, int length)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x, new Integer(length))
+ .asSQL();
+ }
+
+ public void updateBigDecimal(int columnIndex, BigDecimal x)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateBigDecimal(String columnName, BigDecimal x)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateBinaryStream(int columnIndex, InputStream x, int length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Integer(length)).asSQL();
+ }
+
+ public void updateBinaryStream(String columnName, InputStream x, int length)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x, new Integer(length))
+ .asSQL();
+ }
+
+ public void updateBlob(int columnIndex, Blob x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateBlob(String columnName, Blob x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateBoolean(int columnIndex, boolean x)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), Boolean
+ .valueOf(x)).asSQL();
+ }
+
+ public void updateBoolean(String columnName, boolean x)
+ throws SQLException {
+ throw new NotImplementedException(columnName, Boolean.valueOf(x))
+ .asSQL();
+ }
+
+ public void updateByte(int columnIndex, byte x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), new Byte(
+ x)).asSQL();
+ }
+
+ public void updateByte(String columnName, byte x) throws SQLException {
+ throw new NotImplementedException(columnName, new Byte(x)).asSQL();
+ }
+
+ public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateBytes(String columnName, byte[] x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateCharacterStream(int columnIndex, Reader x, int length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Integer(length)).asSQL();
+ }
+
+ public void updateCharacterStream(String columnName, Reader x, int length)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x, new Integer(length))
+ .asSQL();
+ }
+
+ public void updateClob(int columnIndex, Clob x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateClob(String columnName, Clob x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateDate(int columnIndex, Date x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateDate(String columnName, Date x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateDouble(int columnIndex, double x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), new Double(
+ x)).asSQL();
+ }
+
+ public void updateDouble(String columnName, double x)
+ throws SQLException {
+ throw new NotImplementedException(columnName, new Double(x)).asSQL();
+ }
+
+ public void updateFloat(int columnIndex, float x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), new Float(
+ x)).asSQL();
+ }
+
+ public void updateFloat(String columnName, float x) throws SQLException {
+ throw new NotImplementedException(columnName, new Float(x)).asSQL();
+ }
+
+ public void updateInt(int columnIndex, int x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex),
+ new Integer(x)).asSQL();
+ }
+
+ public void updateInt(String columnName, int x) throws SQLException {
+ throw new NotImplementedException(columnName, new Integer(x))
+ .asSQL();
+ }
+
+ public void updateLong(int columnIndex, long x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), new Long(
+ x)).asSQL();
+ }
+
+ public void updateLong(String columnName, long x) throws SQLException {
+ throw new NotImplementedException(columnName, new Long(x)).asSQL();
+ }
+
+ public void updateNull(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public void updateNull(String columnName) throws SQLException {
+ throw new NotImplementedException(columnName).asSQL();
+ }
+
+ public void updateObject(int columnIndex, Object x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateObject(String columnName, Object x)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateObject(int columnIndex, Object x, int scale)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Integer(scale)).asSQL();
+ }
+
+ public void updateObject(String columnName, Object x, int scale)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x, new Integer(scale))
+ .asSQL();
+ }
+
+ public void updateRef(int columnIndex, Ref x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateRef(String columnName, Ref x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateRow() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void updateShort(int columnIndex, short x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), new Short(
+ x)).asSQL();
+ }
+
+ public void updateShort(String columnName, short x) throws SQLException {
+ throw new NotImplementedException(columnName, new Short(x)).asSQL();
+ }
+
+ public void updateString(int columnIndex, String x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateString(String columnName, String x)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateTime(int columnIndex, Time x) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateTime(String columnName, Time x) throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public void updateTimestamp(int columnIndex, Timestamp x)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x)
+ .asSQL();
+ }
+
+ public void updateTimestamp(String columnName, Timestamp x)
+ throws SQLException {
+ throw new NotImplementedException(columnName, x).asSQL();
+ }
+
+ public boolean wasNull() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ // @SuppressWarnings("unchecked")
+ // public Object getObject(int columnIndex, Map x) throws SQLException {
+ // throw new NotImplementedException(new Integer(columnIndex), x).asSQL();
+ // }
+ //
+ // @SuppressWarnings("unchecked")
+ // public Object getObject(String columnName, Map x) throws SQLException {
+ // throw new NotImplementedException(columnName, x).asSQL();
+ // }
+
+ // --------------
+
+ public int getHoldability() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public Reader getNCharacterStream(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public Reader getNCharacterStream(String columnLabel) throws SQLException {
+ throw new NotImplementedException(columnLabel).asSQL();
+ }
+
+ public String getNString(int columnIndex) throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ }
+
+ public String getNString(String columnLabel) throws SQLException {
+ throw new NotImplementedException(columnLabel).asSQL();
+ }
+
+ public Object getObject(int columnIndex, Map/* <String, Class<?>> */map)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), map)
+ .asSQL();
+ }
+
+ public Object getObject(String columnLabel, Map/* <String, Class<?>> */map)
+ throws SQLException {
+ throw new NotImplementedException(columnLabel, map).asSQL();
+ }
+
+ public boolean isClosed() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public void updateAsciiStream(int columnIndex, InputStream x, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Long(length)).asSQL();
+ }
+
+ public void updateAsciiStream(String columnLabel, InputStream x, long length)
+ throws SQLException {
+ throw new NotImplementedException(columnLabel, x, new Long(length))
+ .asSQL();
+ }
+
+ public void updateBinaryStream(int columnIndex, InputStream x, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Long(length)).asSQL();
+ }
+
+ public void updateBinaryStream(String columnLabel, InputStream x,
+ long length) throws SQLException {
+ throw new NotImplementedException(columnLabel, x, new Long(length))
+ .asSQL();
+ }
+
+ public void updateBlob(int columnIndex, InputStream inputStream, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex),
+ inputStream, new Long(length)).asSQL();
+ }
+
+ public void updateBlob(String columnLabel, InputStream inputStream,
+ long length) throws SQLException {
+ throw new NotImplementedException(new Integer(columnLabel),
+ inputStream, new Long(length)).asSQL();
+ }
+
+ public void updateCharacterStream(int columnIndex, Reader x, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Long(length)).asSQL();
+ }
+
+ public void updateCharacterStream(String columnLabel, Reader reader,
+ long length) throws SQLException {
+ throw new NotImplementedException(columnLabel, reader, new Long(length))
+ .asSQL();
+ }
+
+ public void updateClob(int columnIndex, Reader reader, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), reader,
+ new Long(length)).asSQL();
+ }
+
+ public void updateClob(String columnLabel, Reader reader, long length)
+ throws SQLException {
+ throw new NotImplementedException(columnLabel, reader, new Long(length))
+ .asSQL();
+ }
+
+ public void updateNCharacterStream(int columnIndex, Reader x, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), x,
+ new Long(length)).asSQL();
+ }
+
+ public void updateNCharacterStream(String columnLabel, Reader reader,
+ long length) throws SQLException {
+ throw new NotImplementedException(columnLabel, reader, new Long(length))
+ .asSQL();
+ }
+
+ public void updateNClob(int columnIndex, Reader reader, long length)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), reader,
+ new Long(length)).asSQL();
+ }
+
+ public void updateNClob(String columnLabel, Reader reader, long length)
+ throws SQLException {
+ throw new NotImplementedException(columnLabel, reader, new Long(length))
+ .asSQL();
+ }
+
+ public void updateNString(int columnIndex, String string)
+ throws SQLException {
+ throw new NotImplementedException(new Integer(columnIndex), string)
+ .asSQL();
+ }
+
+ public void updateNString(String columnLabel, String string)
+ throws SQLException {
+ throw new NotImplementedException(columnLabel, string).asSQL();
+ }
+
+ // public NClob getNClob(int columnIndex) throws SQLException {
+ // throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ // }
+ //
+ // public NClob getNClob(String columnLabel) throws SQLException {
+ // throw new NotImplementedException(columnLabel).asSQL();
+ // }
+ //
+ // public RowId getRowId(int columnIndex) throws SQLException {
+ // throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ // }
+ //
+ // public RowId getRowId(String columnLabel) throws SQLException {
+ // throw new NotImplementedException(columnLabel).asSQL();
+ // }
+ //
+ // public SQLXML getSQLXML(int columnIndex) throws SQLException {
+ // throw new NotImplementedException(new Integer(columnIndex)).asSQL();
+ // }
+ //
+ // public SQLXML getSQLXML(String columnLabel) throws SQLException {
+ // throw new NotImplementedException(columnLabel).asSQL();
+ // }
+ //
+ // public void updateNClob(int columnIndex, NClob clob) throws SQLException
+ // {
+ // throw new NotImplementedException(new Integer(columnIndex),
+ // clob).asSQL();
+ // }
+ //
+ // public void updateNClob(String columnLabel, NClob clob) throws
+ // SQLException {
+ // throw new NotImplementedException(columnLabel, clob).asSQL();
+ // }
+ //
+ // public void updateRowId(int columnIndex, RowId x) throws SQLException {
+ // throw new NotImplementedException(new Integer(columnIndex), x).asSQL();
+ // }
+ //
+ // public void updateRowId(String columnLabel, RowId x) throws SQLException
+ // {
+ // throw new NotImplementedException(columnLabel, x).asSQL();
+ // }
+ //
+ // public void updateSQLXML(int columnIndex, SQLXML xmlObject)
+ // throws SQLException {
+ // throw new NotImplementedException(new Integer(columnIndex),
+ // xmlObject).asSQL();
+ // }
+ //
+ // public void updateSQLXML(String columnLabel, SQLXML xmlObject)
+ // throws SQLException {
+ // throw new NotImplementedException(columnLabel, xmlObject).asSQL();
+ // }
+}
diff -Nrup a/plugin/java_udf/com/mysql/udf/util/ThrowingResultSetMetaData.java b/plugin/java_udf/com/mysql/udf/util/ThrowingResultSetMetaData.java
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/com/mysql/udf/util/ThrowingResultSetMetaData.java 2008-02-22 17:05:25 -08:00
@@ -0,0 +1,92 @@
+package com.mysql.udf.util;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+
+
+public class ThrowingResultSetMetaData implements ResultSetMetaData {
+
+ public String getCatalogName(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public String getColumnClassName(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public int getColumnCount() throws SQLException {
+ throw new NotImplementedException().asSQL();
+ }
+
+ public int getColumnDisplaySize(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public String getColumnLabel(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public String getColumnName(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public int getColumnType(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public String getColumnTypeName(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public int getPrecision(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public int getScale(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public String getSchemaName(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public String getTableName(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isAutoIncrement(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isCaseSensitive(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isCurrency(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isDefinitelyWritable(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public int isNullable(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isReadOnly(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isSearchable(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isSigned(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+
+ public boolean isWritable(int column) throws SQLException {
+ throw new NotImplementedException(new Integer(column)).asSQL();
+ }
+}
diff -Nrup a/plugin/java_udf/grokjni.pl b/plugin/java_udf/grokjni.pl
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/grokjni.pl 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+
+$struct_name= "native_methods";
+
+print "/* WARNING - THIS FILE IS AUTOMATICALLY GENERATED */\n".
+ "static const JNINativeMethod ".$struct_name."[] =\n{\n";
+while ($ln= <>)
+{
+ $classname=$1 if $ln =~ m/Class:\s+(.*)/;
+ $method=$1 if $ln =~ m/Method:\s+(.*)/;
+ $signature=$1 if $ln =~ m/Signature:\s+(.*)/;
+
+ next if not ( $ln =~ m/JNICALL (.*)/);
+ $function_name= $1;
+
+ print " {\n".
+ " (char*) \"$method\",\n".
+ " (char*) \"$signature\",\n".
+ " (void*) $function_name\n".
+ " },\n";
+}
+
+print "};\n\nstatic const int ${struct_name}_count=\n".
+ "\tsizeof($struct_name)/sizeof(JNINativeMethod);\n";
+
diff -Nrup a/plugin/java_udf/java_context.cc b/plugin/java_udf/java_context.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_context.cc 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,1193 @@
+#include "jvm_interface.h"
+#include "java_context.h"
+#include "jvm_singleton.h"
+#include <stdio.h>
+#include <jni.h>
+#include <string.h>
+
+#if 1
+#define JNI_DBUG_ENTER(a1)
+#define JNI_DBUG_RETURN(a0, a1) return(a1)
+#define JNI_DBUG_VOID_RETURN(a0) return
+#define JNI_DBUG_PRINT(a0, a1)
+# else
+#define JNI_DBUG_ENTER(a1) fprintf(stderr, "entering: ");fprintf(stderr, a1);fprintf(stderr, "\n");
+#define JNI_DBUG_RETURN(a0, a1) fprintf(stderr, "leaving %s\n", a0); return(a1)
+#define JNI_DBUG_VOID_RETURN(a0) fprintf(stderr, "leaving %s\n", a0); return
+#define JNI_DBUG_PRINT(a0, a1) fprintf(stderr, a0, a1); fprintf(stderr, "\n");
+#endif
+
+// JNI Signatures
+const char *JNI_VOID= "V";
+const char *JNI_INT= "I";
+const char *JNI_LONG= "J";
+const char *JNI_BOOL= "Z";
+const char *JNI_OBJECT= "Ljava/lang/Object;";
+const char *JNI_STRING= "Ljava/lang/String;";
+
+const char *FOUR_STRINGS_RETURN_VOID= "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
+const char *STRING_RETURN_VOID= "(Ljava/lang/String;)V";
+const char *EMPTY_RETURN_VOID= "()V";
+const char *STRING_RETURN_INT= "(Ljava/lang/String;)I";
+const char *EMPTY_RETURN_BOOL= "()Z";
+const char *EMPTY_RETURN_INT= "()I";
+const char *EMPTY_RETURN_OBJECT= "()Ljava/lang/Object;";
+const char *OBJECT_RETURN_OBJECT= "(Ljava/lang/Object;)Ljava/lang/Object;";
+const char *OBJECT_RETURN_BOOL= "(Ljava/lang/Object;)Z";
+const char *EMPTY_RETURN_STRING= "()Ljava/lang/String;";
+const char *STRING_RETURN_BYTE_ARRAY= "(Ljava/lang/String;)[B";
+const char *INT_RETURN_BYTE_ARRAY= "(I)[B";
+const char *INT_BYTE_ARRAY_RETURN_VOID= "(I[B)V";
+const char *STRING_RETURN_STRING= "(Ljava/lang/String;)Ljava/lang/String;";
+const char *LONG_RETURN_VOID= "(J)V";
+
+
+Java_context::Java_context(JNIEnv *jenv)
+{
+ env= jenv;
+}
+
+Java_context::~Java_context()
+{
+ Jvm *jvm= Jvm_singleton::check();
+ if (jvm)
+ jvm->detach();
+}
+
+int Java_context::get_version()
+{
+ JNI_DBUG_ENTER("Java_context::get_version");
+ int version= (int) env->GetVersion();
+ JNI_DBUG_RETURN("Java_context::get_version", version);
+}
+
+jstring Java_context::to_jstring(const char *str)
+{
+ JNI_DBUG_ENTER("Java_context::to_jstring");
+ if (str == NULL)
+ {
+ JNI_DBUG_RETURN("Java_context::to_jstring", NULL);
+ }
+
+ // if we can specify unicode, then NewStringUTF will probably be wrong.
+ jstring ljstr= env->NewStringUTF(str);
+ if (ljstr == NULL)
+ {
+ fprintf(stderr,
+ "Out of memory? Unable to allocate 'jstring' from chars: \"%s\"\n", str);
+ JNI_DBUG_RETURN("Java_context::to_jstring", NULL);
+ }
+ jstring jstr= (jstring)to_global_reference(ljstr);
+
+ JNI_DBUG_RETURN("Java_context::to_jstring", jstr);
+}
+
+
+jbyteArray Java_context::to_java_byte_array(const char *str)
+{
+ JNI_DBUG_ENTER("Java_context::to_java_byte_array");
+ int size= position_of_null(str);
+ jbyteArray lar= env->NewByteArray(size);
+ if (lar == NULL)
+ {
+ fprintf(stderr,
+ "Out of memory? Unable to allocate 'jbyteArray' of size: %d\n", size);
+ JNI_DBUG_RETURN("Java_context::to_java_byte_array", NULL);
+ }
+ jbyteArray ar= (jbyteArray) to_global_reference(lar);
+ if (ar == NULL)
+ fprintf(stderr, "The 'jbyteArray' is NULL");
+ else
+ env->SetByteArrayRegion(ar, 0, size, (jbyte*) str);
+ JNI_DBUG_RETURN("Java_context::to_java_byte_array", ar);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object no args");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+
+ jvalue args[0];
+
+ jobject rv= new_java_object(class_name, EMPTY_RETURN_VOID, args);
+ JNI_DBUG_RETURN("Java_context::new_java_object no args", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object string arg");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0=%s", arg0);
+
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+
+ JNI_DBUG_PRINT("calling new %s...", class_name);
+ JNI_DBUG_PRINT(" with args %s", arg0);
+ jobject rv= new_java_object(class_name, STRING_RETURN_VOID, args);
+ delete_global_reference(args[0].l);
+ JNI_DBUG_PRINT("new java object %p\n ", rv);
+ JNI_DBUG_RETURN("Java_context::new_java_object string arg", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ char *argv1[],
+ int argc1,
+ const char *arg2)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object args: obj, string[] str");
+ JNI_DBUG_PRINT("This function will cause a seg fault%s", "");
+
+ jobject js0= (arg0 == NULL) ? NULL : arg0->as_java_object();
+ jstring js2= to_jstring(arg2);
+ jobjectArray jsa= to_string_array(argv1, argc1);
+ jvalue args[3];
+ args[0].l= js0;
+ args[1].l= jsa;
+ args[2].l= js2;
+
+ const char *field_class_name= arg0->java_parameter_class();
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field_class_name);
+
+ strcat(method_signature, "[");
+ strcat(method_signature, JNI_STRING);
+
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ //fprintf(stderr, "method signature: %s\n", method_signature);
+
+ jobject rv= new_java_object(class_name, method_signature, args);
+
+ delete_global_reference(js2);
+ release_java_string_array(jsa, argc1);
+ JNI_DBUG_RETURN("Java_context::new_java_object args: obj, string[] str", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ const char *arg1,
+ const char *arg2)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object: obj, str, str");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0=<%s>",
+ (arg0 == NULL) ? "(null)" : arg0->java_parameter_class());
+ JNI_DBUG_PRINT("arg1=%s", arg1);
+ JNI_DBUG_PRINT("arg2=%s", arg2);
+
+ jobject ja0= (arg0 == NULL) ? NULL : arg0->as_java_object();
+ jstring js1= to_jstring(arg1);
+ jstring js2= to_jstring(arg2);
+
+ jvalue args[3];
+ args[0].l= ja0;
+ args[1].l= js1;
+ args[2].l= js2;
+
+ const char *field_class_name= arg0->java_parameter_class();
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field_class_name);
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ //fprintf(stderr, "method signature: %s\n", method_signature);
+
+ jobject rv= new_java_object(class_name, method_signature, args);
+ delete_global_reference(js1);
+ delete_global_reference(js2);
+ JNI_DBUG_RETURN("Java_context::new_java_object: obj, str, str", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ const char *arg0,
+ const char *arg1,
+ const char *arg2,
+ const char *arg3)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object: str, str, str, str");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0=%s", arg0);
+ JNI_DBUG_PRINT("arg1=%s", arg1);
+ JNI_DBUG_PRINT("arg2=%s", arg2);
+ JNI_DBUG_PRINT("arg3=%s", arg3);
+
+ jvalue args[4];
+ args[0].l= to_jstring(arg0);
+ args[1].l= to_jstring(arg1);
+ args[2].l= to_jstring(arg2);
+ args[3].l= to_jstring(arg3);
+
+ jobject rv= new_java_object(class_name, FOUR_STRINGS_RETURN_VOID, args);
+ delete_global_reference(args[0].l);
+ delete_global_reference(args[1].l);
+ delete_global_reference(args[2].l);
+ delete_global_reference(args[3].l);
+ JNI_DBUG_RETURN("Java_context::new_java_object: str, str, str, str", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ Java_object_parameter *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object: arg: Java_object_parameter");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0 class=<%s>",
+ arg==NULL ? "(null)" : arg0->java_parameter_class());
+
+ jobject ja0= (arg0 == NULL) ? NULL : arg0->as_java_object();
+
+ jvalue args[1];
+ args[0].l= ja0;
+
+ const char *field_class_name= arg0->java_parameter_class();
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field_class_name);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ //fprintf(stderr, "method signature: %s\n", method_signature);
+
+ jobject rv= new_java_object(class_name, method_signature, args);
+ JNI_DBUG_RETURN("Java_context::new_java_object: arg: Java_object_parameter",
+ rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name, long long arg0)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object: arg: Java_object_parameter");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("long long =%l", arg0);
+ jvalue args[1];
+ args[0].j= arg0;
+
+ jobject rv= new_java_object(class_name, LONG_RETURN_VOID, args);
+ JNI_DBUG_RETURN("Java_context::new_java_object: arg: long long", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ Java_object_parameter *arg1,
+ const char *arg2)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object args: obj, obj, str");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0=<%s>",
+ (arg0 == NULL) ? "(null)" : arg0->java_parameter_class());
+ JNI_DBUG_PRINT("arg1=%s",
+ arg1==NULL ? "(null)" : arg1->java_parameter_class());
+ JNI_DBUG_PRINT("arg2=%s", arg2);
+
+ jobject ja0= (arg0 == NULL) ? NULL : arg0->as_java_object();
+ jobject ja1= arg1==NULL ? NULL : arg1->as_java_object();
+ jstring js2= to_jstring(arg2);
+
+ jvalue args[3];
+ args[0].l= ja0;
+ args[1].l= ja1;
+ args[2].l= js2;
+
+ const char *field0_class_name= arg0->java_parameter_class();
+ const char *field1_class_name= arg1->java_parameter_class();
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field0_class_name);
+ object_name_to_jni_type(method_signature, field1_class_name);
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ //fprintf(stderr, "method signature: %s\n", method_signature);
+
+ jobject rv= new_java_object(class_name, method_signature, args);
+ delete_global_reference(js2);
+ JNI_DBUG_RETURN("Java_context::new_java_object args: obj, obj, str", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ Java_object_parameter *arg1)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object args: obj, obj");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0=<%s>",
+ (arg0 == NULL) ? "(null)" : arg0->java_parameter_class());
+ JNI_DBUG_PRINT("arg1=%s",
+ arg1==NULL ? "(null)" : arg1->java_parameter_class());
+
+ jobject ja0= (arg0 == NULL) ? NULL : arg0->as_java_object();
+ jobject ja1= arg1==NULL ? NULL : arg1->as_java_object();
+
+ jvalue args[2];
+ args[0].l= ja0;
+ args[1].l= ja1;
+
+ const char *field0_class_name= arg0->java_parameter_class();
+ const char *field1_class_name= arg1->java_parameter_class();
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field0_class_name);
+ object_name_to_jni_type(method_signature, field1_class_name);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ //fprintf(stderr, "method signature: %s\n", method_signature);
+
+ jobject rv= new_java_object(class_name, method_signature, args);
+ JNI_DBUG_RETURN("Java_context::new_java_object args: obj, obj, str", rv);
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ long long arg1)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object args: obj, obj");
+ JNI_DBUG_PRINT("class_name=%s", class_name);
+ JNI_DBUG_PRINT("arg0=<%s>",
+ (arg0 == NULL) ? "(null)" : arg0->java_parameter_class());
+ JNI_DBUG_PRINT("arg1=%d", arg1);
+
+ jobject ja0= (arg0 == NULL) ? NULL : arg0->as_java_object();
+
+ jvalue args[2];
+ args[0].l= ja0;
+ args[1].j= arg1;
+
+ const char *field0_class_name= arg0->java_parameter_class();
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field0_class_name);
+ strcat(method_signature, JNI_LONG);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ //fprintf(stderr, "method signature: %s\n", method_signature);
+
+ jobject rv= new_java_object(class_name, method_signature, args);
+ JNI_DBUG_RETURN("Java_context::new_java_object args: obj, obj, str", rv);
+}
+
+
+jobject Java_context::new_java_long(long long arg0)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_long");
+ jvalue args[1];
+ args[0].j= arg0;
+
+ jobject rv= new_java_object("java/lang/Long", LONG_RETURN_VOID, args);
+ JNI_DBUG_RETURN("Java_context::new_java_long", rv);
+}
+
+
+void Java_context::call_void_method(jobject jobj, const char *method,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_void_method");
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+ call_void_method_a(jobj, method, STRING_RETURN_VOID, args);
+ delete_global_reference(args[0].l);
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method");
+}
+
+
+void Java_context::call_void_method(jobject jobj, const char *method)
+{
+ JNI_DBUG_ENTER("Java_context::call_void_method");
+ jvalue args[0];
+ call_void_method_a(jobj, method, EMPTY_RETURN_VOID, args);
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method");
+}
+
+
+int Java_context::call_int_method(jobject jobj, const char *method,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_int_method");
+ JNI_DBUG_PRINT("arg0: %s", arg0);
+
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+ int rv= call_int_method_a(jobj, method, STRING_RETURN_INT, args);
+ delete_global_reference(args[0].l);
+ JNI_DBUG_RETURN("Java_context::call_int_method", rv);
+}
+
+
+bool Java_context::call_boolean_method(jobject jobj, const char *method)
+{
+ JNI_DBUG_ENTER("Java_context::call_boolean_method");
+ jvalue args[0];
+ bool rv= (bool) call_boolean_method_a(jobj, method, EMPTY_RETURN_BOOL, args);
+ JNI_DBUG_RETURN("Java_context::call_boolean_method", rv);
+}
+
+
+int Java_context::call_int_method(jobject jobj, const char *method)
+{
+ JNI_DBUG_ENTER("Java_context::call_int_method");
+ jvalue args[0];
+ int rv= call_int_method_a(jobj, method, EMPTY_RETURN_INT, args);
+ JNI_DBUG_RETURN("Java_context::call_int_method", rv);
+}
+
+
+Jbyte_array *Java_context::call_byte_array_method(jobject jobj,
+ const char *method,
+ const char *arg)
+{
+ JNI_DBUG_ENTER("Java_context::call_byte_array_method");
+ jvalue args[1];
+ args[0].l= to_jstring(arg);
+
+ Jbyte_array *rv= call_byte_array_method_a(
+ jobj, method, STRING_RETURN_BYTE_ARRAY, args);
+ delete_global_reference(args[0].l);
+ JNI_DBUG_RETURN("Java_context::call_byte_array_method", rv);
+}
+
+
+Jbyte_array *Java_context::call_byte_array_method(jobject jobj,
+ const char *method,
+ int arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_byte_array_method");
+ jvalue args[1];
+ args[0].i= arg0;
+
+ Jbyte_array *rv= call_byte_array_method_a(
+ jobj, method, INT_RETURN_BYTE_ARRAY, args);
+ JNI_DBUG_RETURN("Java_context::call_byte_array_method", rv);
+}
+
+
+void Java_context::call_void_method_converting_string_to_bytes(jobject jobj,
+ const char *method, int arg0, const char *arg1)
+{
+ JNI_DBUG_ENTER("Java_context::call_void_method_converting_string_to_bytes");
+ jvalue args[2];
+ args[0].i= arg0;
+ args[1].l= to_java_byte_array(arg1);
+
+ call_void_method_a(jobj, method, INT_BYTE_ARRAY_RETURN_VOID, args);
+ delete_global_reference(args[1].l);
+ JNI_DBUG_VOID_RETURN(
+ "Java_context::call_void_method_converting_string_to_bytes");
+}
+
+
+void Java_context::call_void_method(jobject jobj, const char *method,
+ Java_object_parameter *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_void_method");
+ jvalue args[1];
+ args[0].l= arg0->as_java_object();
+
+ const char *field_class_name= arg0->java_parameter_class();
+
+ char method_signature[10 + strlen(field_class_name)];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ object_name_to_jni_type(method_signature, field_class_name);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ call_void_method_a(jobj, method, method_signature, args);
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method");
+}
+
+
+void Java_context::call_void_method(jobject jobj, const char *method,
+ bool arg0,
+ const char *arg1,
+ const char *arg2,
+ Java_object_parameter *arg3)
+{
+ JNI_DBUG_ENTER("Java_context::call_void_method");
+ jvalue args[4];
+ args[0].z= arg0;
+ args[1].l= to_jstring(arg1);
+ args[2].l= to_jstring(arg2);
+ args[3].l= arg3->as_java_object();
+
+ char method_signature[1024];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ strcat(method_signature, JNI_BOOL);
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, JNI_STRING);
+ object_name_to_jni_type(method_signature, arg3->java_parameter_class());
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ call_void_method_a(jobj, method, method_signature, args);
+ delete_global_reference(args[1].l);
+ delete_global_reference(args[2].l);
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method");
+}
+
+
+void Java_context::call_void_method(jobject jobj, const char *method,
+ char *argv[], int argc)
+ {
+ JNI_DBUG_ENTER("Java_context::call_void_method");
+ jvalue args[1];
+ jobjectArray jsa= to_string_array(argv, argc);
+ args[0].l= jsa;
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "([");
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, ")");
+ strcat(method_signature, JNI_VOID);
+
+ call_void_method_a(jobj, method, method_signature, args);
+
+ release_java_string_array(jsa, argc);
+}
+
+
+jobject Java_context::get_static_instance_field(const char *class_name,
+ const char *field_name)
+{
+ JNI_DBUG_ENTER("Java_context::get_static_instance_field");
+ jobject rv= get_static_object_field(class_name, field_name, class_name);
+ JNI_DBUG_RETURN("Java_context::get_static_instance_field", rv);
+}
+
+
+jobject Java_context::get_static_object_field(const char *class_name,
+ const char *field_name,
+ const char *field_class)
+{
+ JNI_DBUG_ENTER("Java_context::get_static_object_field");
+ char field_signature[strlen(field_class)+3];
+ field_signature[0]= '\0';
+ object_name_to_jni_type(field_signature, field_class);
+
+ jclass cls= get_java_class(class_name);
+ if (cls == NULL)
+ {
+ fprintf(stderr, "The 'jclass' is null for \"%s\"\n", class_name);
+ JNI_DBUG_RETURN("Java_context::get_static_object_field", NULL);
+ }
+
+ jfieldID fieldID= get_static_field_id(cls, class_name,
+ field_name, field_signature);
+ if (fieldID == NULL)
+ {
+ fprintf(stderr,
+ "The 'jfieldID' is NULL for class: %s field: %s type: %s\n",
+ class_name, field_name, field_class);
+ JNI_DBUG_RETURN("Java_context::get_static_object_field", NULL);
+ }
+
+ jobject lobj= env->GetStaticObjectField(cls, fieldID);
+ env->DeleteLocalRef(cls);
+ jobject rv= to_global_reference(lobj);
+ JNI_DBUG_RETURN("Java_context::get_static_object_field", rv);
+}
+
+
+jobject Java_context::call_object_method(jobject jobj, const char *method)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ jobject rv= call_object_method(jobj, method, "java/lang/Object");
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+jobject Java_context::call_object_method(jobject jobj,
+ const char *method,
+ const char *return_class_name)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "()");
+ object_name_to_jni_type(method_signature, return_class_name);
+
+ jvalue args[0];
+ jobject rv= call_object_method_a(jobj, method, method_signature, args);
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+jobject Java_context::call_object_method(jobject jobj,
+ const char *method,
+ const char *return_class_name,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ JNI_DBUG_PRINT("method=%s", method);
+ JNI_DBUG_PRINT("return_class_name=%s", return_class_name);
+ JNI_DBUG_PRINT("arg0=%s", arg0);
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(");
+ strcat(method_signature, JNI_STRING);
+ strcat(method_signature, ")");
+ object_name_to_jni_type(method_signature, return_class_name);
+
+ JNI_DBUG_PRINT("method_signature=%s", method_signature);
+
+ jobject rv= call_object_method_a(jobj, method, method_signature, args);
+
+ delete_global_reference(args[0].l);
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+jobject Java_context::call_object_method_obj(jobject jobj,
+ const char *method,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ JNI_DBUG_PRINT("method=%s", method);
+ JNI_DBUG_PRINT("return_class_name=%s", return_class_name);
+ JNI_DBUG_PRINT("arg0=%s", arg0);
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+
+ jobject rv= call_object_method_a(jobj, method, OBJECT_RETURN_OBJECT, args);
+
+ delete_global_reference(args[0].l);
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+bool Java_context::call_boolean_method_obj(jobject jobj,
+ const char *method,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ JNI_DBUG_PRINT("method=%s", method);
+ JNI_DBUG_PRINT("arg0=%s", arg0);
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+
+ bool rv= (bool) call_boolean_method_a(jobj, method, OBJECT_RETURN_BOOL, args);
+
+ delete_global_reference(args[0].l);
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+jobject Java_context::call_object_method(jobject jobj,
+ const char *method,
+ const char *return_class_name,
+ char arg0,
+ char arg1)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ jvalue args[2];
+ args[0].c= arg0;
+ args[1].c= arg1;
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, "(CC)");
+ object_name_to_jni_type(method_signature, return_class_name);
+
+ jobject rv= call_object_method_a(jobj, method, method_signature, args);
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+jobject Java_context::call_object_method_object_param(jobject jobj,
+ const char *method,
+ const char *arg0)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method");
+ jvalue args[1];
+ args[0].l= to_jstring(arg0);
+
+ char method_signature[256];
+ method_signature[0]= '\0';
+ strcat(method_signature, OBJECT_RETURN_OBJECT);
+
+ jobject rv= call_object_method_a(jobj, method, method_signature, args);
+ JNI_DBUG_RETURN("Java_context::call_object_method", rv);
+}
+
+
+void Java_context::to_string(jobject jobj, char *buf, int buf_size)
+{
+ JNI_DBUG_ENTER("Java_context::to_string");
+ call_string_method(jobj, "toString", buf, buf_size);
+ JNI_DBUG_VOID_RETURN("Java_context::to_string");
+}
+
+
+void Java_context::call_string_method(jobject jobj, char *method_name,
+ char *buf, int buf_size)
+{
+ JNI_DBUG_ENTER("Java_context::call_string_method");
+ if (jobj == NULL)
+ {
+ fprintf(stderr, "'jobject' is NULL\n");
+ JNI_DBUG_VOID_RETURN("Java_context::call_string_method");
+ }
+ jclass cls= env->GetObjectClass(jobj);
+
+ jmethodID methodId= get_method_id(cls, method_name, EMPTY_RETURN_STRING);
+ env->DeleteLocalRef(cls);
+ jvalue args[0];
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "'jmethodID' is NULL for \"%s\"\n", method_name);
+ JNI_DBUG_VOID_RETURN("Java_context::call_string_method");
+ }
+ jstring jstr= (jstring) env->CallObjectMethodA(jobj, methodId, args);
+ const char *str= env->GetStringUTFChars(jstr, 0);
+ buf[0]= '\0';
+ strncat(buf, str, buf_size-1);
+ env->ReleaseStringUTFChars(jstr, str);
+ JNI_DBUG_VOID_RETURN("Java_context::call_string_method");
+}
+
+
+void Java_context::get_class_name(jobject obj, char *buf, int buf_length)
+{
+ JNI_DBUG_ENTER("Java_context::get_class_name");
+ if (obj == NULL)
+ {
+ buf[0]= '\0';
+ strncat(buf, "(null)", buf_length);
+ return;
+ }
+ jobject jobjclass= call_object_method(obj, "getClass", "java/lang/Class");
+ jobject class_name= call_object_method(jobjclass, "getName",
+ "java/lang/String");
+ jobject class_name_slash= call_object_method(class_name, "replace",
+ "java/lang/String", '.', '/');
+
+ to_string(class_name_slash, buf, buf_length);
+ JNI_DBUG_VOID_RETURN("Java_context::get_class_name");
+}
+
+
+void Java_context::delete_global_reference(jobject jobj)
+{
+ env->DeleteGlobalRef(jobj);
+}
+
+
+// private methods:
+
+void Java_context::object_name_to_jni_type(char *buf, const char *class_name)
+{
+ JNI_DBUG_ENTER(
+ "Java_context::object_name_to_jni_type class_name, signature, jargs");
+ strcat(buf, "L");
+ strcat(buf, class_name);
+ strcat(buf, ";");
+ // fprintf("in angle brackets: <%s>", buf);
+ JNI_DBUG_VOID_RETURN("Java_context::object_name_to_jni_type");
+}
+
+
+jobject Java_context::new_java_object(const char *class_name,
+ const char *signature,
+ jvalue *args)
+{
+ JNI_DBUG_ENTER("Java_context::new_java_object class_name, signature, jargs");
+ JNI_DBUG_PRINT("getting jclass <%s> ...", class_name);
+ jclass cls= get_java_class(class_name);
+ if (cls == NULL) goto err;
+ JNI_DBUG_PRINT("getting jmethodID <init> with signature: %s ...", signature);
+ jmethodID methodId= get_method_id(cls, "<init>", signature);
+
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "jmethodID is NULL for constructor\n");
+ env->DeleteLocalRef(cls);
+ JNI_DBUG_RETURN("Java_context::new_java_object", NULL);
+ }
+
+ JNI_DBUG_PRINT("creating new object ...%s", "");
+
+ jobject lobj= env->NewObjectA(cls, methodId, args);
+ env->DeleteLocalRef(cls);
+ JNI_DBUG_PRINT("new object: %p", lobj);
+ if (lobj == NULL)
+ {
+ fprintf(stderr, "NULL returned. No object created.\n");
+ fprintf(stderr, "jclass <%s> ...\n", class_name);
+ fprintf(stderr, "jmethodID <init> with signature: %s ...\n", signature);
+ if_java_exception_occurred_describe();
+err:
+ JNI_DBUG_RETURN(
+ "ERROR: Java_context::new_java_object class_name, signature, jargs",
+ NULL);
+ }
+ jobject jobj= to_global_reference(lobj);
+ JNI_DBUG_RETURN("Java_context::new_java_object class_name, signature, jargs",
+ jobj);
+}
+
+
+jint Java_context::call_int_method_a(jobject jobj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args)
+{
+ JNI_DBUG_ENTER("Java_context::call_int_method_a");
+ //fprintf(stderr, "jobject jobj: %p", obj));
+ JNI_DBUG_PRINT("method name: %s", method_name);
+ JNI_DBUG_PRINT("method signature: %s", signature);
+
+ // JNI_DBUG_PRINT("methodName: %s", methodName);
+ // JNI_DBUG_PRINT("signature: %s", signature);
+ if (jobj == NULL)
+ {
+ fprintf(stderr, "jobject is NULL\n");
+ JNI_DBUG_RETURN("Java_context::call_int_method_a", 0);
+ }
+
+ jclass cls= env->GetObjectClass(jobj);
+
+ jmethodID methodId= get_method_id(cls, method_name, signature);
+ env->DeleteLocalRef(cls);
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "jmethodID is NULL for \"%s\"\n", method_name);
+ JNI_DBUG_RETURN("Java_context::call_int_method_a", 0);
+ }
+ jint rv= env->CallIntMethodA(jobj, methodId, args);
+ JNI_DBUG_RETURN("Java_context::call_int_method_a", rv);
+}
+
+
+jobject Java_context::call_object_method_a(jobject jobj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args)
+{
+ JNI_DBUG_ENTER("Java_context::call_object_method_a");
+ JNI_DBUG_PRINT("jobject obj: %p", jobj);
+ JNI_DBUG_PRINT("method name: %s", method_name);
+ JNI_DBUG_PRINT("method signature: %s", signature);
+
+ JNI_DBUG_PRINT("methodName: %s", method_name);
+ JNI_DBUG_PRINT("signature: %s", signature);
+ if (jobj == NULL)
+ {
+ fprintf(stderr, "jobject is NULL\n");
+ JNI_DBUG_RETURN("Java_context::call_object_method_a", NULL);
+ }
+
+ jclass cls= env->GetObjectClass(jobj);
+
+ jmethodID methodId= get_method_id(cls, method_name, signature);
+ env->DeleteLocalRef(cls);
+
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "jmethodID is NULL for \"%s\"\n", method_name);
+ JNI_DBUG_RETURN("Java_context::call_object_method_a", NULL);
+ }
+
+ jobject lobj= env->CallObjectMethodA(jobj, methodId, args);
+ jobject rv= to_global_reference(lobj);
+ JNI_DBUG_RETURN("Java_context::call_object_method_a", rv);
+}
+
+
+jboolean Java_context::call_boolean_method_a(jobject jobj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args)
+{
+ JNI_DBUG_ENTER("Java_context::call_boolean_method_a");
+ if (jobj == NULL)
+ {
+ fprintf(stderr, "jobject is NULL\n");
+ JNI_DBUG_RETURN("Java_context::call_boolean_method_a", false);
+ }
+
+ jclass cls= env->GetObjectClass(jobj);
+
+ jmethodID methodId= get_method_id(cls, method_name, signature);
+
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "jmethodID is NULL for \"%s\"\n", method_name);
+ JNI_DBUG_RETURN("Java_context::call_boolean_method_a", false);
+ }
+
+ env->DeleteLocalRef(cls);
+ jboolean rv= env->CallBooleanMethodA(jobj, methodId, args);
+ JNI_DBUG_RETURN("Java_context::call_boolean_method_a", rv);
+}
+
+
+void Java_context::call_void_method_a(jobject jobj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args)
+{
+ JNI_DBUG_ENTER("Java_context::call_void_method_a");
+ if (jobj == NULL)
+ {
+ fprintf(stderr, "jobject is NULL\n");
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method_a");
+ }
+
+ jclass cls= env->GetObjectClass(jobj);
+ jmethodID methodId= get_method_id(cls, method_name, signature);
+ env->DeleteLocalRef(cls);
+
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "jmethodID is NULL for \"%s\"\n", method_name);
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method_a");
+ }
+
+ env->CallVoidMethodA(jobj, methodId, args);
+ JNI_DBUG_VOID_RETURN("Java_context::call_void_method_a");
+}
+
+
+
+Jbyte_array *Java_context::call_byte_array_method_a(jobject jobj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args)
+{
+ JNI_DBUG_ENTER("Java_context::call_byte_array_method_a");
+ if (jobj == NULL)
+ {
+ fprintf(stderr, "jobject is NULL\n");
+ JNI_DBUG_RETURN("Java_context::call_byte_array_method_a", NULL);
+ }
+ jclass cls= env->GetObjectClass(jobj);
+ jmethodID methodId= get_method_id(cls, method_name, signature);
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "jmethodID is NULL for \"%s\"\n", method_name);
+ JNI_DBUG_RETURN("Java_context::call_byte_array_method_a", NULL);
+ }
+ jbyteArray jbarr= (jbyteArray) env->CallObjectMethodA(jobj, methodId, args);
+ Jbyte_array *rv= new Jbyte_array(get_array_length(jbarr),
+ get_byte_array_elements(jbarr));
+ env->DeleteLocalRef(cls);
+ env->DeleteLocalRef(jbarr);
+ JNI_DBUG_RETURN("Java_context::call_byte_array_method_a", rv);
+}
+
+
+jsize Java_context::get_array_length(jarray jarr)
+{
+ JNI_DBUG_ENTER("Java_context::get_array_length");
+ if (jarr == NULL)
+ {
+ JNI_DBUG_RETURN("Java_context::get_array_length", -1);
+ }
+
+ jsize rv= env->GetArrayLength(jarr);
+ JNI_DBUG_RETURN("Java_context::get_array_length", rv);
+}
+
+
+jbyte *Java_context::get_byte_array_elements(jbyteArray jbarr)
+{
+ JNI_DBUG_ENTER("Java_context::get_byte_array_elements");
+ if (jbarr == NULL)
+ {
+ JNI_DBUG_RETURN("Java_context::get_byte_array_elements", NULL);
+ }
+
+ jboolean isCopy;
+ jbyte *rv= env->GetByteArrayElements(jbarr, &isCopy);
+ JNI_DBUG_RETURN("Java_context::get_byte_array_elements", rv);
+}
+
+
+void Java_context::if_java_exception_occurred_describe()
+{
+ JNI_DBUG_ENTER("Java_context::if_java_exception_occurred_describe");
+ if (env->ExceptionOccurred())
+ env->ExceptionDescribe();
+ JNI_DBUG_VOID_RETURN("Java_context::if_java_exception_occurred_describe");
+}
+
+
+jclass Java_context::get_java_class(const char *class_name)
+{
+ JNI_DBUG_ENTER("Java_context::get_java_class");
+ jclass cls= env->FindClass(class_name);
+ if (cls == NULL)
+ {
+ fprintf(stderr, "Can't find class: %s", class_name);
+ jclass jsys= env->FindClass("System");
+ if (jsys == NULL) goto end;
+ const char *sig= STRING_RETURN_STRING;
+ jmethodID methodId= env->GetStaticMethodID(jsys, "getProperty", sig);
+ jvalue args[1];
+ args[0].l= to_jstring("java.class.path");
+ jobject jstr= env->CallStaticObjectMethodA(jsys, methodId, args);
+ env->DeleteLocalRef(jsys);
+ delete_global_reference(args[0].l);
+ char buf[2048];
+ to_string(jstr, buf, 2048);
+ env->DeleteLocalRef(jstr);
+ fprintf(stderr, "Syste.getProperty(\"java.class.path\")=%s", buf);
+ // throw(1);
+ }
+end:
+ JNI_DBUG_PRINT("jclass= %p", cls);
+ JNI_DBUG_RETURN("Java_context::get_java_class", cls);
+}
+
+
+void Java_context::find_class_name(jclass cls, char *buf, int buf_size)
+{
+ JNI_DBUG_ENTER("Java_context::find_class_name");
+ buf[0]= '\0';
+ JNI_DBUG_PRINT("jclass= %p", cls);
+ jmethodID getName= env->GetMethodID(cls, "toString", EMPTY_RETURN_STRING);
+ JNI_DBUG_PRINT("getName= %p", getName);
+ jstring name= (jstring)env->CallObjectMethod(cls, getName);
+ JNI_DBUG_PRINT("name= %p", name);
+ const char *str= env->GetStringUTFChars(name, 0);
+ buf[0]= '\0';
+ strncat(buf, str, buf_size-1);
+ JNI_DBUG_VOID_RETURN("Java_context::find_class_name");
+}
+
+
+jmethodID Java_context::get_method_id(jclass cls,
+ const char *method_name,
+ const char *signature)
+{
+ JNI_DBUG_ENTER("Java_context::get_method_id");
+ jmethodID methodId= env->GetMethodID(cls, method_name, signature);
+
+ if (methodId == NULL)
+ {
+ fprintf(stderr, "Can't find method: %s\n", method_name);
+ fprintf(stderr, " with signature: %s\n", signature);
+ fprintf(stderr, " of class: %p\n", cls);
+ int buf_size= 1024;
+ char class_name[buf_size];
+ find_class_name(cls, class_name, buf_size);
+ fprintf(stderr, " of class named: %s\n", class_name);
+ // throw(1);
+ }
+ JNI_DBUG_RETURN("Java_context::get_method_id", methodId);
+}
+
+
+int Java_context::position_of_null(const char *str)
+{
+ JNI_DBUG_ENTER("Java_context::position_of_null");
+ int i= 0;
+ while (str[i] != '\0')
+ i++;
+
+ if (i > 512 || i < 0)
+ {
+ fprintf(stderr, "this is an odd string:%s", str);
+ }
+ JNI_DBUG_RETURN("Java_context::position_of_null", i);
+}
+
+
+jfieldID Java_context::get_static_field_id(jclass cls,
+ const char *class_name,
+ const char *field_name,
+ const char *sig)
+{
+ JNI_DBUG_ENTER("Java_context::get_static_field_id");
+ jfieldID jfID= env->GetStaticFieldID(cls, field_name, sig);
+ if (jfID == NULL)
+ {
+ fprintf(stderr, "Can't find static field: %s\n", field_name);
+ fprintf(stderr, " of class: %s\n", class_name);
+ fprintf(stderr, " with signature: %s\n", sig);
+ // throw(1);
+ }
+
+ JNI_DBUG_RETURN("Java_context::get_static_field_id", jfID);
+}
+
+
+jobject Java_context::to_global_reference(jobject lref)
+{
+ JNI_DBUG_ENTER("Java_context::to_global_reference");
+ jobject gref= env->NewGlobalRef(lref);
+ env->DeleteLocalRef(lref);
+ JNI_DBUG_RETURN("Java_context::to_global_reference", gref);
+}
+
+
+jobjectArray Java_context::to_string_array(char *argv[], int argc)
+{
+ JNI_DBUG_ENTER("Java_context::to_string_array");
+ jobjectArray jsa;
+ jclass strcls= env->FindClass("java/lang/String");
+ jsa= env->NewObjectArray(argc, strcls, NULL);
+ for(int i= 0; i< argc; i++)
+ {
+ jstring js1= to_jstring(argv[i]);
+ env->SetObjectArrayElement(jsa, i, js1);
+ }
+ JNI_DBUG_RETURN("Java_context::to_string_array", jsa);
+}
+
+
+void Java_context::release_java_string_array(jobjectArray jsa, int argc)
+{
+ JNI_DBUG_ENTER("Java_context::release_java_string_array");
+ for(int i= 0; i< argc; i++)
+ {
+ delete_global_reference(env->GetObjectArrayElement(jsa, i));
+ }
+ env->DeleteLocalRef(jsa);
+ JNI_DBUG_VOID_RETURN("Java_context::release_java_string_array");
+}
+
+bool Java_context::register_natives(jclass cls, const JNINativeMethod *methods, int count)
+{
+ JNI_DBUG_ENTER("Java_context::register_natives");
+ bool fail= false;
+ if (env->RegisterNatives(cls, methods, count))
+ fail= true;
+ JNI_DBUG_RETURN("Java_context::register_natives", fail);
+}
+/* END java_context.cc */
diff -Nrup a/plugin/java_udf/java_context.h b/plugin/java_udf/java_context.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_context.h 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,170 @@
+#ifndef _JAVA_CONTEXT_H_
+#define _JAVA_CONTEXT_H_
+
+#include <jni.h>
+#include "jbyte_array.h"
+#include "java_object_parameter.h"
+
+class Java_context
+{
+
+public:
+ Java_context(JNIEnv *jenv);
+ ~Java_context();
+
+ int get_version();
+
+ jobject new_java_object(const char *class_name);
+ jobject new_java_object(const char *class_name, const char *arg0);
+ jobject new_java_object(const char *class_name, Java_object_parameter *arg0);
+ jobject new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ const char *arg1,
+ const char *arg2);
+ jobject new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ Java_object_parameter *arg1,
+ const char *arg2);
+ jobject new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ char *argv1[],
+ int argc1,
+ const char *arg2);
+ jobject new_java_object(const char *class_name,
+ const char *arg0,
+ const char *arg1,
+ const char *arg2,
+ const char *arg3);
+ jobject new_java_object(const char *class_name, long long arg0);
+ jobject new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ long long arg1);
+ jobject new_java_object(const char *class_name,
+ Java_object_parameter *arg0,
+ Java_object_parameter *arg1);
+
+ jobject new_java_long(long long arg0);
+
+
+ void call_void_method(jobject jobj, const char *method);
+ void call_void_method(jobject jobj, const char *method, const char *arg0);
+ void call_void_method(jobject jobj, const char *method,
+ Java_object_parameter *arg0);
+ void call_void_method(jobject jobj, const char *method,
+ bool arg0,
+ const char *arg1,
+ const char *arg2,
+ Java_object_parameter *arg3);
+ void call_void_method(jobject jobj, const char *method,
+ char *argv[], int argc);
+
+ jobject call_object_method(jobject jobj, const char *method);
+ jobject call_object_method(jobject jobj,
+ const char *method,
+ const char *return_class_name);
+ jobject call_object_method(jobject jobj,
+ const char *method,
+ const char *return_class_name,
+ const char *arg0);
+ jobject call_object_method(jobject jobj,
+ const char *method,
+ const char *return_class_name,
+ char arg0,
+ char arg1);
+ jobject call_object_method_object_param(jobject jobj,
+ const char *method,
+ const char *arg0);
+
+ jobject call_object_method_obj(jobject jobj,
+ const char *method,
+ const char *arg0);
+
+ int call_int_method(jobject jobj, const char *method);
+ int call_int_method(jobject jobj, const char *method, const char *arg0);
+
+ bool call_boolean_method(jobject jobj, const char *method);
+ bool call_boolean_method_obj(jobject jobj,
+ const char *method,
+ const char *arg0);
+
+
+ Jbyte_array *call_byte_array_method(jobject jobj,
+ const char *method,
+ const char *arg0);
+ Jbyte_array *call_byte_array_method(jobject jobj,
+ const char *method,
+ int arg0);
+
+ void call_void_method_converting_string_to_bytes(jobject jobj,
+ const char *method,
+ int arg0,
+ const char *arg1);
+
+ void if_java_exception_occurred_describe();
+
+
+ jobject get_static_instance_field(const char *class_name,
+ const char *field_name);
+
+ jobject get_static_object_field(const char *class_name,
+ const char *field_name,
+ const char *field_class_name);
+
+ void call_string_method(jobject jobj,
+ char *method_name,
+ char *buf,
+ int buf_size);
+
+ void to_string(jobject jobj, char *buf, int buf_size);
+ void get_class_name(jobject jobj, char *buf, int buf_size);
+ void delete_global_reference(jobject jobj);
+
+
+ jclass get_java_class(const char *class_name);
+ bool register_natives(jclass cls, const JNINativeMethod *methods, int count);
+private:
+ JNIEnv *env;
+ void find_class_name(jclass cls, char *buf, int buf_size);
+ jmethodID get_method_id(jclass cls,
+ const char *method_name,
+ const char *signature);
+ jobject new_java_object(const char *class_name,
+ const char *signature,
+ jvalue *args);
+ void call_void_method_a(jobject obj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args);
+ jint call_int_method_a(jobject obj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args);
+ jobject call_object_method_a(jobject obj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args);
+ jboolean call_boolean_method_a(jobject obj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args);
+ Jbyte_array *call_byte_array_method_a(jobject obj,
+ const char *method_name,
+ const char *signature,
+ jvalue *args);
+
+ jstring to_jstring(const char *str);
+ jbyteArray to_java_byte_array(const char *str);
+ jsize get_array_length(jarray jarr);
+ jbyte *get_byte_array_elements(jbyteArray jbarr);
+ void object_name_to_jni_type(char *buf, const char *class_name);
+ int position_of_null(const char *str);
+ jfieldID get_static_field_id(jclass cls,
+ const char *class_name,
+ const char *field_name,
+ const char *field_signature);
+ jobject to_global_reference(jobject lref);
+ jobjectArray to_string_array(char *argv[], int argc);
+ void release_java_string_array(jobjectArray jsa, int argc);
+};
+
+#endif //_JAVA_CONTEXT_H_
diff -Nrup a/plugin/java_udf/java_context_test.cc b/plugin/java_udf/java_context_test.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_context_test.cc 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,588 @@
+#include "java_context.h"
+#include "test_utils.h"
+#include "jvm_singleton.h"
+#include "jvm_interface.h"
+#include "jobject_wrapper.h"
+#include <jni.h>
+#include <stdio.h>
+#include <string.h>
+
+const char *TEST_OBJECT_CLASS_NAME= "com/mysql/jnitest/TestObject";
+
+class Test_object : public Java_object_parameter
+{
+public:
+ Test_object(Java_context *java, const char *arg0) : Java_object_parameter()
+ {
+ _java= java;
+ _jobj= _java->new_java_object(TEST_OBJECT_CLASS_NAME, arg0);
+ }
+
+ ~Test_object()
+ {
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+ java->delete_global_reference(_jobj);
+ jvm->detach();
+ }
+ const char *java_parameter_class()
+ {
+ return TEST_OBJECT_CLASS_NAME;
+ }
+ jobject as_java_object()
+ {
+ return _jobj;
+ }
+
+private:
+ Java_context *_java;
+ jobject _jobj;
+};
+
+void test_new_java_object()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+ jvm->detach();
+}
+
+void test_new_java_object_string_arg()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ char *arg0= "foo";
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME, arg0);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, arg0, "test_new_java_object_string_arg to_string");
+ jvm->detach();
+}
+
+void test_new_java_object_testobject_str_str()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ Test_object *arg0= new Test_object(java, "foo");
+ char *arg1= "bar";
+ char *arg2= "baz";
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME,
+ arg0, arg1, arg2);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ char *expected= "[foo] bar baz";
+ assert_string_equals(buf, expected, "to_string");
+ jvm->detach();
+}
+
+void test_new_java_object_testobject_arg()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ Test_object *arg0= new Test_object(java, "foo");
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME, arg0);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "foo", "to_string");
+
+ jvm->detach();
+}
+
+void test_new_java_object_testobject_strarray_str()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ Test_object *arg0= new Test_object(java, "foo");
+ char argbuf[1024];
+ memset(argbuf, 0, 1024);
+ strncat(argbuf, "bar", 1024);
+
+ int argc1= 2;
+ char *argv1[argc1];
+ argv1[0]= "bar";
+ argv1[1]= "biz";
+
+ char *arg2= "baz";
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME,
+ arg0, argv1, argc1, arg2);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ char *expected= "[foo] [bar, biz] baz";
+ assert_string_equals(buf, expected, "to_string");
+
+ jvm->detach();
+}
+
+void test_new_java_object_4strs()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ char *arg0= "foo";
+ char *arg1= "bar";
+ char *arg2= "baz";
+ char *arg3= "wiz";
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME, arg0, arg1, arg2, arg3);
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ char *expected= "foo bar baz wiz";
+
+ assert_string_equals(buf, expected, "to_string");
+
+ jvm->detach();
+}
+
+void test_new_java_object_long()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ long long arg0= 7;
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME, arg0);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "7", "to_string");
+ jvm->detach();
+}
+
+
+void test_new_java_long()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ long long arg0= 7;
+
+ jobject jobj1= java->new_java_long(arg0);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "7", "to_string");
+
+ java->get_class_name(jobj1, buf, 100);
+ assert_string_equals(buf, "java/lang/Long", "class name");
+
+ Jobject_wrapper wrapped(java, jobj1);
+ assert_string_equals(wrapped.java_parameter_class(), "java/lang/Long",
+ "wrapped class name");
+
+ jvm->detach();
+}
+
+void test_new_java_long_with_int()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ int arg0= 7;
+
+ jobject jobj1= java->new_java_long(arg0);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "7", "to_string");
+
+ java->get_class_name(jobj1, buf, 100);
+ assert_string_equals(buf, "java/lang/Long", "class name");
+
+ Jobject_wrapper wrapped(java, jobj1);
+ assert_string_equals(wrapped.java_parameter_class(), "java/lang/Long",
+ "wrapped class name");
+
+ jvm->detach();
+}
+
+
+void test_call_void_method()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ const char *method= "resetData";
+ java->call_void_method(jobj1, method);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ char *expected= "reset";
+
+ assert_string_equals(buf, expected, "to_string");
+
+ jvm->detach();
+}
+
+
+void test_call_void_method_str_arg()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ java->call_void_method(jobj1, "setData", "foo");
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "foo", "to_string");
+
+ jvm->detach();
+}
+
+void test_call_void_method_arg_obj()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ Test_object arg0(java, "foo");
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ java->call_void_method(jobj1, "setData", &arg0);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "[foo]", "to_string");
+
+ jvm->detach();
+}
+
+void test_call_void_method_4args()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ bool arg0= true;
+ char *arg1= "foo";
+ char *arg2= "bar";
+ Test_object arg3(java, "baz");
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ java->call_void_method(jobj1, "setData", arg0, arg1, arg2, &arg3);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "true foo bar [baz]", "to_string");
+
+ jvm->detach();
+}
+
+void test_call_void_method_strarray()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ int argc= 2;
+ char *argv[argc];
+ argv[0]= "bar";
+ argv[1]= "biz";
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ assert_not_NULL(jobj1, TEST_OBJECT_CLASS_NAME);
+
+ java->call_void_method(jobj1, "setData", argv, argc);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "[bar, biz]", "to_string");
+
+ jvm->detach();
+}
+
+void test_call_int_method()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ int i= java->call_int_method(jobj1, "dataLength");
+
+ assert_ints_equal(i, 7, "dataLength of 'No Args'");
+
+ jvm->detach();
+}
+
+
+void test_call_int_method_str()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ int i= java->call_int_method(jobj1, "dataLength", "foo");
+
+ assert_ints_equal(i, 3, "dataLength of foo");
+
+ jvm->detach();
+}
+
+void test_call_boolean_method()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ Test_object foo(java, "even letters");
+
+ bool b= java->call_boolean_method(foo.as_java_object(), "even");
+
+ assert_true(b, "even");
+
+ jvm->detach();
+}
+
+void test_call_byte_array_method_str()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ char *method= "toBytes";
+ char *arg0= "foo";
+ Jbyte_array *jba= java->call_byte_array_method(jobj1, method, arg0);
+
+ assert_false(jba->is_null(), "is_null()");
+ assert_ints_equal(jba->length(), 3, "length");
+
+ assert_ints_equal(jba->get(0), 'f', "jba->get(0)");
+ assert_ints_equal(jba->get(1), 'o', "jba->get(1)");
+ assert_ints_equal(jba->get(2), 'o', "jba->get(2)");
+
+ delete jba;
+ jvm->detach();
+}
+
+void test_call_byte_array_method_int()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ char *method= "toBytes";
+ int arg0= 567;
+ Jbyte_array *jba= java->call_byte_array_method(jobj1, method, arg0);
+
+ assert_false(jba->is_null(), "is_null()");
+ assert_ints_equal(jba->length(), 3, "length");
+
+ assert_ints_equal(jba->get(0), '5', "jba->get(0)");
+ assert_ints_equal(jba->get(1), '6', "jba->get(1)");
+ assert_ints_equal(jba->get(2), '7', "jba->get(2)");
+
+ delete jba;
+ jvm->detach();
+}
+
+void test_call_void_method_converting_string_to_bytes()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME);
+
+ char *method= "setData";
+ int arg0= 7;
+ char *arg1= "foo";
+ java->call_void_method_converting_string_to_bytes(jobj1, method, arg0, arg1);
+
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ assert_string_equals(buf, "7foo", "to_string");
+
+ jvm->detach();
+}
+
+void test_get_static_instance_field()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ char *TEST_OBJECT_CLASS_NAME= "java/lang/Boolean";
+ char *field_name= "TRUE";
+ jobject jobj1= java->get_static_instance_field(TEST_OBJECT_CLASS_NAME, field_name);
+
+ assert_not_NULL(jobj1, "Boolean.TRUE");
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ char *expected= "true";
+ assert_string_equals(buf, expected, "to_string");
+
+ jvm->detach();
+}
+
+void test_get_static_object_field()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ char *TEST_OBJECT_CLASS_NAME= "java/lang/Boolean";
+ char *field_name= "FALSE";
+ char *field_class_name= TEST_OBJECT_CLASS_NAME;
+ jobject jobj1= java->get_static_object_field(TEST_OBJECT_CLASS_NAME, field_name, field_class_name);
+
+ assert_not_NULL(jobj1, "Boolean.TRUE");
+ char buf[100];
+ java->to_string(jobj1, buf, 100);
+ char *expected= "false";
+ assert_string_equals(buf, expected, "to_string");
+
+ jvm->detach();
+}
+
+void test_call_object_method()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ jobject jobj1= java->new_java_object(TEST_OBJECT_CLASS_NAME, "foobar");
+
+ char *method= "getData";
+ jobject jobj2= java->call_object_method(jobj1, method);
+
+ assert_not_NULL(jobj2, "return object");
+ char buf[100];
+ java->to_string(jobj2, buf, 100);
+ assert_string_equals(buf, "foobar", "to_string");
+
+ jvm->detach();
+}
+
+void test_call_object_method_str()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+
+ jobject jobj1= java->new_java_object("java/lang/String", "test");
+
+ char *method= "concat";
+ char *return_type= "java/lang/String";
+ jobject jobj2= java->call_object_method(jobj1, method, return_type, "me");
+
+ assert_not_NULL(jobj2, "return object");
+ char buf[100];
+ java->to_string(jobj2, buf, 100);
+ assert_string_equals(buf, "testme", "to_string");
+
+ jvm->detach();
+}
+
+void test_if_java_exception_occurred_describe()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java= jvm->attach();
+ java->if_java_exception_occurred_describe();
+ jvm->detach();
+}
+
+int main(int argc, char *argv[])
+{
+ printf("running %s ", argv[0]);
+ if (argc > 1)
+ Jvm_singleton::set_default_jvm_options(argv[1]);
+
+ test_new_java_object();
+ test_new_java_object_string_arg();
+ test_new_java_object_testobject_arg();
+ test_new_java_object_testobject_str_str();
+ test_new_java_object_4strs();
+ test_new_java_object_testobject_strarray_str();
+ test_new_java_object_long();
+
+ test_new_java_long();
+ test_new_java_long_with_int();
+
+ test_call_void_method();
+ test_call_void_method_str_arg();
+ test_call_void_method_arg_obj();
+ test_call_void_method_4args();
+ test_call_void_method_strarray();
+
+ test_call_int_method();
+ test_call_int_method_str();
+
+ test_call_boolean_method();
+
+ test_call_byte_array_method_str();
+ test_call_byte_array_method_int();
+
+ test_call_void_method_converting_string_to_bytes();
+
+ test_get_static_instance_field();
+
+ test_get_static_object_field();
+
+ test_call_object_method();
+ test_call_object_method_str();
+
+ test_if_java_exception_occurred_describe();
+
+ printf(" Success\n");
+}
diff -Nrup a/plugin/java_udf/java_object_parameter.cc b/plugin/java_udf/java_object_parameter.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_object_parameter.cc 2008-02-22 17:05:14 -08:00
@@ -0,0 +1,10 @@
+#include "java_object_parameter.h"
+
+// Java_object_parameter interface implementation
+Java_object_parameter::Java_object_parameter()
+{
+}
+
+Java_object_parameter::~Java_object_parameter()
+{
+}
diff -Nrup a/plugin/java_udf/java_object_parameter.h b/plugin/java_udf/java_object_parameter.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_object_parameter.h 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,16 @@
+#ifndef _JAVA_OBJECT_PARAMETER_
+#define _JAVA_OBJECT_PARAMETER_
+
+#include <jni.h>
+
+class Java_object_parameter
+{
+public:
+ Java_object_parameter();
+ virtual ~Java_object_parameter();
+
+ virtual const char *java_parameter_class()= 0;
+ virtual jobject as_java_object()= 0;
+};
+
+#endif /* _JAVA_OBJECT_PARAMETER_ */
diff -Nrup a/plugin/java_udf/java_udf.cc b/plugin/java_udf/java_udf.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_udf.cc 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,303 @@
+/* Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include <my_global.h>
+#include <stdlib.h>
+#include <m_ctype.h>
+#include <m_string.h>
+#include <my_sys.h>
+#include <mysql.h>
+#include <mysql/plugin.h>
+#include "java_context.h"
+#include "jvm_singleton.h"
+#include "jvm_interface.h"
+#include "jobject_wrapper.h"
+#include "jnicallback.h"
+#include "jnilinkage.h"
+#include "jniutils.h"
+
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#define __attribute__(A)
+#endif
+
+struct psm_java_context /* one context per thread */
+{
+ int nesting_level;
+ int ref_count;
+ MYSQL_THD thd;
+ Jvm *jvm;
+ Java_context *java_context;
+};
+
+struct st_mysql_psmroutine /* each function handle per thread*/
+{
+ psm_java_context *context;
+ jobject jo_function_descriptor; /* java FunctionDescriptor */
+ jobject invoker; /* java Invoker */
+};
+
+
+static MYSQL_THDVAR_OPAQUE(context, struct psm_java_context);
+
+static jobject udf_module;
+
+static char *jvm_options_file;
+
+static int jni_version;
+
+
+/*
+ Initialize the plugin at server start or plugin installation.
+
+ SYNOPSIS
+ java_udf_plugin_init()
+
+ DESCRIPTION
+ Does nothing.
+
+ RETURN VALUE
+ 0 success
+ 1 failure (could not instantiate JVM)
+ 2 failure (could not instantiate java UDFModule class)
+*/
+
+static int java_udf_plugin_init(void *arg __attribute__((unused)))
+{
+ Jvm *jvm= Jvm_singleton::check();
+ if (!jvm)
+ {
+ char options_filename[FN_REFLEN+1];
+ fn_format(options_filename, jvm_options_file, mysql_data_home, "",
+ MYF(MY_UNPACK_FILENAME));
+ Jvm_singleton::set_default_jvm_options(options_filename);
+ jvm= Jvm_singleton::get();
+ }
+ if (!jvm)
+ return 1;
+ Java_context *java_context= jvm->attach();
+
+ jni_version= java_context->get_version();
+
+ udf_module= java_context->new_java_object("com/mysql/udf/UDFModule");
+ if (!udf_module) goto err;
+
+ jclass jc_udf_callback= java_context->get_java_class(
+ "com/mysql/udf/NativeUDFCallback");
+ if (!jc_udf_callback) goto err;
+
+ if (java_context->register_natives(jc_udf_callback, native_methods,
+ native_methods_count)) goto err;
+
+ delete java_context;
+
+ return 0;
+err:
+ Jvm_singleton::set(NULL);
+ delete jvm;
+ return 2;
+}
+
+
+/*
+ Terminate the plugin at server shutdown or plugin deinstallation.
+
+ SYNOPSIS
+ java_udf_plugin_deinit()
+ Does nothing.
+
+ RETURN VALUE
+ 0 success
+ 1 failure (cannot happen)
+
+*/
+
+static int java_udf_plugin_deinit(void *arg __attribute__((unused)))
+{
+ Jvm *jvm= Jvm_singleton::check();
+ if (!jvm)
+ return 1;
+ Java_context *java_context= jvm->attach();
+ java_context->delete_global_reference(udf_module);
+ delete java_context;
+ delete jvm;
+ Jvm_singleton::set(NULL);
+ return 0;
+}
+
+
+static int java_udf_find(MYSQL_PSM_ROUTINE *handle,
+ const char *name, int name_length)
+{
+ *handle= (MYSQL_PSM_ROUTINE) malloc(sizeof(struct st_mysql_psmroutine));
+ bzero(*handle, sizeof(struct st_mysql_psmroutine));
+
+ Jvm *jvm= Jvm_singleton::get();
+ Java_context *java_context= jvm->attach();
+ (*handle)->jo_function_descriptor= java_context->call_object_method(
+ udf_module, "find", "com/mysql/udf/FunctionDescriptor",
+ name); /* make 'name' utf8 from system charset */
+ delete java_context;
+
+ if ( !(*handle)->jo_function_descriptor ) goto err;
+
+ return 0;
+
+err:
+ free (*handle);
+ (*handle)= NULL;
+ return -1;
+}
+
+static int java_udf_execute(MYSQL_PSM_ROUTINE handle,
+ MYSQL_PSM_CONTEXT psm_context)
+{
+ psm_java_context *context;
+ int error= -1;
+
+ if (!(context= THDVAR(psm_context->thd, context)))
+ {
+ context= new psm_java_context;
+ THDVAR(psm_context->thd, context)= context;
+ context->thd= psm_context->thd;
+ context->jvm= Jvm_singleton::get();
+ context->nesting_level= 1;
+ context->ref_count= 1;
+ context->java_context= context->jvm->attach();
+ }
+ else
+ {
+ context->nesting_level++;
+ context->ref_count++;
+ }
+ handle->context= context;
+
+ if (!handle->invoker)
+ {
+ Jobject_wrapper jw_function_descriptor(context->java_context,
+ handle->jo_function_descriptor);
+ jobject jo_callback= context->java_context->new_java_object(
+ "com/mysql/udf/NativeUDFCallback",
+ (unsigned long) psm_context);
+ if (!jo_callback)
+ goto err;
+ Jobject_wrapper jw_callback(context->java_context, jo_callback);
+ jw_callback.set_class_name("com/mysql/udf/UDFCallback");
+
+ handle->invoker= context->java_context->new_java_object(
+ "com/mysql/udf/Invoker",
+ &jw_function_descriptor,
+ &jw_callback);
+ if (!handle->invoker)
+ goto err;
+ context->java_context->call_void_method(handle->invoker, "init");
+ context->java_context->delete_global_reference(jo_callback);
+ }
+
+ context->java_context->call_void_method(handle->invoker, "exec");
+ context->nesting_level--;
+ error= 0;
+
+err:
+ if (context->ref_count != 1)
+ {
+ context->ref_count--;
+ handle->context= NULL;
+ }
+
+ return error;
+}
+
+static int java_udf_release(MYSQL_PSM_ROUTINE handle)
+{
+ Java_context *java_context= handle->context ?
+ handle->context->java_context : Jvm_singleton::get()->attach();
+
+ java_context->delete_global_reference(handle->invoker);
+ java_context->delete_global_reference(handle->jo_function_descriptor);
+
+ if (!handle->context)
+ delete java_context;
+ else
+ if (!(--handle->context->ref_count))
+ {
+ delete java_context;
+ THDVAR(handle->context->thd, context)= NULL;
+ delete handle->context;
+ }
+
+ free(handle);
+ return 0;
+};
+
+
+/*
+ Plugin type-specific descriptor
+*/
+
+static struct st_mysql_psmlanguage java_udf_descriptor=
+{
+ MYSQL_PSM_LANGUAGE_INTERFACE_VERSION, /* interface version */
+ java_udf_find, /* function resolution function */
+ java_udf_release, /* function release function */
+ java_udf_execute /* execute function */
+};
+
+/*
+ Plugin status variables for SHOW STATUS
+*/
+
+static struct st_mysql_show_var simple_status[]=
+{
+ {"jni_version", (char*) &jni_version, SHOW_INT},
+ {"jvm_version", "", SHOW_CHAR},
+ {0,0,SHOW_UNDEF}
+};
+
+/*
+ Plugin system variables.
+*/
+
+static MYSQL_SYSVAR_STR(config_file, jvm_options_file,
+ PLUGIN_VAR_READONLY, "Configuration file for Java virtual machine",
+ NULL, NULL, "jvm_options.cnf");
+
+
+static struct st_mysql_sys_var* system_variables[]= {
+ MYSQL_SYSVAR(context),
+ MYSQL_SYSVAR(config_file),
+ NULL
+};
+
+/*
+ Plugin library descriptor
+*/
+
+mysql_declare_plugin(ftexample)
+{
+ MYSQL_PSMLANGUAGE_PLUGIN, /* type */
+ &java_udf_descriptor, /* descriptor */
+ "Java", /* name */
+ "MySQL AB", /* author */
+ "Java UDF Demo", /* description */
+ PLUGIN_LICENSE_GPL,
+ java_udf_plugin_init, /* init function (when loaded) */
+ java_udf_plugin_deinit, /* deinit function (when unloaded) */
+ 0x0001, /* version */
+ simple_status, /* status variables */
+ system_variables, /* system variables */
+ NULL
+}
+mysql_declare_plugin_end;
+
diff -Nrup a/plugin/java_udf/java_util_arraylist.cc b/plugin/java_udf/java_util_arraylist.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_util_arraylist.cc 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,33 @@
+#include "java_util_arraylist.h"
+
+const char *ADD= "add";
+
+Java_util_arraylist::Java_util_arraylist(Java_context *java) : Java_object_parameter()
+{
+ _java= java;
+ _instance= _java->new_java_object("java/util/ArrayList");
+}
+
+
+Java_util_arraylist::~Java_util_arraylist()
+{
+ // remove reference to _instance
+}
+
+
+const char *Java_util_arraylist::java_parameter_class()
+{
+ return "java/util/List";
+}
+
+
+jobject Java_util_arraylist::as_java_object()
+{
+ return _instance;
+}
+
+
+void Java_util_arraylist::add(const char *str)
+{
+ _java->call_boolean_method_obj(_instance, ADD, str);
+}
diff -Nrup a/plugin/java_udf/java_util_arraylist.h b/plugin/java_udf/java_util_arraylist.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/java_util_arraylist.h 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,23 @@
+#ifndef JAVA_UTIL_ARRAYLIST_H_
+#define JAVA_UTIL_ARRAYLIST_H_
+#include <jni.h>
+#include "java_context.h"
+#include "java_object_parameter.h"
+
+class Java_util_arraylist : public Java_object_parameter
+{
+public:
+ Java_util_arraylist(Java_context *java);
+ virtual ~Java_util_arraylist();
+
+ void add(const char *str);
+
+ virtual const char *java_parameter_class();
+ virtual jobject as_java_object();
+
+private:
+ Java_context *_java;
+ jobject _instance;
+};
+
+#endif /*JAVA_UTIL_ARRAYLIST_H_*/
diff -Nrup a/plugin/java_udf/jbyte_array.cc b/plugin/java_udf/jbyte_array.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jbyte_array.cc 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,45 @@
+#include "jbyte_array.h"
+#include <jni.h>
+#include <string.h>
+
+Jbyte_array::Jbyte_array(jsize len, jbyte *body)
+{
+ _len= len;
+ _body= body;
+}
+
+Jbyte_array::~Jbyte_array()
+{
+}
+
+int Jbyte_array::length()
+{
+ return _len;
+}
+
+char Jbyte_array::get(int index)
+{
+ if (is_null() || index < 0 || index >= _len)
+ return 0;
+ return _body[index];
+}
+
+bool Jbyte_array::is_null()
+{
+ return (_body == NULL);
+}
+
+char *Jbyte_array::to_chars(char *buf, int buf_size)
+{
+ buf[0]= '\0';
+ if (is_null())
+ {
+ strncat(buf, "<NULL>", buf_size-1);
+ return buf;
+ }
+
+ for(int i= 0; i < length() && i < (buf_size - 1); i++)
+ buf[i]= (char) get(i);
+ buf[length()]= '\0';
+ return buf;
+}
diff -Nrup a/plugin/java_udf/jbyte_array.h b/plugin/java_udf/jbyte_array.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jbyte_array.h 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,27 @@
+#ifndef _JBYTE_ARRAY_H_
+#define _JBYTE_ARRAY_H_
+
+#include <jni.h>
+
+class Jbyte_array
+{
+
+public:
+ /**
+ * grep -i jbyte jni_md.h
+ * typedef signed char jbyte;
+ */
+ Jbyte_array(jsize len, jbyte *body);
+ ~Jbyte_array();
+
+ int length();
+ char get(int index);
+ bool is_null();
+ char *to_chars(char *buf, int buf_size);
+
+private:
+ jsize _len;
+ jbyte *_body;
+
+};
+#endif //_JBYTE_ARRAY_H_
diff -Nrup a/plugin/java_udf/jbyte_array_test.cc b/plugin/java_udf/jbyte_array_test.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jbyte_array_test.cc 2008-02-22 17:05:15 -08:00
@@ -0,0 +1,81 @@
+#include "test_utils.h"
+#include "jbyte_array.h"
+#include <stdio.h>
+#include <string.h>
+
+signed char *new_foo()
+{
+ signed char *foo= new signed char[3];
+ foo[0]= 'f';
+ foo[1]= 'o';
+ foo[2]= 'o';
+ return foo;
+}
+
+void test_char_jbyte_array_same_size()
+{
+ printf(".");
+ assert_ints_equal(sizeof(signed char), sizeof(jbyte), "sizeof char and jbyte");
+ jbyte a;
+ signed char b= 'b';
+ a= b;
+ assert_ints_equal(a, b, "type change");
+}
+
+void test_length()
+{
+ printf(".");
+ Jbyte_array *jb= new Jbyte_array(3, new_foo());
+ assert_ints_equal(jb->length(), 3, "length()");
+}
+
+void test_get()
+{
+ printf(".");
+ signed char *foo= new_foo();
+ Jbyte_array *jb= new Jbyte_array(3, foo);
+
+ for(int i= 0; i < jb->length(); i++)
+ {
+ char buf[12];
+ char msg[200];
+ sprintf(buf, "%d", i);
+ msg[0]= '\0';
+ strcat(msg, "get(");
+ strcat(msg, buf);
+ strcat(msg, ")");
+ assert_ints_equal(jb->get(i), foo[i], msg);
+ }
+}
+
+void test_is_null()
+{
+ printf(".");
+ Jbyte_array njb(-1, NULL);
+ assert_true(njb.is_null(), "Jbyte_array->is_null() with NULL");
+
+ Jbyte_array jb(3, new_foo());
+ assert_false(jb.is_null(), "Jbyte_array->is_null() with foo");
+}
+
+void test_to_chars()
+{
+ printf(".");
+
+ Jbyte_array jb(3, new_foo());
+
+ int buf_size= 80;
+ char buf[buf_size];
+ assert_string_equals(jb.to_chars(buf, buf_size), "foo", "to_chars()");
+}
+
+int main(int argc, char *argv[])
+{
+ printf("running %s ", argv[0]);
+ test_char_jbyte_array_same_size();
+ test_length();
+ test_get();
+ test_is_null();
+ test_to_chars();
+ printf(" Success\n");
+}
diff -Nrup a/plugin/java_udf/jnicallback.cc b/plugin/java_udf/jnicallback.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jnicallback.cc 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,244 @@
+#include <my_global.h>
+#include <stdlib.h>
+#include <m_ctype.h>
+#include <m_string.h>
+#include <mysql.h>
+#include <mysql/plugin.h>
+#include "jnicallback.h"
+#include "jniutils.h"
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: get_argument_count
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_mysql_udf_NativeUDFCallback_get_1argument_1count
+ (JNIEnv *jenv, jclass jcls, jlong that)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->arg_count;
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: get_argument_type
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_com_mysql_udf_NativeUDFCallback_get_1argument_1type
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ int field_type, length;
+ void *ptr;
+
+ context->field_ptr(arg_index, &field_type, &ptr, &length);
+ return field_type;
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: is_argument_null
+ * Signature: (JI)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_mysql_udf_NativeUDFCallback_is_1argument_1null
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->val_null(arg_index);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: set_null_argument
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_com_mysql_udf_NativeUDFCallback_set_1null_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ context->store_null(arg_index);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: get_long_argument
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_com_mysql_udf_NativeUDFCallback_get_1long_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->val_integer(arg_index);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: set_long_argument
+ * Signature: (JIJ)V
+ */
+JNIEXPORT void JNICALL Java_com_mysql_udf_NativeUDFCallback_set_1long_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index, jlong val)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ context->store_integer(arg_index, val, 0);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: get_string_argument
+ * Signature: (JI)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_mysql_udf_NativeUDFCallback_get_1string_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ int field_type, length;
+ void *ptr;
+ const char *str;
+ jstring jstr;
+ CHARSET_INFO* cs;
+
+ context->field_ptr(arg_index, &field_type, &ptr, &length);
+ length= ( length + 64 ) & ~63; /* round up temp size */
+
+ for (;;)
+ {
+ int temp_length= length;
+ char *temp_ptr= (char *) malloc(length);
+ str= context->val_string(arg_index, temp_ptr, &length, &cs);
+ if (length >= temp_length)
+ {
+ length= ( length + 64 ) & ~63; /* round up temp size */
+ free(temp_ptr);
+ continue;
+ }
+
+ jstr= make_jstring(jenv, str, length, cs);
+ free(temp_ptr);
+ return jstr;
+ }
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: set_string_argument
+ * Signature: (JILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_mysql_udf_NativeUDFCallback_set_1string_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index, jstring val)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+
+ const char *str= jenv->GetStringUTFChars(val, 0);
+
+ context->store_string(arg_index, str, strlen(str),
+ &my_charset_utf8_general_ci);
+
+ jenv->ReleaseStringUTFChars(val, str);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: get_double_argument
+ * Signature: (JI)D
+ */
+JNIEXPORT jdouble JNICALL Java_com_mysql_udf_NativeUDFCallback_get_1double_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->val_double(arg_index);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: set_double_argument
+ * Signature: (JID)V
+ */
+JNIEXPORT void JNICALL Java_com_mysql_udf_NativeUDFCallback_set_1double_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index, jdouble val)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ context->store_double(arg_index, val, 53 /* PRECISION_FOR_DOUBLE */);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: get_big_decimal_argument
+ * Signature: (JI)Ljava/math/BigDecimal;
+ */
+JNIEXPORT jstring JNICALL Java_com_mysql_udf_NativeUDFCallback_get_1big_1decimal_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index)
+{
+ return Java_com_mysql_udf_NativeUDFCallback_get_1string_1argument(jenv, jcls,
+ that, arg_index);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: set_big_decimal_argument
+ * Signature: (JILjava/math/BigDecimal;)V
+ */
+JNIEXPORT void JNICALL Java_com_mysql_udf_NativeUDFCallback_set_1big_1decimal_1argument
+ (JNIEnv *jenv, jclass jcls, jlong that, jint arg_index, jstring val)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ const char *str= jenv->GetStringUTFChars(val, 0);
+ context->store_string(arg_index, str, strlen(str),
+ &my_charset_utf8_general_ci);
+ jenv->ReleaseStringUTFChars(val, str);
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: row_field
+ * Signature: (JLjava/lang/String;III)I
+ */
+JNIEXPORT jint JNICALL Java_com_mysql_udf_NativeUDFCallback_row_1field
+ (JNIEnv *jenv, jclass jcls, jlong that, jstring col_name, jint field_type,
+ jint display_width, jint precision)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ const char *str= jenv->GetStringUTFChars(col_name, 0);
+ int rv= context->row_field(str, field_type, display_width,
+ precision);
+ jenv->ReleaseStringUTFChars(col_name, str);
+
+ return rv;
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: row_prepare
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_mysql_udf_NativeUDFCallback_row_1prepare
+ (JNIEnv *jenv, jclass jcls, jlong that)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->row_prepare();
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: row_send
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_mysql_udf_NativeUDFCallback_row_1send
+ (JNIEnv *jenv, jclass jcls, jlong that)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->row_send();
+}
+
+/*
+ * Class: com_mysql_udf_NativeUDFCallback
+ * Method: row_send_eof
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_com_mysql_udf_NativeUDFCallback_row_1send_1eof
+ (JNIEnv *jenv, jclass jcls, jlong that)
+{
+ MYSQL_PSM_CONTEXT context= (MYSQL_PSM_CONTEXT) that;
+ return context->row_send_eof();
+}
+
diff -Nrup a/plugin/java_udf/jniutils.cc b/plugin/java_udf/jniutils.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jniutils.cc 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,25 @@
+#include <my_global.h>
+#include "jniutils.h"
+
+jstring make_jstring(JNIEnv * jenv, const char *src_str, uint src_length,
+ CHARSET_INFO *src_cs)
+{
+ CHARSET_INFO *tgt_cs= &my_charset_utf8_general_ci;
+ char * tgt_str;
+ uint tgt_len;
+ uint add_len;
+ jstring result;
+ uint dummy; /* let us ignore any errors */
+
+ add_len= src_length / src_cs->mbminlen * tgt_cs->mbmaxlen;
+ tgt_str= (char *) malloc(add_len+1);
+
+ tgt_len= copy_and_convert(tgt_str, add_len, tgt_cs,
+ src_str, src_length, src_cs, &dummy);
+
+ tgt_str[tgt_len]= 0;
+ result= jenv->NewStringUTF(tgt_str);
+ free(tgt_str);
+
+ return result;
+}
diff -Nrup a/plugin/java_udf/jniutils.h b/plugin/java_udf/jniutils.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jniutils.h 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,25 @@
+#include <jni.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <strings.h>
+#include <mysql.h>
+#include <mysql/plugin.h>
+#include <m_ctype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+jstring make_jstring(JNIEnv * jenv, const char *src_str, uint src_length, CHARSET_INFO *src_cs);
+
+/* the following function is copied from sql_string.h */
+uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
+ const char *from, uint32 from_length,
+ CHARSET_INFO *from_cs, uint *errors);
+
+/* the following datatype is copied from mysql_priv.h */
+extern char *mysql_data_home;
+
+#ifdef __cplusplus
+}
+#endif
diff -Nrup a/plugin/java_udf/jobject_wrapper.cc b/plugin/java_udf/jobject_wrapper.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jobject_wrapper.cc 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,30 @@
+#include <my_global.h>
+#include <m_string.h>
+
+#include "jobject_wrapper.h"
+
+Jobject_wrapper::Jobject_wrapper(Java_context *java, jobject jobj) : Java_object_parameter()
+{
+ _java= java;
+ _jobj= jobj;
+ _java->get_class_name(_jobj, _class_name, sizeof(_class_name)-1);
+}
+
+Jobject_wrapper::~Jobject_wrapper()
+{
+}
+
+const char *Jobject_wrapper::java_parameter_class()
+{
+ return _class_name;
+}
+
+void Jobject_wrapper::set_class_name(const char *class_name)
+{
+ strxnmov(_class_name, sizeof(_class_name)-1, class_name, NullS);
+}
+
+jobject Jobject_wrapper::as_java_object()
+{
+ return _jobj;
+}
diff -Nrup a/plugin/java_udf/jobject_wrapper.h b/plugin/java_udf/jobject_wrapper.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jobject_wrapper.h 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,26 @@
+#ifndef _JOBJECT_WRAPPER_H_
+#define _JOBJECT_WRAPPER_H_
+
+#include "java_context.h"
+#include <jni.h>
+
+class Jobject_wrapper : public Java_object_parameter
+{
+public:
+ Jobject_wrapper(Java_context *java, jobject jobj);
+ virtual ~Jobject_wrapper();
+
+
+ // functions inherited from Java_object_parameter
+ const char *java_parameter_class();
+ jobject as_java_object();
+ void set_class_name(const char *);
+
+private:
+ Java_context *_java;
+ jobject _jobj;
+ char _class_name[256];
+
+};
+
+#endif /*_JOBJECT_WRAPPER_H_*/
diff -Nrup a/plugin/java_udf/jvm_interface.cc b/plugin/java_udf/jvm_interface.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jvm_interface.cc 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,10 @@
+#include "jvm_interface.h"
+
+// Jvm interface implementation
+Jvm::Jvm()
+{
+}
+
+Jvm::~Jvm()
+{
+}
diff -Nrup a/plugin/java_udf/jvm_interface.h b/plugin/java_udf/jvm_interface.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jvm_interface.h 2008-02-22 17:05:16 -08:00
@@ -0,0 +1,23 @@
+#ifndef _JVM_INTERFACE_H_
+#define _JVM_INTERFACE_H_
+
+class Java_context;
+
+// This is an "pure" interface class for JVM objects
+// The default implementation is NativeJVM
+// but we wish to make "mock" JVMs for testing
+class Jvm
+{
+
+public:
+ // constructors
+ Jvm();
+ virtual ~Jvm();
+
+ // methods
+ virtual Java_context *attach()= 0;
+ virtual void detach()= 0;
+ virtual void destroy_jvm()= 0;
+};
+
+#endif //_JVM_INTERFACE_H_
diff -Nrup a/plugin/java_udf/jvm_options.cnf.in b/plugin/java_udf/jvm_options.cnf.in
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jvm_options.cnf.in 2008-02-22 17:05:17 -08:00
@@ -0,0 +1,2 @@
+-Djava.awt.headless=true
+-Djava.class.path=.:@abs_srcdir@/java_udf.jar:@abs_srcdir@/java_udf_util.jar:@abs_srcdir@/java_udf_example.jar
diff -Nrup a/plugin/java_udf/jvm_singleton.cc b/plugin/java_udf/jvm_singleton.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jvm_singleton.cc 2008-02-22 17:05:17 -08:00
@@ -0,0 +1,60 @@
+#include "jvm_singleton.h"
+#include "jvm_interface.h"
+#include "native_jvm.h"
+#include <jni.h>
+
+// Should this be a "smart" mutex:
+// Should it unlock if an exception causes the stack to unwind past
+// the aquisition of the mutex?
+// This is trivial in Java, but I'll have to look into how to do
+// this in C++ ....
+
+Jvm *Jvm_singleton::_instance= NULL;
+pthread_mutex_t Jvm_singleton::_jvm_mutex= PTHREAD_MUTEX_INITIALIZER;
+char *Jvm_singleton::_vm_options_file= NULL;
+
+Jvm *Jvm_singleton::get()
+{
+ pthread_mutex_lock(&_jvm_mutex);
+
+ if ( _instance == NULL)
+ {
+ Native_jvm *new_jvm= new Native_jvm(_vm_options_file);
+ set_inner(new_jvm);
+ }
+
+ pthread_mutex_unlock(&_jvm_mutex);
+
+ return _instance;
+}
+
+
+Jvm *Jvm_singleton::check()
+{
+ Jvm *jvm;
+ pthread_mutex_lock(&_jvm_mutex);
+ jvm= _instance;
+ pthread_mutex_unlock(&_jvm_mutex);
+ return jvm;
+}
+
+void Jvm_singleton::set(Jvm *new_jvm)
+{
+ pthread_mutex_lock(&_jvm_mutex);
+
+ set_inner(new_jvm);
+
+ pthread_mutex_unlock(&_jvm_mutex);
+}
+
+
+void Jvm_singleton::set_default_jvm_options(char *vm_options_file)
+{
+ _vm_options_file= vm_options_file;
+}
+
+
+void Jvm_singleton::set_inner(Jvm *new_jvm) {
+ _instance= new_jvm;
+}
+
diff -Nrup a/plugin/java_udf/jvm_singleton.h b/plugin/java_udf/jvm_singleton.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jvm_singleton.h 2008-02-22 17:05:17 -08:00
@@ -0,0 +1,25 @@
+#ifndef _JVM_SINGLETON_H_
+#define _JVM_SINGLETON_H_
+
+#include <pthread.h>
+
+class Jvm;
+
+class Jvm_singleton
+{
+
+public:
+ static Jvm *get();
+ static Jvm *check();
+ static void set(Jvm *newJvm);
+ static void set_default_jvm_options(char *vm_options_file);
+
+private:
+ static Jvm *_instance;
+ static pthread_mutex_t _jvm_mutex;
+ static char *_vm_options_file;
+
+ static void set_inner(Jvm *newJvm);
+};
+
+#endif // _JVM_SINGLETON_H_
diff -Nrup a/plugin/java_udf/jvm_singleton_test.cc b/plugin/java_udf/jvm_singleton_test.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/jvm_singleton_test.cc 2008-02-22 17:05:17 -08:00
@@ -0,0 +1,19 @@
+#include "test_utils.h"
+#include "jvm_interface.h"
+#include "jvm_singleton.h"
+#include <stdio.h>
+
+void test_get()
+{
+ printf(".");
+ Jvm *jvm= Jvm_singleton::get();
+
+ assert_not_NULL(jvm, "Jvm");
+}
+
+int main(int argc, char *argv[])
+{
+ printf("running %s ", argv[0]);
+ test_get();
+ printf(" Success\n");
+}
diff -Nrup a/plugin/java_udf/makejars.sh b/plugin/java_udf/makejars.sh
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/makejars.sh 2008-02-22 17:05:17 -08:00
@@ -0,0 +1,19 @@
+#!/bin/sh
+jar cvf java_udf.jar ./com/mysql/udf/*.class
+jar cvf java_udf.src.jar ./com/mysql/udf/*.java
+
+jar cvf java_udf_util.jar ./com/mysql/udf/util/*.class
+jar cvf java_udf_util.src.jar ./com/mysql/udf/util/*.java
+
+jar cvf java_udf_example.jar ./com/mysql/udf/example/*.class
+jar cvf java_udf_example.src.jar ./com/mysql/udf/example/*.java
+
+jar cvf java_udf_test.jar ./com/mysql/jnitest/TestObject.class \
+ ./com/mysql/udf/test/*.class \
+ ./com/mysql/udf/test/util/*.class \
+ ./com/mysql/udf/test/example/*.class
+
+jar cvf java_udf_test.src.jar ./com/mysql/jnitest/TestObject.java \
+ ./com/mysql/udf/test/*.java \
+ ./com/mysql/udf/test/util/*.java \
+ ./com/mysql/udf/test/example/*.java
Binary files a/plugin/java_udf/mysql-connector-java-6.0-nightly-bin.jar and b/plugin/java_udf/mysql-connector-java-6.0-nightly-bin.jar differ
diff -Nrup a/plugin/java_udf/native_jvm.cc b/plugin/java_udf/native_jvm.cc
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/native_jvm.cc 2008-02-22 17:05:18 -08:00
@@ -0,0 +1,113 @@
+#include "native_jvm.h"
+#include <jni.h>
+#include <stdio.h>
+#include <string.h>
+
+Native_jvm::Native_jvm(const char* vm_options_file) : Jvm()
+{
+ JNIEnv* env;
+ JavaVMInitArgs* vm_args= new_vm_args(vm_options_file);
+
+ // Create the Java VM
+ jint res= JNI_CreateJavaVM(&_jvm,
+ (void **) &env,
+ (void *) vm_args);
+
+ // delete vm_args? No.
+
+ if (res < 0)
+ fprintf(stderr, "Can't create Java VM.");
+}
+
+Native_jvm::~Native_jvm()
+{
+ destroy_jvm();
+}
+
+void Native_jvm::destroy_jvm()
+{
+ if (_jvm != NULL)
+ _jvm->DestroyJavaVM();
+
+ _jvm= NULL;
+}
+
+Java_context *Native_jvm::attach ()
+{
+ JNIEnv *env;
+
+ jint res= _jvm->AttachCurrentThread ((void **) &env, NULL);
+ if (res < 0)
+ fprintf(stderr, "Attach Failed.");
+
+ return new Java_context(env);
+}
+
+void Native_jvm::detach()
+{
+ _jvm->DetachCurrentThread();
+}
+
+JavaVMInitArgs *Native_jvm::new_vm_args(const char *vm_options_file)
+{
+ // fprintf(stderr, "Options file: %s\n", vm_options_file);
+
+ /*****************************/
+ const int MAX_LINES= 20;
+ const int MAX_LINE_LENGTH= 2048;
+ int num_lines= 0;
+ FILE *options_file;
+ char buf[MAX_LINES][MAX_LINE_LENGTH];
+
+ if ((options_file= fopen(vm_options_file, "r")))
+ {
+ while (fgets(buf[num_lines], MAX_LINE_LENGTH, options_file)
+ && MAX_LINES > num_lines)
+ if (trim_right(buf[num_lines]) > 0)
+ num_lines++;
+ fclose(options_file);
+ }
+ /*****************************/
+ JavaVMOption *options= new JavaVMOption[num_lines];
+ for(int i= 0; i < num_lines; i++)
+ {
+ char *option= strdup(buf[i]);
+ options[i].optionString= option;
+ }
+
+ JavaVMInitArgs *vm_args= new JavaVMInitArgs;
+ vm_args->version= JNI_VERSION_1_4;
+ vm_args->options= options;
+ vm_args->nOptions= num_lines;
+
+ return vm_args;
+}
+
+/**************************/
+int Native_jvm::trim_right(char *str)
+{
+ int str_len;
+ int index;
+
+ if (str == NULL)
+ {
+ fprintf(stderr, "str is NULL");
+ return 0;
+ }
+
+ str_len= strlen(str);
+ index= str_len - 1;
+ if (str_len > 0)
+ {
+ while (index >= 0 && is_white_space(str[index]))
+ index--;
+ str[index+1]='\0';
+ }
+ return index;
+}
+
+bool Native_jvm::is_white_space(char c)
+{
+ return c == '\n' || c == ' ' || c == '\t' || c == '\r';
+}
+
diff -Nrup a/plugin/java_udf/native_jvm.h b/plugin/java_udf/native_jvm.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/plugin/java_udf/native_jvm.h 2008-02-22 17:05:18 -08:00
@@ -0,0 +1,27 @@
+#ifndef _NATIVE_JVM_H_
+#define _NATIVE_JVM_H_
+
+#include "jvm_interface.h"
+#include "java_context.h"
+#include <jni.h>
+
+class Native_jvm : public Jvm
+{
+
+public:
+ Native_jvm(const char *vm_options_file);
+ ~Native_jvm();
+
+ Java_context *attach();
| Thread |
|---|
| • bk commit into 5.1 tree (antony:1.2531) | antony | 23 Feb |