Martijn van Oosterhout 7 December 2006 12:50:09 [ permanent link ]
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.
Zoltan Boszormenyi 7 December 2006 14:55:47 [ permanent link ]
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; bool isnull;
t = PG_GETARG_HEAPTUPLEHEADER(0); timest = DatumGetTimestamp(GetAttributeByName(t, "ts_today", &isnull)); elog(NOTICE, "DatumGetTimestamp() OK, value is %s", isnull ? "NULL" : "NOT NULL");
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
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.
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:
Martijn van Oosterhout 7 December 2006 16:22:26 [ permanent link ]
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:>
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; bool isnull;
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.
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;> bool isnull;>
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
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;>> bool isnull;>>
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:
Martijn van Oosterhout 8 December 2006 12:53:48 [ permanent link ]
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.
If you would like to report an abuse of our service, such as a spam message, please . Если Вы хотите пожаловаться на содержимое этой страницы, пожалуйста .