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

Поиск
Список
Период
Сортировка
От Georgi Kolev
Тема PQoidValue - get last ID of primary key after INSERT - small fix
Дата
Msg-id ebchh2$opp$1@sea.gmane.org
обсуждение исходный текст
Ответы Re: PQoidValue - get last ID of primary key after INSERT - small fix  (Tom Lane <tgl@sss.pgh.pa.us>)
Список 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);
 
}




В списке pgsql-interfaces по дате отправления:

Предыдущее
От: Andro
Дата:
Сообщение: Re: PQftype() and Oid
Следующее
От: Tom Lane
Дата:
Сообщение: Re: PQoidValue - get last ID of primary key after INSERT - small fix