...as well as another bug described below.
So, Mark, you can use select order by for update now, 
but be aware that such queries may return unordered
data if sort-keys will be changed by concurrent xactions.

My hands are mostly away from sources now, though I still
get Assert in vacuum (FreeBSD 2.2.6) when run Hiroshi test.

Vadim

======================= CVS log message ==================

1. Fix for elog(ERROR, "EvalPlanQual: t_xmin is uncommitted ?!")
   and possibly for other cases too:
   
   DO NOT cache status of transaction in unknown state
   (i.e. non-committed and non-aborted ones)
   
   Example:
   T1 reads row updated/inserted by running T2 and cache T2 status.
   T2 commits.
   Now T1 reads a row updated by T2 and with HEAP_XMAX_COMMITTED
   in t_infomask (so cached T2 status is not changed).
   Now T1 EvalPlanQual gets updated row version without HEAP_XMIN_COMMITTED
   -> TransactionIdDidCommit(t_xmin) and TransactionIdDidAbort(t_xmin)
   return FALSE and T2 decides that t_xmin is not committed and gets
   ERROR above.
   
   It's too late to find more smart way to handle such cases and so
   I just changed xact status caching and got rid TransactionIdFlushCache()
   from code.
   
   Changed: transam.c, xact.c, lmgr.c and transam.h - last three
   just because of TransactionIdFlushCache() is removed.

2. heapam.c:

   T1 marked a row for update. T2 waits for T1 commit/abort.
   T1 commits. T3 updates the row before T2 locks row page.
   Now T2 sees that new row t_xmax is different from xact id (T1)
   T2 was waiting for. Old code did Assert here. New one goes to
   HeapTupleSatisfiesUpdate. Obvious changes too.

Thu, 10 Jun 1999 22:52:51 +0800
Vadim Mikheev <vadim@krs.ru>
elog(ERROR, "EvalPlanQual: t_xmin is uncommitted ?!") fixed