static IntPtr From(byte[] value)
        {
            var ptr = PostgresInterop.pg_alloc_datum(value.Length);

            Marshal.Copy(value, 0, ptr + 4, value.Length);
            return(ptr);
        }
        static DateTime ToTime(IntPtr value)
        {
            var ret = PostgresInterop.pg_timestamp_to_cstring(value);
            var s   = Marshal.PtrToStringAnsi(ret);

            return(s.SafeDatetimeParse() ?? DateTime.MinValue);
        }
        static decimal ToNumber(IntPtr value)
        {
            // cannot use default marshalling because it will free the memory
            var ret = PostgresInterop.pg_numeric_to_cstring(value);
            var s   = Marshal.PtrToStringAnsi(ret);

            return(s.SafeDecimalParse() ?? 0);
        }
        //-----------------------------------------------------
        // individual conversion functions, from common to Datum
        static IntPtr From(string value)
        {
            var bytes = Encoding.UTF8.GetBytes(value);
            var ptr   = PostgresInterop.pg_alloc_datum(bytes.Length);

            Marshal.Copy(bytes, 0, ptr + 4, bytes.Length);
            return(ptr);
        }
        //-----------------------------------------------------
        // individual conversion functions, from Datum to common
        // IntPtr points to varlena struct
        // First int is length<<2 (two bits left as flags)
        // length includes header, so data length is (len/4)-4

        // Get raw binary
        static byte[] ToBinary(IntPtr value)
        {
            var dval = PostgresInterop.pg_detoast_bytea(value);
            var len  = Marshal.ReadInt32(dval) / 4;
            var buf  = new byte[len - 4];

            Marshal.Copy(dval + 4, buf, 0, buf.Length);
            return(buf);
        }
 static IntPtr From(decimal value)
 {
     return(PostgresInterop.pg_cstring_to_numeric(value.ToString()));
 }
 static IntPtr From(DateTime value)
 {
     return(PostgresInterop.pg_cstring_to_timestamp(value.ToString("yyyy-MM-dd HH:mm:ss.fff")));
 }