1

I want to return an vector of pairs using a C extension. This is a simple code I have:

extern "C" { 
Datum pair(PG_FUNCTION_ARGS){ 

        // get the input
        text *t1 = PG_GETARG_TEXT_PP(0); 
        text *t2 = PG_GETARG_TEXT_PP(1); 
        std::string localT1 = text_to_cstring(t1); 
        std::string localT2 = text_to_cstring(t2); 

        // Return vector of pairs 
        std::vector<std::pair&lt;std::string, std::string>> ret; 
        ret.emplace_back(encodedLocalT1, encodedLocalT2); 
        PG_RETURN_ARRAYTYPE_P(ret); 

}; 
PG_FUNCTION_INFO_V1(pair); 
} 

But it doesn't work like it and I don't know if it's even possible. So I tried to return a text[] but it doesn't work either:

extern "C" { 
Datum pair(PG_FUNCTION_ARGS){ 

        // Get the input 
        text *t1 = PG_GETARG_TEXT_PP(0); 
        text *t2 = PG_GETARG_TEXT_PP(1); 
        std::string localT1 = text_to_cstring(t1); 
        std::string localT2 = text_to_cstring(t2); 

        // Return array with 2 strings 
        ArrayType *array;
        Datum elements[2];
        int16 typlen;
        bool typbyval;
        char typalign;

        elements[0] = cstring_to_text(localT1.c_str());
        elements[1] = cstring_to_text(localT2.c_str());

        get_typlenbyvalalign(TEXTOID, &typlen, &typbyval, &typalign);
        array = construct_array(elements, 2, TEXTOID, typlen, typbyval, typalign);

        PG_RETURN_ARRAYTYPE_P(array);

}; 
PG_FUNCTION_INFO_V1(pair); 
} 

I use those includes in the extension:

extern "C" { // C Headers must be inside exter "C" { } block.
#include <postgres.h>
#include <fmgr.h>
#include <utils/builtins.h>
#include <catalog/pg_type.h>
#include <utils/rel.h>
#include <utils/array.h>
#include <stdlib.h>
#include <stdint.h>
#include <utils/lsyscache.h>

PG_MODULE_MAGIC;
}

// CPP Header must be outside extern "C" { } block.
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iterator> // For the ostream_iterator
#include <chrono> // For some code benchmarking

// External projects c++ libraries compiled and linked on running 'make'.
#include <seal/seal.h>
#include <thread>
#include <cppcodec/base64_rfc4648.hpp>

The code example above is minimal to help with the question. All the includes are used in the long version of the code.

I can't seem to figure out how to achieve my goal, I prefer to return text[] with the 2 strings as its elements.

1 Answer 1

1

This code worked for me.

extern "C" { 
Datum text_array(PG_FUNCTION_ARGS){ 

        // Get the inputs of TEXT type variables 
        text *t1 = PG_GETARG_TEXT_PP(0); 
        text *t2 = PG_GETARG_TEXT_PP(1); 
        // Cast into cpp strings
        std::string localT1 = TextDatumGetCString(t1); 
        std::string localT2 = TextDatumGetCString(t2); 

        // Return a text array with 2 elemsnts
        ArrayType *array;
        Datum elements[2];
        int16 typlen;
        bool typbyval;
        char typalign;

        // Cast the cpp strings back to pgSQL Datum type
        elements[0] = CStringGetTextDatum(localT1.c_str());
        elements[1] = CStringGetTextDatum(localT2.c_str());
        // Create the return array for pgSQL
        get_typlenbyvalalign(TEXTOID, &typlen, &typbyval, &typalign);
        array = construct_array(elements, 2, TEXTOID, typlen, typbyval, typalign);

        PG_RETURN_ARRAYTYPE_P(array);

}; 
PG_FUNCTION_INFO_V1(text_array); 
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.