From: Tor Didriksen Date: September 19 2011 2:28pm Subject: bzr push into mysql-trunk branch (tor.didriksen:3439 to 3440) List-Archive: http://lists.mysql.com/commits/141013 Message-Id: <201109191428.p8JESv2H009112@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3440 Tor Didriksen 2011-09-19 Add a UDF using stl. modified: mysql-test/r/udf.result mysql-test/t/udf.test sql/udf_example.cc 3439 Tor Didriksen 2011-09-19 Convert udf_example from .c to .cc renamed: sql/udf_example.c => sql/udf_example.cc modified: sql/CMakeLists.txt sql/udf_example.cc === modified file 'mysql-test/r/udf.result' --- a/mysql-test/r/udf.result 2011-07-19 15:11:15 +0000 +++ b/mysql-test/r/udf.result 2011-09-19 14:27:04 +0000 @@ -499,3 +499,26 @@ UNLOCK TABLES; # Reaping: CREATE FUNCTION metaphon ... DROP FUNCTION metaphon; DROP FUNCTION reverse_lookup; +# +# WL#5825 Using C++ Standard Library with MySQL code +# +CREATE AGGREGATE FUNCTION my_median +RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB"; +SELECT my_median(1); +my_median(1) +1 +CREATE TABLE t1(a INT, b INT); +SELECT a, my_median(b) from t1 group by a; +a my_median(b) +INSERT INTO t1 values +(1, 1), (1, 2), (1, 200), +(2, 1), (2, 200), (2, 200), (2, 1000), +(3, 1), (3, 1), (3, 100), (3, 100), (3, 42) +; +SELECT a, my_median(b) from t1 GROUP BY a; +a my_median(b) +1 2 +2 200 +3 42 +DROP FUNCTION my_median; +DROP TABLE t1; === modified file 'mysql-test/t/udf.test' --- a/mysql-test/t/udf.test 2011-02-09 10:19:05 +0000 +++ b/mysql-test/t/udf.test 2011-09-19 14:27:04 +0000 @@ -603,3 +603,24 @@ connection default; --reap DROP FUNCTION metaphon; DROP FUNCTION reverse_lookup; + +--echo # +--echo # WL#5825 Using C++ Standard Library with MySQL code +--echo # + +--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB +eval CREATE AGGREGATE FUNCTION my_median +RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB"; + +SELECT my_median(1); +CREATE TABLE t1(a INT, b INT); +SELECT a, my_median(b) from t1 group by a; +INSERT INTO t1 values +(1, 1), (1, 2), (1, 200), +(2, 1), (2, 200), (2, 200), (2, 1000), +(3, 1), (3, 1), (3, 100), (3, 100), (3, 42) +; +SELECT a, my_median(b) from t1 GROUP BY a; + +DROP FUNCTION my_median; +DROP TABLE t1; === modified file 'sql/udf_example.cc' --- a/sql/udf_example.cc 2011-09-19 11:20:45 +0000 +++ b/sql/udf_example.cc 2011-09-19 14:27:04 +0000 @@ -112,6 +112,8 @@ */ #include +#include +#include #ifdef STANDARD /* STANDARD is defined, don't use any mysql functions */ @@ -1153,4 +1155,79 @@ char * check_const_len(UDF_INIT *initid, } +C_MODE_START; +my_bool my_median_init (UDF_INIT *initid, UDF_ARGS *args, char *message); +void my_median_deinit(UDF_INIT* initid); +void my_median_add (UDF_INIT* initid, UDF_ARGS* args, + char* is_null, char *error); +void my_median_clear (UDF_INIT* initid, UDF_ARGS* args, + char* is_null, char *error); +longlong my_median (UDF_INIT* initid, UDF_ARGS* args, + char* is_null, char *error); +C_MODE_END; + +struct My_median_data +{ + std::vector vec; +}; + + +my_bool my_median_init (UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + My_median_data *data= new (std::nothrow) My_median_data; + if (!data) + { + strmov(message,"Could not allocate memory"); + return true; + } + initid->ptr= static_cast(static_cast(data)); + return false; +} + +void my_median_deinit(UDF_INIT* initid) +{ + My_median_data *data= + static_cast(static_cast(initid->ptr)); + delete data; +} + +void my_median_add(UDF_INIT* initid, UDF_ARGS* args, + char* is_null __attribute__((unused)), + char* message __attribute__((unused))) +{ + My_median_data *data= + static_cast(static_cast(initid->ptr)); + if (args->args[0]) + { + void *arg0= args->args[0]; + longlong number= *(static_cast(arg0)); + data->vec.push_back(number); + } +} + +void my_median_clear(UDF_INIT* initid, UDF_ARGS* args, + char* is_null __attribute__((unused)), + char* message __attribute__((unused))) +{ + My_median_data *data= + static_cast(static_cast(initid->ptr)); + data->vec.clear(); +} + +longlong my_median(UDF_INIT* initid, UDF_ARGS* args, + char* is_null, + char* message __attribute__((unused))) +{ + My_median_data *data= + static_cast(static_cast(initid->ptr)); + if (data->vec.size() == 0) + { + *is_null= 1; + return 0; + } + const size_t ix= data->vec.size() / 2; + std::nth_element(data->vec.begin(), data->vec.begin() + ix, data->vec.end()); + return data->vec[ix]; +} + #endif /* HAVE_DLOPEN */ No bundle (reason: useless for push emails).