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)
> ;
>

Reply via email to