Re: [GENERAL] Internal function call from C-language function

2006-12-08 Thread Martijn van Oosterhout
On Thu, Dec 07, 2006 at 06:01:13PM +0100, Zoltan Boszormenyi wrote:
 I have just one more question:
 How can I get an Oid out of a Datum, i.e.
 how do I know what type I get in a given Datum?
 DatumGetObjectId() seems to give me an Oid that
 was specifically stored as a Datum.
 
 I have found the alternative solution.
 If t is HeapTupleHeader then:

snip

There is no way to tell what type is in a Datum, it's just that,
nothing else. The information about the actual type can come from
elsewhere, for example:

- If extracting from a tuple, the tuple descriptor has the type (as you found)
- If passed as argument, the fcinfo struct *may* have the type
information
- The SPI interface provide ways to get information also

On the other side, a Datum is abstract, and you can receive a Datum as
argument and pass it to other functions without needing to know what
type it is. But you better so it right because there is no type
checking on that level.

As for the backtrace, you can get gdb to attach to the backend after
you connect. Then when you get the segfault, gdb will catch it and show
you exactly where.

Have a nice day,
-- 
Martijn van Oosterhout   kleptog@svana.org   http://svana.org/kleptog/
 From each according to his ability. To each according to his ability to 
 litigate.


signature.asc
Description: Digital signature


[GENERAL] Internal function call from C-language function

2006-12-07 Thread Zoltan Boszormenyi

Hi,

I need to call date_part() from a C function.
How to do that?

Thanks in advance,
Zoltán Böszörményi


---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Martijn van Oosterhout
On Thu, Dec 07, 2006 at 09:48:25AM +0100, Zoltan Boszormenyi wrote:
 Hi,
 
 I need to call date_part() from a C function.
 How to do that?

Look in fmgr.h for the functions {Oid,Direct,}FunctionCall* which
provide various ways to call other functions.

There's also FunctionCallInvoke() which is more efficient if you're
going to call it lots of times.

Have a nice day,
-- 
Martijn van Oosterhout   kleptog@svana.org   http://svana.org/kleptog/
 From each according to his ability. To each according to his ability to 
 litigate.


signature.asc
Description: Digital signature


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Zoltan Boszormenyi

Hi,

Martijn van Oosterhout írta:

On Thu, Dec 07, 2006 at 09:48:25AM +0100, Zoltan Boszormenyi wrote:
  

Hi,

I need to call date_part() from a C function.
How to do that?



Look in fmgr.h for the functions {Oid,Direct,}FunctionCall* which
provide various ways to call other functions.

There's also FunctionCallInvoke() which is more efficient if you're
going to call it lots of times.

Have a nice day,
  


thanks, I found the DirectFunctionCall family,
that wasn't the problem.

The real trick was that inside a C function,
I have to use timestamp_part(), as date_part()
doesn't even exists. The header catalog/pg_proc.h
proves it. date_part() is an SQL wrapper around
real C functions: timestamp[tz]_part(), time[tz]_part()
and interval_part().

However, I have another problem. I have this in the code:

  HeapTupleHeader t;
  Datum   timest;
  boolisnull;

   t = PG_GETARG_HEAPTUPLEHEADER(0);
   timest = DatumGetTimestamp(GetAttributeByName(t, ts_today, 
isnull));
   elog(NOTICE, DatumGetTimestamp() OK, value is %s, isnull ? 
NULL : NOT NULL);


   if (isnull)
   PG_RETURN_BOOL(false);

   yeardatum = CStringGetDatum(year);  
   elog(NOTICE, CStringGetDatum() 1 OK);
   returndatum = DirectFunctionCall2(timestamp_part, yeardatum, 
timest);
   elog(NOTICE, date_part() 1 OK); 
   year = DatumGetFloat8(returndatum);
   elog(NOTICE, conversion 1 OK);


...

But I get this:

NOTICE:  PG_GETARG OK
NOTICE:  DatumGetTimestamp() OK, value is NOT NULL
NOTICE:  CStringGetDatum() 1 OK
ERROR:  invalid memory alloc request size 1951613700

So DirectFunctionCall2() fails. How can I fix it?

Best regards,
Zoltán


---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Martijn van Oosterhout
On Thu, Dec 07, 2006 at 12:55:47PM +0100, Zoltan Boszormenyi wrote:
 However, I have another problem. I have this in the code:

snip

yeardatum = CStringGetDatum(year);  
elog(NOTICE, CStringGetDatum() 1 OK);
returndatum = DirectFunctionCall2(timestamp_part, yeardatum, 
 timest);

You're passing a cstring as first argument, whereas I'm fairly sure you
should be passing text. When calling from C the're no argument
checking. I think what you're looking for is:

  yeardatum = text_in(year);

Or something like that.

Hope this helps,
-- 
Martijn van Oosterhout   kleptog@svana.org   http://svana.org/kleptog/
 From each according to his ability. To each according to his ability to 
 litigate.


signature.asc
Description: Digital signature


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Zoltan Boszormenyi

Martijn van Oosterhout írta:

On Thu, Dec 07, 2006 at 12:55:47PM +0100, Zoltan Boszormenyi wrote:
  

However, I have another problem. I have this in the code:



snip

  
   yeardatum = CStringGetDatum(year);  
   elog(NOTICE, CStringGetDatum() 1 OK);
   returndatum = DirectFunctionCall2(timestamp_part, yeardatum, 
timest);



You're passing a cstring as first argument, whereas I'm fairly sure you
should be passing text. When calling from C the're no argument
checking. I think what you're looking for is:

  yeardatum = text_in(year);

Or something like that.

Hope this helps,
  


text_in() doesn't exists, it's textin() but I have to call it through
DirectFunctionCall1(), like this:

yeardatum = DirectFunctionCall1(textin, CStringGetDatum(year));

However, the session crashes on the subsequent

returndatum = DirectFunctionCall2(timestamp_part, yeardatum, timest);

Best regards,

Zoltán


---(end of broadcast)---
TIP 4: Have you searched our list archives?

  http://archives.postgresql.org/


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Martijn van Oosterhout
On Thu, Dec 07, 2006 at 01:40:22PM +0100, Zoltan Boszormenyi wrote:
 text_in() doesn't exists, it's textin() but I have to call it through
 DirectFunctionCall1(), like this:
 
 yeardatum = DirectFunctionCall1(textin, CStringGetDatum(year));
 
 However, the session crashes on the subsequent
 
 returndatum = DirectFunctionCall2(timestamp_part, yeardatum, timest);

It would be a good idea to actually find out where it crashes, that
would help you work out what the actual problem is. Just looking at the
code you posted, I only see this other bit that looks a bit suspect:

  Datum   timest;
  boolisnull;

   t = PG_GETARG_HEAPTUPLEHEADER(0);
   timest = DatumGetTimestamp(GetAttributeByName(t, ts_today, isnull));

You're calling DatumGetTimestamp() which would return a timestamp
(probably some structure) but you're storing it in a Datum. Just take
the result of GetAttributeByName directly.

Get at least a backtrace next time it crashes...

Have a nice day,
-- 
Martijn van Oosterhout   kleptog@svana.org   http://svana.org/kleptog/
 From each according to his ability. To each according to his ability to 
 litigate.


signature.asc
Description: Digital signature


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Zoltan Boszormenyi

Hi,

Martijn van Oosterhout írta:

On Thu, Dec 07, 2006 at 01:40:22PM +0100, Zoltan Boszormenyi wrote:
  

text_in() doesn't exists, it's textin() but I have to call it through
DirectFunctionCall1(), like this:

yeardatum = DirectFunctionCall1(textin, CStringGetDatum(year));

However, the session crashes on the subsequent

returndatum = DirectFunctionCall2(timestamp_part, yeardatum, timest);



It would be a good idea to actually find out where it crashes, that
would help you work out what the actual problem is. Just looking at the
code you posted, I only see this other bit that looks a bit suspect:

  Datum   timest;
  boolisnull;

   t = PG_GETARG_HEAPTUPLEHEADER(0);
   timest = DatumGetTimestamp(GetAttributeByName(t, ts_today, isnull));

You're calling DatumGetTimestamp() which would return a timestamp
(probably some structure) but you're storing it in a Datum. Just take
the result of GetAttributeByName directly.
  


Thanks, that worked for me.

I have just one more question:
How can I get an Oid out of a Datum, i.e.
how do I know what type I get in a given Datum?
DatumGetObjectId() seems to give me an Oid that
was specifically stored as a Datum.

The function I am working on is made for an
INSERT RULE, something like this:

CREATE OR REPLACE FUNCTION
myfunc( row1 table1 ) RETURNS BOOL VOLATILE
LANGUAGE C AS 'myfunc.so', 'myfunc';

CREATE RULE rule_table1_insert
AS ON INSERT TO table1
DO INSTEAD (SELECT myfunc( new ) );

So I get the to-be-inserted row in my function.
In the function, depending on the passed in values
I need to insert some other table. To do it,
I need to use SPI_prepare() which needs the list of Oids.


Get at least a backtrace next time it crashes...
  


And how exactly can I do that? psql only reports that
the backend crashed and unable to reset connection.
At that time the backend session is already gone, isn't it?


Have a nice day,
  


Thanks, to you, too. You helped a lot.

Best regards,
Zoltán


---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] Internal function call from C-language function

2006-12-07 Thread Zoltan Boszormenyi

Hi,

Zoltan Boszormenyi írta:

Hi,

Martijn van Oosterhout írta:

On Thu, Dec 07, 2006 at 01:40:22PM +0100, Zoltan Boszormenyi wrote:
 

text_in() doesn't exists, it's textin() but I have to call it through
DirectFunctionCall1(), like this:

yeardatum = DirectFunctionCall1(textin, CStringGetDatum(year));

However, the session crashes on the subsequent

returndatum = DirectFunctionCall2(timestamp_part, yeardatum, timest);



It would be a good idea to actually find out where it crashes, that
would help you work out what the actual problem is. Just looking at the
code you posted, I only see this other bit that looks a bit suspect:

  Datum   timest;
  boolisnull;

   t = PG_GETARG_HEAPTUPLEHEADER(0);
   timest = DatumGetTimestamp(GetAttributeByName(t, ts_today, 
isnull));


You're calling DatumGetTimestamp() which would return a timestamp
(probably some structure) but you're storing it in a Datum. Just take
the result of GetAttributeByName directly.
  


Thanks, that worked for me.

I have just one more question:
How can I get an Oid out of a Datum, i.e.
how do I know what type I get in a given Datum?
DatumGetObjectId() seems to give me an Oid that
was specifically stored as a Datum.


I have found the alternative solution.
If t is HeapTupleHeader then:

   Oid tupType;
   int32   tupTypmod;
   TupleDesc   tupDesc;

   tupType = HeapTupleHeaderGetTypeId(t);
   tupTypmod = HeapTupleHeaderGetTypMod(t);
   tupDesc = lookup_rowtype_tupdesc(tupType, tupTypmod);

will give me the needed TupleDesc and I can use SPI_gettypeid().

Thanks and best regards,
Zoltán


---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq