> Hope that helps to clarify the confusion.
>
Thanks for the explanation. Yes, it does clarify my doubt to some extent.
My point is, once we find the leaf page containing the given tid, we go through each item in the page until we find the data corresponding to the given tid which means we kind of perform a sequential scan at the page level. I'm referring to the below loop in zsbt_attr_scan_fetch_array().
for (off = FirstOffsetNumber; off <= maxoff; off++)
{
ItemId iid = PageGetItemId(page, off);
ZSAttributeArrayItem *item = (ZSAttributeArrayItem *) PageGetItem(page, iid);
if (item->t_endtid <= nexttid)
continue;
if (item->t_firsttid > nexttid)
break;But that's not true for IndexScan in case of heap table because there the index tuple contains the exact physical location of tuple in the heap. So, there is no need to scan the entire page.
Further here are some minor comments that i could find while doing a quick code walkthrough.
1) In zsundo_insert_finish(), there is a double call to BufferGetPage(undobuf); Is that required ?
2) In zedstoream_fetch_row(), why is zsbt_tid_begin_scan() being called twice? I'm referring to the below code.
if (fetch_proj->num_proj_atts == 0)
{
....
....
zsbt_tid_begin_scan(rel, tid, tid + 1,
snapshot,
&fetch_proj->tid_scan);
fetch_proj->tid_scan.serializable = true;
for (int i = 1; i < fetch_proj->num_proj_atts; i++)
{
int attno = fetch_proj->proj_atts[i];
zsbt_attr_begin_scan(rel, reldesc, attno,
&fetch_proj->attr_scans[i - 1]);
}
MemoryContextSwitchTo(oldcontext);
zsbt_tid_begin_scan(rel, tid, tid + 1, snapshot, &fetch_proj->tid_scan);
}
Also, for all types of update operation (be it key or non-key update) we create a new tid for the new version of tuple. Can't we use the tid associated with the old tuple for the cases where there is no concurrent transactions to whom the old tuple is still visible.
--
With Regards,
Ashutosh Sharma
EnterpriseDB:
http://www.enterprisedb.com