Problem with composite type creation in C under Linux - Mailing list pgsql-hackers

From Marios Vodas
Subject Problem with composite type creation in C under Linux
Date
Msg-id AANLkTing+0QkHQRem6rrK3+d6qCO++6221M398RNDCrp@mail.gmail.com
Whole thread Raw
Responses Re: Problem with composite type creation in C under Linux
List pgsql-hackers
I have developed some custom composite and base types in PostgreSQL 9 which you can find in the code I provide below.
I compile my C library using GCC 4.5 under Linux and Visual Studio 2010 under Windows.

The problem is when I run this command: SELECT to_composite('((1, 2), (3, 4))'::m_segment_base).
This is the result I get in Windows and Linux respectively:

    Windows: "("(1,2)","(3,4)")"
    Linux: "("(1,)",)"

Probably the composite type is not created well in function "to_composite", but I guess the code should be OK since it works under MSVC...

So my question is why this doesn't work under Linux? And how can I fix it of course.

Here is my code in SQL and C:


***SQL code***
CREATE TYPE m_point_composite AS
(
    x double precision,
    y double precision
);

CREATE TYPE m_segment_composite AS
(
    i m_point_composite,
    e m_point_composite
);

CREATE TYPE m_point_base
(
    INTERNALLENGTH = 16,
    INPUT = m_point_base_in,
    OUTPUT = m_point_base_out,
    RECEIVE = m_point_base_recv,
    SEND = m_point_base_send,
    ALIGNMENT = double
);

CREATE TYPE m_segment_base
(
    INTERNALLENGTH = 32,
    INPUT = m_segment_base_in,
    OUTPUT = m_segment_base_out,
    RECEIVE = m_segment_base_recv,
    SEND = m_segment_base_send,
    ALIGNMENT = double
); 

CREATE OR REPLACE FUNCTION to_composite(m_segment_base)
RETURNS m_segment_composite AS
    '$libdir/myLib','to_composite'
LANGUAGE 'C' IMMUTABLE STRICT;

***C code***
struct m_point_base {
    float8 x;
    float8 y;
};

struct m_segment_base {
    m_point_base i;
    m_point_base e;
};

PGDLLEXPORT Datum to_composite(PG_FUNCTION_ARGS) {
    m_segment_base *in = (m_segment_base *) PG_GETARG_POINTER(0);

    TupleDesc tupdesc;
    bool isnull;

    Datum vi[2];
    HeapTuple i;

    Datum ve[2];
    HeapTuple e;

    Datum vout[2];
    HeapTuple out;

    TupleDesc tupdesc_m_point_composite = RelationNameGetTupleDesc("m_point_composite");

    vi[0] = Float8GetDatum(in->i.x);
    vi[1] = Float8GetDatum(in->i.y);
    i = heap_form_tuple(tupdesc_m_point_composite, vi, &isnull);

    ve[0] = Float8GetDatum(in->e.x);
    ve[1] = Float8GetDatum(in->e.y);
    e = heap_form_tuple(tupdesc_m_point_composite, ve, &isnull);

    vout[0] = HeapTupleGetDatum(i);
    vout[1] = HeapTupleGetDatum(e);

    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
        ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("function returning record called in context that cannot accept type record")));
    }

    BlessTupleDesc(tupdesc);
    out = heap_form_tuple(tupdesc, vout, &isnull);

    PG_RETURN_DATUM(HeapTupleGetDatum(out));
}
PG_FUNCTION_INFO_V1(to_composite)
;

pgsql-hackers by date:

Previous
From: David Fetter
Date:
Subject: Re: Alpha4 release blockers (was Re: wrapping up this CommitFest)
Next
From: Tom Lane
Date:
Subject: Re: Problem with composite type creation in C under Linux