diff --git a/utils/udfsdk/CMakeLists.txt b/utils/udfsdk/CMakeLists.txt index 5e4428cd9..809140c7f 100644 --- a/utils/udfsdk/CMakeLists.txt +++ b/utils/udfsdk/CMakeLists.txt @@ -4,7 +4,7 @@ include_directories( ${ENGINE_COMMON_INCLUDES} ########### next target ############### -set(udfsdk_LIB_SRCS udfinfinidb.cpp) +set(udfsdk_LIB_SRCS udfsdk.cpp) add_definitions(-DMYSQL_DYNAMIC_PLUGIN) diff --git a/utils/udfsdk/README.txt b/utils/udfsdk/README.txt index 3b72ec2f0..83497ca46 100644 --- a/utils/udfsdk/README.txt +++ b/utils/udfsdk/README.txt @@ -1,26 +1,23 @@ -How to use the InfiniDB UDF SDK +How to use the ColumnStore UDF SDK -Make sure you have a working GCC C++ compiler system, version 4.1.2 or later. You -also must have the libxml2-devel package installed. -Obtain the InfiniDB source distribution for your version of InfiniDB -from github.com. -Ideally, the machine you are compiling on and deploying on are the same machine. If this -is not possible, they must have the same InfiniDB software installation. - -Unpack the source tar file +Obtain the MariaDB columnstore source code from https://github.com/mariadb-corporation/mariadb-columnstore-server +and follow the pre-requisite and build instructions. Go into the utils/udfsdk directory. -At this point you can use the idb_add() function template in udfinfinidb.cpp and udfmysql.cpp +At this point you can use the MCS_add() function template in udfsdk.cpp and udfmysql.cpp files to create your own function or just try that function as is. -Make the library -Stop InfiniDB -Copy the libudf_mysql.so.1.0.0 and libudfsdk.so.1.0.0 file to /usr/local/mariadb/columnstore/lib on -every InfiniDB node -Start InfiniDB -In the directory /usr/local/mariadb/columnstore/mysql/lib64/mysql/plugin create a symbolic link called -libudf_msql.so to the file /usr/local/mariadb/columnstore/lib/libudf_msql.so.1.0.0 -In the mysql client add the function (e.g. "create function idb_add returns integer soname -'libudf_msql.so';") -You should now be able to use the idb_add() function in the select and/or where clauses -of SQL statements. +- Make the library + $ make +- Copy the libudf_mysql.so.1.0.0 and libudfsdk.so.1.0.0 file to /usr/local/mariadb/columnstore/lib on + every columnstore node. + $ sudo cp libudf_mysql.so.1.0.0 libudfsdk.so.1.0.0 /usr/local/mariadb/columnstore/lib/ +- Restart ColumnStore + $ mcsadmin restartsystem y +- Using the mcsmysql client add the user defined function, e.g, + $ mcsmysql + > create function mcs_add returns integer soname 'libudf_mysql.so'; + > create function mcs_isnull returns string soname 'libudf_mysql.so'; + +You should now be able to use the mcs_add(arg1, arg2) and mcs_isnull(arg) functions in the select and/or where clauses +of SQL statements. \ No newline at end of file diff --git a/utils/udfsdk/udfmysql.cpp b/utils/udfsdk/udfmysql.cpp index 4d14b2479..e6707278b 100644 --- a/utils/udfsdk/udfmysql.cpp +++ b/utils/udfsdk/udfmysql.cpp @@ -82,8 +82,8 @@ inline string cvtArgToString(int t, const char* v) } /**************************************************************************** - * UDF function interface for MySQL connector to recognize is defined in - * this section. MySQL's UDF function creation guideline needs to be followed. + * UDF function interface for MariaDB connector to recognize is defined in + * this section. MariaDB's UDF function creation guideline needs to be followed. * * Three interface need to be defined on the connector for each UDF function. * @@ -91,12 +91,12 @@ inline string cvtArgToString(int t, const char* v) * the input. * XXX_deinit: To clean up the memory. * XXX: The function implementation. - * Detailed instruction can be found at MySQL source directory: + * Detailed instruction can be found at MariaDB source directory: * ~/sql/udf_example.cc. * * Please note that the implementation of the function defined on the connector * will only be called when all the input arguments are constant. e.g., - * idb_add(2,3). That way, the function does not run in a distributed fashion + * mcs_add(2,3). That way, the function does not run in a distributed fashion * and could be slow. If there is a need for the UDF function to run with * pure constant input, then one needs to put a implementation in the XXX * body, which is very similar to the ones in getXXXval API. If there's no @@ -106,16 +106,16 @@ inline string cvtArgToString(int t, const char* v) extern "C" { /** - * IDB_ADD connector stub + * MCS_ADD connector stub */ #ifdef _MSC_VER __declspec(dllexport) #endif -my_bool idb_add_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +my_bool mcs_add_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { if (args->arg_count != 2) { - strcpy(message,"idb_add() requires two argument"); + strcpy(message,"mcs_add() requires two argument"); return 1; } @@ -125,14 +125,14 @@ my_bool idb_add_init(UDF_INIT* initid, UDF_ARGS* args, char* message) #ifdef _MSC_VER __declspec(dllexport) #endif -void idb_add_deinit(UDF_INIT* initid) +void mcs_add_deinit(UDF_INIT* initid) { } #ifdef _MSC_VER __declspec(dllexport) #endif -double idb_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +double mcs_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { double op1, op2; @@ -143,17 +143,17 @@ double idb_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) } /** - * IDB_ISNULL connector stub + * MCS_ISNULL connector stub */ #ifdef _MSC_VER __declspec(dllexport) #endif -my_bool idb_isnull_init(UDF_INIT* initid, UDF_ARGS* args, char* message) +my_bool mcs_isnull_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { if (args->arg_count != 1) { - strcpy(message,"idb_isnull() requires one argument"); + strcpy(message,"mcs_isnull() requires one argument"); return 1; } @@ -163,14 +163,14 @@ my_bool idb_isnull_init(UDF_INIT* initid, UDF_ARGS* args, char* message) #ifdef _MSC_VER __declspec(dllexport) #endif -void idb_isnull_deinit(UDF_INIT* initid) +void mcs_isnull_deinit(UDF_INIT* initid) { } #ifdef _MSC_VER __declspec(dllexport) #endif -long long idb_isnull(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) +long long mcs_isnull(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { return 0; } diff --git a/utils/udfsdk/udfinfinidb.cpp b/utils/udfsdk/udfsdk.cpp similarity index 85% rename from utils/udfsdk/udfinfinidb.cpp rename to utils/udfsdk/udfsdk.cpp index 892979bda..c341680d3 100644 --- a/utils/udfsdk/udfinfinidb.cpp +++ b/utils/udfsdk/udfsdk.cpp @@ -53,9 +53,9 @@ UDFSDK::~UDFSDK() /** * All UDF functions should be registered in the function map. They will be - * picked up by the InfiniDB F&E framework when the servers are started. - * That will make sure the UDF functions runs distributedly in InfiniDB - * engines just like the internal InfiniDB functions. + * picked up by the MariaDB ColumnStore F&E framework when the servers are started. + * That will make sure the UDF functions runs distributedly in ColumnStore + * engines just like the internal ColumnStore functions. */ FuncMap UDFSDK::UDFMap() const { @@ -64,23 +64,23 @@ FuncMap UDFSDK::UDFMap() const // first: function name // second: Function pointer // please use lower case for the function name. Because the names might be - // case-insensitive in MySQL depending on the setting. In such case, + // case-insensitive in MariaDB depending on the setting. In such case, // the function names passed to the interface is always in lower case. - fm["idb_add"] = new IDB_add(); - fm["idb_isnull"] = new IDB_isnull(); + fm["mcs_add"] = new MCS_add(); + fm["mcs_isnull"] = new MCS_isnull(); return fm; } /*************************************************************************** - * IDB_ADD implementation + * MCS_ADD implementation * * OperationType() definition */ -CalpontSystemCatalog::ColType IDB_add::operationType (FunctionParm& fp, +CalpontSystemCatalog::ColType MCS_add::operationType (FunctionParm& fp, CalpontSystemCatalog::ColType& resultType) { - // operation type of idb_add is determined by the argument types + // operation type of MCS_add is determined by the argument types assert (fp.size() == 2); CalpontSystemCatalog::ColType rt; if (fp[0]->data()->resultType() == fp[1]->data()->resultType()) @@ -135,7 +135,7 @@ CalpontSystemCatalog::ColType IDB_add::operationType (FunctionParm& fp, * * This API is called when an double value is needed to return from the UDF function */ -double IDB_add::getDoubleVal(Row& row, +double MCS_add::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -190,7 +190,7 @@ double IDB_add::getDoubleVal(Row& row, return 0; } -float IDB_add::getFloatVal(Row& row, +float MCS_add::getFloatVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -203,11 +203,11 @@ float IDB_add::getFloatVal(Row& row, * * This API is called when an integer value is needed to return from the UDF function * - * Because the result type idb_add is double(real), all the other API can simply call + * Because the result type MCS_add is double(real), all the other API can simply call * getDoubleVal and apply the conversion. This method may not fit for all the UDF * implementation. */ -int64_t IDB_add::getIntVal(Row& row, +int64_t MCS_add::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -215,7 +215,7 @@ int64_t IDB_add::getIntVal(Row& row, return (int64_t)getDoubleVal(row, parm, isNull, op_ct); } -string IDB_add::getStrVal(Row& row, +string MCS_add::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -227,7 +227,7 @@ string IDB_add::getStrVal(Row& row, return oss.str(); } -IDB_Decimal IDB_add::getDecimalVal(Row& row, +IDB_Decimal MCS_add::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -239,26 +239,26 @@ IDB_Decimal IDB_add::getDecimalVal(Row& row, } /** - * This API should never be called for IDB_add, because the latter + * This API should never be called for MCS_add, because the latter * is not for date/datetime values addition. In such case, one can * either not implement this API and an IDB-5001 error will be thrown, * or throw a customized exception here. */ -int32_t IDB_add::getDateIntVal(Row& row, +int32_t MCS_add::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) { - throw logic_error("Invalid API called for IDB_ADD"); + throw logic_error("Invalid API called for MCS_ADD"); } /** - * This API should never be called for IDB_add, because the latter + * This API should never be called for MCS_add, because the latter * is not for date/datetime values addition. In such case, one can * either not implement this API and an IDB-5001 error will be thrown, * or throw a customized exception here. */ -int64_t IDB_add::getDatetimeIntVal(Row& row, +int64_t MCS_add::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -266,7 +266,7 @@ int64_t IDB_add::getDatetimeIntVal(Row& row, return (int64_t)getDoubleVal(row, parm, isNull, op_ct); } -bool IDB_add::getBoolVal(Row& row, +bool MCS_add::getBoolVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -275,14 +275,14 @@ bool IDB_add::getBoolVal(Row& row, } /*************************************************************************** - * IDB_ISNULL implementation + * MCS_ISNULL implementation * * OperationType() definition */ -CalpontSystemCatalog::ColType IDB_isnull::operationType (FunctionParm& fp, +CalpontSystemCatalog::ColType MCS_isnull::operationType (FunctionParm& fp, CalpontSystemCatalog::ColType& resultType) { - // operation type of idb_isnull should be the same as the argument type + // operation type of MCS_isnull should be the same as the argument type assert (fp.size() == 1); return fp[0]->data()->resultType(); } @@ -290,9 +290,9 @@ CalpontSystemCatalog::ColType IDB_isnull::operationType (FunctionParm& fp, /** * getBoolVal API definition * - * This would be the most commonly called API for idb_isnull function + * This would be the most commonly called API for MCS_isnull function */ -bool IDB_isnull::getBoolVal(Row& row, +bool MCS_isnull::getBoolVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -304,7 +304,7 @@ bool IDB_isnull::getBoolVal(Row& row, // in parameter isNull will be set if the parameter is evaluated NULL. // Please note that before this function returns, isNull should be set to // false, otherwise the result of the function would be considered NULL, - // which is not possible for idb_isnull(). + // which is not possible for MCS_isnull(). case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: parm[0]->data()->getDecimalVal(row, isNull); @@ -327,7 +327,7 @@ bool IDB_isnull::getBoolVal(Row& row, * * This API is called when a double value is needed to return from the UDF function */ -double IDB_isnull::getDoubleVal(Row& row, +double MCS_isnull::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -335,7 +335,7 @@ double IDB_isnull::getDoubleVal(Row& row, return (getBoolVal(row, parm, isNull, op_ct) ? 1 : 0); } -float IDB_isnull::getFloatVal(Row& row, +float MCS_isnull::getFloatVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -348,11 +348,11 @@ float IDB_isnull::getFloatVal(Row& row, * * This API is called when an integer value is needed to return from the UDF function * - * Because the result type idb_add is double(real), all the other API can simply call + * Because the result type MCS_add is double(real), all the other API can simply call * getDoubleVal and apply the conversion. This method may not fit for all the UDF * implementations. */ -int64_t IDB_isnull::getIntVal(Row& row, +int64_t MCS_isnull::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -360,7 +360,7 @@ int64_t IDB_isnull::getIntVal(Row& row, return (getBoolVal(row, parm, isNull, op_ct) ? 1 : 0); } -string IDB_isnull::getStrVal(Row& row, +string MCS_isnull::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -371,7 +371,7 @@ string IDB_isnull::getStrVal(Row& row, } -IDB_Decimal IDB_isnull::getDecimalVal(Row& row, +IDB_Decimal MCS_isnull::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -382,7 +382,7 @@ IDB_Decimal IDB_isnull::getDecimalVal(Row& row, return dec; } -int32_t IDB_isnull::getDateIntVal(Row& row, +int32_t MCS_isnull::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) @@ -390,7 +390,7 @@ int32_t IDB_isnull::getDateIntVal(Row& row, return (getBoolVal(row, parm, isNull, op_ct) ? 1 : 0); } -int64_t IDB_isnull::getDatetimeIntVal(Row& row, +int64_t MCS_isnull::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& op_ct) diff --git a/utils/udfsdk/udfsdk.h b/utils/udfsdk/udfsdk.h index 659cb837c..d472fe91e 100644 --- a/utils/udfsdk/udfsdk.h +++ b/utils/udfsdk/udfsdk.h @@ -23,7 +23,7 @@ ***********************************************************************/ /** - * InfiniDB interface for writing a user defined function (UDF). + * MariaDB ColumnStore interface for writing a user defined function (UDF). * * The basic steps are: * @@ -32,13 +32,13 @@ * 3. add the connector stub for this UDF function in udfsdk.cpp * 4. build the dynamic library libudfsdk * 5. put the library in /usr/local/mariadb/columnstore/lib of all modules - * 6. restart all the InfiniDB servers and MySQL server - * 7. notify mysqld about the new functions with the commands like: + * 6. restart MariaDB ColumnStore + * 7. Register the new functions with the commands like: * - * CREATE FUNCTION idb_add returns REAL soname 'libudfsdk.so'; - * CREATE FUNCTION idb_isnull returns BOOL soname 'libudfsdk.so'; + * CREATE FUNCTION mcs_add returns REAL soname 'libudfsdk.so'; + * CREATE FUNCTION mcs_isnull returns BOOL soname 'libudfsdk.so'; * - * The UDF functions run distributedly in the InfiniDB engine. The evaluation + * The UDF functions run distributedly in the ColumnStore engine. The evaluation * is row by row. Aggregate UDF is currently not supported. Two examples are * given in this file to demonstrate the steps that it takes to create a UDF * function. More examples can be found in utils/funcexp/func_*.cpp. @@ -78,9 +78,9 @@ private: }; /** - * Example: IDB_add (args1, args2) + * Example: MCS_add (args1, args2) * - * IDB_add takes two arguments of any data type. It returns a double result. + * MCS_add takes two arguments of any data type. It returns a double result. * * The function interface is defined here. All UDF functions are derived from * class funcexp::Func. A set of getXXXval interface APIs are declared in the @@ -90,30 +90,30 @@ private: * the function is expected to return. * * For example, given the following two queries, different APIs will be called - * to evaluate the function idb_add. + * to evaluate the function MCS_add. * - * select idb_add(int1, int2) from t1; - * getDoubleVal() is called, because the result type of idb_add is DOUBLE(real). + * select MCS_add(int1, int2) from t1; + * getDoubleVal() is called, because the result type of MCS_add is DOUBLE(real). * - * select substr(string1, int1, idb_add(int1+int2)); - * getIntVal() will be called, because idb_add() is passed as the third argument + * select substr(string1, int1, MCS_add(int1+int2)); + * getIntVal() will be called, because MCS_add() is passed as the third argument * to substr function, and an integer result is expected. * * If one API is not implemented but called for a function, IDB-5001 error will * be returned. */ -class IDB_add : public funcexp::Func +class MCS_add : public funcexp::Func { public: /* * Constructor. Pass the function name to the base constructor. */ - IDB_add() : Func("idb_add") {} + MCS_add() : Func("mcs_add") {} /* - * Destructor. IDB_add does not need to do anything here to clean up. + * Destructor. MCS_add does not need to do anything here to clean up. */ - virtual ~IDB_add() {} + virtual ~MCS_add() {} /** * Decide on the function's operation type @@ -152,7 +152,7 @@ public: * the same reference is passed to all the function argument * evaluations. One always need to know if any argument is NULL * to decide the result of the function. It's explained in detail - * in idb_isnull() function example. + * in MCS_isnull() function example. * @parm op_ct the operation type that is determined in operationType(). * */ @@ -205,7 +205,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a date result of the function. + * Returns an integer representation of a date result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. @@ -216,7 +216,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a datetime result of the function. + * Returns an integer representation of a datetime result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. @@ -228,22 +228,22 @@ public: }; /** - * Example: IDB_isnull(arg1) + * Example: MCS_isnull(arg1) * * The purpose of this example is to demostrate the NULL handling in the UDF interface */ -class IDB_isnull : public funcexp::Func +class MCS_isnull : public funcexp::Func { public: /* * Constructor. Pass the function name to the base constructor. */ - IDB_isnull() : Func("idb_isnull") {} + MCS_isnull() : Func("mcs_isnull") {} /* - * Destructor. IDB_add does not need to do anything here to clean up. + * Destructor. MCS_add does not need to do anything here to clean up. */ - virtual ~IDB_isnull() {} + virtual ~MCS_isnull() {} /** * Decide on the function's operation type @@ -301,7 +301,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a date result of the function. + * Returns an integer representation of a date result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API. @@ -312,7 +312,7 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); /** - * Returns an InfiniDB integer representation of a datetime result of the function. + * Returns an integer representation of a datetime result of the function. * * Check the date/time functions in ~/utils/funcexp for implementation * example of this API.