| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 9 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 3 个月前 | ||
| 5 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 8 个月前 | ||
| 8 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 8 个月前 | ||
| 8 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 7 个月前 | ||
| 7 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 9 个月前 | ||
| 7 个月前 | ||
| 7 个月前 |
Adding new external functions
To add new functions to omni-runtime, follow the steps below. You will need to modify: externalfunctions.h, externalfunctions.cpp, func_registry.cpp.
Steps to create function
-
If needed, create new
.hand.cppfile for function types such as ``, otherwise put new functions in theexternalfunctions.handexternalfunctions.cppfiles. -
Add the function declaration of the
function in theexternalfunctions.hfile. ex:extern DELLEXPORT int32_t add1(int32_t x);Parameter types can be
int32_t,int64_t,double,boolean,stringordecimal.- For variable length
stringparameter akaVARCHAR, it's passed in aschar*(pointer to the data) andint32_t(length of the string) - For fixed length
stringparameter akaCHAR(width), it's passed in aschar*(pointer to the data)int32_t(width) andint32_t(length of the string) - For
decimal128bit parameter, it's passed in asint64_t(high 64 bit) andint64_t(low 64 bit) values. - If you need to allocate memory for returning
stringvalues, you can also pass in aint64_tin the beginning of parameter list as the pointer address to anExecutionContextobject, and use this object to allocate new memory for better performance and void memory leak
Return type can also be
int32_t,int64_t,double,boolean,stringordecimal.- For
stringreturn type, the function return type should bechar*, but a pointer to the return string length will also be passed in at the end of the param list - For
decimal128bit return type, the pointers to the high bits and low bits must be passed in at the end of the param list.
- For variable length
-
Write function in C++ in the
externalfunctions.cppfile(If you want to use template for your functions you can put your implementation in header). ex:extern DLLEXPORT int32_t add1(int32_t x) { return x + 1; } -
Register your functions in Function Registry: You can either register the functions in
external_func_registry.cppor create your own registry- If adding to
external_func_registry, you only need to add your function in theGetFunctions()method. - If creating your own registry, you need to implement the
BaseFunctionRegistryinterface infunc_registry_base.hand add all your functions inGetFunctions()method.
vector<Function> ExternalFunctionRegistry::GetFunctions() { std::vector<Function> externalFunctionRegistry = { Function(reinterpret_cast<void*>(Increment<int32_t>), "Increment", {}, {OMNI_INT}, OMNI_INT), Function(reinterpret_cast<void*>(Increment<int64_t>), "Increment", {}, {OMNI_LONG}, OMNI_LONG), }; return externalFunctionRegistry; }The return types and parameter types in function signature registered can only be the data types, currently supporting:
- OMNI_INT
- OMNI_LONG
- OMNI_DOUBLE
- OMNI_BOOLEAN
- OMNI_VARCHAR
- OMNI_CHAR
- OMNI_DECIMAL64
- OMNI_DECIMAL128
- If adding to
-
Finally, if you are adding a new function registry, register it in the
FunctionRegistryclass infunc_registryby adding it to the registries list inGetFunctionRegistries()method:vector<unique_ptr<BaseFunctionRegistry>> FunctionRegistry::GetFunctionRegistries() { vector<unique_ptr<BaseFunctionRegistry>> functionRegistries; // Other registries... // External functions functionRegistries.push_back(make_unique<ExternalFunctionRegistry>()); // Put your registry here return functionRegistries; }
Exception handling
When registering function, set setExecutionContext to true:
Function(reinterpret_cast<void*>(Increment<int32_t>), "Increment", {}, {OMNI_INT}, OMNI_INT, true)
In your function whenever you need to throw an error or exception, set error message in the execution context by using helper function SetError in context_helper.h:
#include "context_helper.h"
// Make sure you have the contextPtr as the first arg in your function
extern "C" DLLEXPORT int64_t DivDec64Ret64(int64_t contextPtr, int64_t x, int64_t y)
{
if (y == 0) {
char message[] = "Divided by zero error!";
SetError(contextPtr, message, sizeof(message)/sizeof(char));
return 0;
}
return round(double(x)/y);
}
Filter and Projection operators will throw OMNI_EXCEPTION which will be caught at JNI layer and be returned to engine side.
Adding new functions
OmniRuntime Function Class
Function(void *address, string &fnName, vector<string> &aliases, vector<DataType> ¶mTypes, DataType &retType, bool setExecutionContext);
Constructs a omni-runtime Function object that contains the functionality and attributes of an omni-runtime function including function signature to facilitate registration and funcID to uniquely identify built-in or external functions in the functions dir.
fnNamedenotes the name the function will be referenced by the query.substr,LIKE,abs, etc. are examples of fnNames for base functions.generateFuncIDis used to generate afuncIDthat is used to identify the corresponding function from thefunctionsdir that the omniruntimeFunctionrefers to.aliasesallows us to specify multiple names for the same functionaddressis the void function pointerparamTypesis a vector of data types of arguments -VARCHARandCHARare expanded to their corresponding function signature equivalent types to contain value, length for VARCHAR and value, length and width forCHARretTypeis the data type of the return valuesetExecutionContextif true - pass the execution context to func signature as a param, it will always be the first parameter in your function, default to false
Function Registry
- Instead of a single function registry class, each xxxfunctions.cpp file has a corresponding xxx_func_registry.cpp that appends the omniruntime
Functionto the single static vectorfunctionRegistry. LookupFunctionreturns the omniruntimeFunctioncorresponding to thefuncIDprovided.