We're Moving!

The Vertica Forum is moving to a new OpenText Analytics Database (Vertica) Community.

Join us there to post discussion topics, learn about

product releases, share tips, access the blog, and much more.

Create My New Community Account Now


How to make AnalyticPartitionWriter produce arbitrary fixed-point numeric data? — Vertica Forum

How to make AnalyticPartitionWriter produce arbitrary fixed-point numeric data?

Anyone have any tips for outputing numerics (i.e. with precision and scale) from AnalyticPartitionWriter? It seems there is no setNumeric() method.
https://docs.vertica.com/24.4.x/sdkdocs/CppSDK/class_vertica_1_1_analytic_partition_writer.htm

I'm writing a UDx and it would be very handy to produce VNumerics. Instead I'm using floats which make me nervous. Seems Java has it... why not C++? Is there some other method?

Comments

  • Bryan_HBryan_H Vertica Employee Administrator

    You should be able to create a VNumeric and pass the pointer in the C++ SDK:
    VNumeric * getColPtrForWrite (size_t idx)

  • Thanks. I'm struggling to get that function to work though, getting strange values like 1402984621720.88. Probably I'm using it wrong. Do you have an example of how it should be used? Attaching a reproducer.

    dbadmin@pc=>with nums as (select 12.5::numeric(8,2) as num) select *, numeric_test(num) over () from nums;
      num  |     ?column?
    -------+------------------
     12.50 | 1402984621720.88
    (1 row)
    
  • edited November 2024

    Ok, figured it out with the help of InvertedIndex.cpp example from the SDK.

    class numeric_test : public AnalyticFunction
    {
        virtual void processPartition(ServerInterface &srvInterface, AnalyticPartitionReader &inputReader,
                                        AnalyticPartitionWriter &outputWriter)
        {   
            const SizedColumnTypes &inTypes = inputReader.getTypeMetaData();
            vector<size_t> argCols;
            inTypes.getArgumentColumns(argCols);
    
            const SizedColumnTypes &outTypes = outputWriter.getTypeMetaData();
            vector<size_t> outCols;
            outTypes.getArgumentColumns(outCols);
    
            do {
                const VNumeric* inVal = inputReader.getNumericPtr(argCols.at(0));
                char* buff = new char[64];
                inVal->toString(buff, 64);
                srvInterface.log("string value of inVal: %s", buff);
    
                VNumeric &outNum = outputWriter.getNumericRef(outCols.at(0));
                outNum.copy(inVal);
    
                outputWriter.next();
            } while (inputReader.next());
        }
    
        virtual void setup(ServerInterface &srvInterface, const SizedColumnTypes
                            &argTypes)
        { }
    
        virtual void destroy(ServerInterface &srvInterface, const SizedColumnTypes
                            &argTypes)
        { }
    };
    
  • Just to point out, conversions to/from string are outrageously expensive.
    I remember solving problem, by creating var of required datatype, for example NUMERIC(10,2). Then, overriding 8-byte array with my value. That performs quite reasonable.

Leave a Comment

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