getting error while compiling UDF
Hello All,
I am trying to compile a simple UDF for checking if the string is completely alphabetic.
This is my code
g++ -D HAVE_LONG_INT_64 -I /opt/vertica/sdk/include -Wall -shared -Wno-unused-value -fPIC -o home/dbadmin/navin/isalpha.so isalpha.cpp /opt/vertica/sdk/include/Vertica.cpp
isalpha.cpp: In member function ‘virtual Vertica::ScalarFunction* isalphaFactory::createScalarFunction(Vertica::ServerInterface&)’:
isalpha.cpp:72: error: ISO C++ forbids applying ‘sizeof’ to an expression of function type
isalpha.cpp:72: error: expected type-specifier before ‘isalpha’
isalpha.cpp:72: error: expected ')' before ‘isalpha’
isalpha.cpp:72: error: cannot convert ‘int*’ to ‘Vertica::ScalarFunction*’ in return
I tried googling these errors, but no effective solution to this.
Can anybody point out what mistakes I am doing and explain me the mistakes and solution.
Thanks in Advance
I am trying to compile a simple UDF for checking if the string is completely alphabetic.
This is my code
#include "Vertica.h"When I try compiling it using this statement
#include <algorithm> using namespace Vertica; using namespace std; /* * ScalarFunction implementation for a UDSF that adds * two numbers together. */ class isalpha : public ScalarFunction { public: virtual void processBlock(ServerInterface &srvInterface, BlockReader &arg_reader, BlockWriter &res_writer) { do { std::string inStr = arg_reader.getStringRef(0).str(); size_t pos; while( (pos=inStr.find('.')) != string::npos || (pos=inStr.find(',')) != string::npos ) inStr.erase(pos, 1); int sizeOfString = inStr.length(); int iteration = 0; bool isAlpha = true; while(iteration < sizeOfString) { if(!isalpha(inStr[iteration])) { isAlpha = false; break; } iteration++; } res_writer.setBool(isAlpha); // Finish writing the row, and advance to the next output row res_writer.next(); // Continue looping until there are no more input rows } while (arg_reader.next()); } }; class isalphaFactory : public ScalarFunctionFactory { // return an instance of Add2Ints to perform the actual addition. virtual ScalarFunction *createScalarFunction(ServerInterface &interface) { // Calls the vt_createFuncObj to create the new Add2Ints class instance. return vt_createFuncObj(interface.allocator, isalpha); } virtual void getPrototype(ServerInterface &interface, ColumnTypes &argTypes, ColumnTypes &returnType) { // Takes two ints as inputs, so add ints to the argTypes object argTypes.addVarchar(); returnType.addBool(); } }; // Register the factory with HP Vertica RegisterFactory(isalphaFactory);
g++ -D HAVE_LONG_INT_64 -I /opt/vertica/sdk/include -Wall -shared -Wno-unused-value -fPIC -o home/dbadmin/navin/isalpha.so isalpha.cpp /opt/vertica/sdk/include/Vertica.cpp
isalpha.cpp: In member function ‘virtual Vertica::ScalarFunction* isalphaFactory::createScalarFunction(Vertica::ServerInterface&)’:
isalpha.cpp:72: error: ISO C++ forbids applying ‘sizeof’ to an expression of function type
isalpha.cpp:72: error: expected type-specifier before ‘isalpha’
isalpha.cpp:72: error: expected ')' before ‘isalpha’
isalpha.cpp:72: error: cannot convert ‘int*’ to ‘Vertica::ScalarFunction*’ in return
I tried googling these errors, but no effective solution to this.
Can anybody point out what mistakes I am doing and explain me the mistakes and solution.
Thanks in Advance
0
Comments
I'm glad to hear that you're writing a UDx! Let us know how it goes.
If you would be interested in publishing your UDx, we would be glad to take it as an addition to the strings_package on https://github.com/vertica/Vertica-Extension-Packages
The issue here is a namespace collision: You have declared a class "isalpha", but the <algorithm> header also declares a function "isalpha()". When you call "vt_createFuncObj(interface.allocator, isalpha)", "isalpha" is therefore ambiguous. (The error is because your compiler is picking the wrong one, and the vt_createFuncObj() macro is trying to do something that makes sense for an object/class but not for a raw function.)
The simple solution would be to rename your class to not have the same name as a system function.
The more-complex solution would be to note that all system functions are in the std:: namespace, and your class is in the global namespace. So you could, alternatively, be more explicit about your namespace usage; make it unambiguous which thing you mean. (For example, "::isalpha" means the one in the global namespace; "::std::isalpha" means the one in the std namespace.) I would only recommend this approach if you're familiar/comfortable with C++ namespaces; otherwise it would be simpler to just make sure everything has a distinct name. (Keep in mind, the C++ class name can be different from the SQL function name; you can specify a different function name in your CREATE DDL statement.)
If you're trying to debug this sort of error, you might consider installing and compiling with the "clang"/"clang++" compiler, rather than g++. clang is included in the yum or apt repositories of many of our supported Linux distributions. g++ is our officially supported compiler; it's what we test with. But I know there are people using clang; you can certainly at least try compiling with it to see what error messages it gives. And in this case it gives a much more verbose error message: (Actual error contains bold and colored text to identify each line; sadly I can't copy/paste that here)
Adam