Thread: ERROR: cache lookup failed for type 0
Hi, I am learning how to use the c functions and my function below works when I do: select testgetrows(); but when I do select * from testgetrows(); I am getting: "ERROR: cache lookup failed for type 0" Whats's the problem? 10x. drop function testgetrows(); CREATE OR REPLACE FUNCTION testgetrows() RETURNS SETOF my_first_table AS 'foo6', 'testgetrows' LANGUAGE C IMMUTABLE STRICT; #include "postgres.h" #include <string.h> #include <array.h> #include "fmgr.h" #include "funcapi.h" #include "access/heapam.h" typedef struct { HeapScanDesc scan; Relation lRel; } testgetrows_fctx; PG_FUNCTION_INFO_V1(testgetrows); Datum testgetrows(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; testgetrows_fctx *fctx; if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); fctx = (testgetrows_fctx *) palloc(sizeof(testgetrows_fctx)); fctx->lRel = heap_open(17236, AccessShareLock); fctx->scan = heap_beginscan(fctx->lRel, SnapshotNow, 0, NULL); funcctx->user_fctx = fctx; MemoryContextSwitchTo(oldcontext); } funcctx = SRF_PERCALL_SETUP(); fctx = funcctx->user_fctx; HeapTuple tuple; tuple = heap_getnext(fctx->scan, ForwardScanDirection); if (HeapTupleIsValid(tuple)) { Datum result; result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); } else /* do when there is no more left */ { heap_endscan(fctx->scan); heap_close(fctx->lRel, AccessShareLock); SRF_RETURN_DONE(funcctx); } } Regards, tzahi.
Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > Hi, I am learning how to use the c functions and my function below works > when I do: > select testgetrows(); > but when I do select * from testgetrows(); I am getting: > "ERROR: cache lookup failed for type 0" > Whats's the problem? I don't think it's safe to do HeapTupleGetDatum() directly on a tuple obtained from heap_getnext. You need to copy it. regards, tom lane
It still doesn't work. btw, I am using 8rc2. changed it to: Datum result; HeapTuple tupleCopy; tupleCopy = heap_copytuple(tuple); result = HeapTupleGetDatum(tupleCopy); SRF_RETURN_NEXT(funcctx, result); its probably something with the column description. the rows are returned ok with select testgetrows(); but not with select * from testgetrows(); Regards, tzahi. > -----Original Message----- > From: pgsql-general-owner@postgresql.org > [mailto:pgsql-general-owner@postgresql.org] On Behalf Of Tom Lane > Sent: Friday, January 07, 2005 8:59 PM > To: Tzahi Fadida > Cc: pgsql-general@postgresql.org > Subject: Re: [GENERAL] ERROR: cache lookup failed for type 0 > > > Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > > Hi, I am learning how to use the c functions and my function below > > works when I do: select testgetrows(); > > but when I do select * from testgetrows(); I am getting: > > "ERROR: cache lookup failed for type 0" > > Whats's the problem? > > I don't think it's safe to do HeapTupleGetDatum() directly on > a tuple obtained from heap_getnext. You need to copy it. > > regards, tom lane > > ---------------------------(end of > broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to > majordomo@postgresql.org > >
Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > It still doesn't work. btw, I am using 8rc2. Um. The "clean" way to do this is to use BlessTupleDesc and then heap_formtuple. That requires you to break down the original tuple into fields (see heap_deformtuple). Alternatively you could poke the datatype ID fields directly into the copied tuple. regards, tom lane
well, I tried the heap_deformtuple and I am getting now: select testgetrows(); server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request. The connection to the server was lost. Attempting reset: Failed. !> btw, as can be seen below I tried two kinds of tupledesc just in case with the same results. /*funcctx->tuple_desc= BlessTupleDesc(fctx->lRel->rd_att);*/ funcctx->tuple_desc=BlessTupleDesc(RelationNameGetTupleDesc("my_first_ta ble")); #include "postgres.h" #include <string.h> #include <array.h> #include "fmgr.h" #include "funcapi.h" #include "access/heapam.h" typedef struct { HeapScanDesc scan; Relation lRel; } testgetrows_fctx; PG_FUNCTION_INFO_V1(testgetrows); Datum testgetrows(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; testgetrows_fctx *fctx; if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); fctx = (testgetrows_fctx *) palloc(sizeof(testgetrows_fctx)); fctx->lRel = heap_open(17236, AccessShareLock); fctx->scan = heap_beginscan(fctx->lRel, SnapshotNow, 0, NULL); /*funcctx->tuple_desc= BlessTupleDesc(fctx->lRel->rd_att);*/ funcctx->tuple_desc=BlessTupleDesc(RelationNameGetTupleDesc("my_first_ta ble")); funcctx->user_fctx = fctx; MemoryContextSwitchTo(oldcontext); } funcctx = SRF_PERCALL_SETUP(); fctx = funcctx->user_fctx; HeapTuple tuple; tuple = heap_getnext(fctx->scan, ForwardScanDirection); if (HeapTupleIsValid(tuple)) { Datum result; Datum *values; HeapTuple tupleCopy; HeapTuple tupleCopy2; char *nulls = (char *)palloc(funcctx->tuple_desc->natts * sizeof(char)); tupleCopy = heap_copytuple(tuple); heap_deformtuple(tuple,funcctx->tuple_desc,values,nulls); tupleCopy2 = heap_formtuple(funcctx->tuple_desc,values,nulls); result = HeapTupleGetDatum(tupleCopy2); SRF_RETURN_NEXT(funcctx, result); } else /* do when there is no more left */ { heap_endscan(fctx->scan); heap_close(fctx->lRel, AccessShareLock); SRF_RETURN_DONE(funcctx); } } Regards, tzahi. > -----Original Message----- > From: Tom Lane [mailto:tgl@sss.pgh.pa.us] > Sent: Friday, January 07, 2005 10:31 PM > To: Tzahi Fadida > Cc: pgsql-general@postgresql.org > Subject: Re: [GENERAL] ERROR: cache lookup failed for type 0 > > > Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > > It still doesn't work. btw, I am using 8rc2. > > Um. The "clean" way to do this is to use BlessTupleDesc and > then heap_formtuple. That requires you to break down the > original tuple into fields (see heap_deformtuple). > Alternatively you could poke the datatype ID fields directly > into the copied tuple. > > regards, tom lane > >
Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > well, I tried the heap_deformtuple and I am getting now: > select testgetrows(); > server closed the connection unexpectedly You didn't palloc the values array. Any reasonable compiler would have warned you about that BTW. If you don't have compiler warnings enabled, learn to use them. Also, I'd recommend using the tupledesc from the just-opened lRel; fetching it via an independent path is just asking for trouble. regards, tom lane
returning a setof tuples like a subquery was(RE: ERROR: cache lookup failed for type 0 )
From
Tzahi Fadida
Date:
yes you were right it works now. 10x, sorry for the rookie mistake I jumped the gun on the last one. If you will i have another question on the same subject. I want to return a setof tuples without a predetermined return type like a subquery with a join, I don't want to specify a type. for example, new_join_alg_func(table1,table2). when I use SETOF RECORD I have to specify a type, same goes for anyelement. Regards, tzahi. > -----Original Message----- > From: pgsql-general-owner@postgresql.org > [mailto:pgsql-general-owner@postgresql.org] On Behalf Of Tom Lane > Sent: Saturday, January 08, 2005 12:24 AM > To: Tzahi Fadida > Cc: pgsql-general@postgresql.org > Subject: Re: [GENERAL] ERROR: cache lookup failed for type 0 > > > Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > > well, I tried the heap_deformtuple and I am getting now: select > > testgetrows(); server closed the connection unexpectedly > > You didn't palloc the values array. Any reasonable compiler > would have warned you about that BTW. If you don't have > compiler warnings enabled, learn to use them. > > Also, I'd recommend using the tupledesc from the just-opened > lRel; fetching it via an independent path is just asking for trouble. > > regards, tom lane > > ---------------------------(end of > broadcast)--------------------------- > TIP 7: don't forget to increase your free space map settings > >
Tom Lane <tgl@sss.pgh.pa.us> writes: > Tzahi Fadida <tzahi_ml@myrealbox.com> writes: > > well, I tried the heap_deformtuple and I am getting now: > > select testgetrows(); > > server closed the connection unexpectedly > > You didn't palloc the values array. Any reasonable compiler would have > warned you about that BTW. If you don't have compiler warnings enabled, > learn to use them. I think with gcc this type of warning is only enabled when you're compiling with optimizations. Most people don't compile with optimizations enabled when developing. -- greg
Greg Stark <gsstark@mit.edu> writes: > Tom Lane <tgl@sss.pgh.pa.us> writes: >> You didn't palloc the values array. Any reasonable compiler would have >> warned you about that BTW. If you don't have compiler warnings enabled, >> learn to use them. > I think with gcc this type of warning is only enabled when you're compiling > with optimizations. Most people don't compile with optimizations enabled when > developing. Pretty much the first thing you learn when developing with gcc is to use -O1 -Wall for compiling devel code. Gets all the warnings and doesn't confuse gdb too badly. Once in a long while I'll recompile an individual file with -O0 so that I can single-step through it more easily, but 99.44% of the time I'd rather have the uninitialized-variable warning. regards, tom lane