From: Georgi Kolev <geo_kolev@mail.ru>
To: pgsql-interfaces@postgresql.org
Subject: PQoidValue - get last ID of primary key after INSERT - small fix
Date: Wed, 09 Aug 2006 14:38:24 +0300
Message-ID: <ebchh2$opp$1@sea.gmane.org> (raw)
Hi,
In psycopg2 the value of ID after INSERT statement is derived by
'cursor.lastrowid' attribute which in turn calls PQoidValue().
The easiest way to fix the problem were to fix heap_insert() to get the
right value in case there is no OID column declared in the table.
In case there is an OID, the function works the 'old' manner.
If there is no OID, we serach for PKEY column which is declared
'SERIAL' (at the moment I check the type to be 'int4').
I think the best way is to develop brand new functions PQid4Value and
PQid8Value similar to PQoidValue (or something else) to solve the whole
problem with SERIAL and BIGSERIAL.
Bellow is the piece of the code I have noticed. I can propose it as a
diff patch or else as needed. If there are some better ideas of fixing
the problem I will be very glad to discuss them :)
/backend/access/heap/heapam.c:1097
Oid
heap_insert(Relation relation, HeapTuple tup, CommandId cid,
bool use_wal, bool use_fsm)
{
...
if (!OidIsValid(HeapTupleGetOid(tup)))
{
TupleDesc tupdesc = RelationGetDescr(relation);
int natts = tupdesc->natts;
int varattno;
Form_pg_attribute att;
List *indexoidlist;
ListCell *indexoidscan;
indexoidlist = RelationGetIndexList(relation);
foreach(indexoidscan, indexoidlist)
{
Oid indexoid = lfirst_oid(indexoidscan);
HeapTuple indexTuple;
Form_pg_index indexStruct;
int i;
indexTuple = SearchSysCache(INDEXRELID,
ObjectIdGetDatum(indexoid),
0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "cache lookup failed for index %u", indexoid);
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
if (indexStruct->indisprimary && indexStruct->indnatts == 1)
{
for (varattno = 0; varattno < natts; varattno++)
{
att = tupdesc->attrs[varattno];
if (indexStruct->indkey.values[0] == att->attnum)
{
Oid typoid;
HeapTuple typeTuple;
char *atttype;
typoid = tupdesc->attrs[varattno]->atttypid;
typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(typoid),
0, 0, 0);
if (!HeapTupleIsValid(typeTuple))
return NULL;
atttype = pstrdup(NameStr(((Form_pg_type)
GETSTRUCT(typeTuple))->typname));
ReleaseSysCache(typeTuple);
if (strcmp(atttype, "int4")==0)
{
Datum origval;
bool isnull;
origval = heap_getattr(tup, varattno+1, tupdesc, &isnull);
ReleaseSysCache(indexTuple);
list_free(indexoidlist);
return DatumGetInt32(origval);
}
}
}
}
ReleaseSysCache(indexTuple);
}
list_free(indexoidlist);
}
return HeapTupleGetOid(tup);
}
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-interfaces@postgresql.org
Cc: geo_kolev@mail.ru
Subject: Re: PQoidValue - get last ID of primary key after INSERT - small fix
In-Reply-To: <ebchh2$opp$1@sea.gmane.org>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox