getting error while compiling UDF

Navin_CNavin_C Vertica Customer
Hello All,

I am trying to compile a simple UDF for checking if the string is completely alphabetic.

This is my code
#include "Vertica.h"
#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);
When I try compiling it using this statement

 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


Comments

  • Hi Navin,

    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)
    $ clang++ -D HAVE_LONG_INT_64  -I /opt/vertica/sdk/include -Wall -shared -Wno-unused-value -fPIC -o isalpha.so isalpha.cpp /opt/vertica/sdk/include/Vertica.cpp
    (...)
    isalpha.cpp:57:50: error: reference to 'isalpha' is ambiguous
        return vt_createFuncObj(interface.allocator, isalpha);
                                                     ^
    /opt/vertica/sdk/include/BasicsUDxShared.h:827:47: note: expanded from macro 'vt_createFuncObj'
        (new ((_allocator)->alloc(sizeof(_type))) _type(_args))
                                                  ^
    isalpha.cpp:10:7: note: candidate found by name lookup is 'isalpha'
    class isalpha : public ScalarFunction
          ^
    /usr/include/ctype.h:112:12: note: candidate found by name lookup is 'isalpha'
    __exctype (isalpha);
               ^
    /usr/include/ctype.h:103:36: note: expanded from macro '__exctype'
    #define __exctype(name) extern int name (int) __THROW
                                       ^
    /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/locale_facets.h:2560:5: note: candidate
          found by name lookup is 'std::isalpha'
        isalpha(_CharT __c, const locale& __loc)
        ^
    4 errors generated.

    Adam

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file