PQoidValue - get last ID of primary key after INSERT - small fix

From: Georgi Kolev <geo_kolev(at)mail(dot)ru>
To: pgsql-interfaces(at)postgresql(dot)org
Subject: PQoidValue - get last ID of primary key after INSERT - small fix
Date: 2006-08-09 11:38:24
Message-ID: ebchh2$opp$1@sea.gmane.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-interfaces

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);
}

Responses

Browse pgsql-interfaces by date

  From Date Subject
Next Message Tom Lane 2006-08-10 18:40:45 Re: PQoidValue - get last ID of primary key after INSERT - small fix
Previous Message Andro 2006-08-07 07:34:34 Re: PQftype() and Oid