In WT-247 and WT-312, I pushed the cursor work in session.truncate down into the cursor layer, and at the same time, changed it to handle implicitly created records in column-store.
Michael comments:
> I saw that and wondered whether we should do this up in __session_truncate for all cursor types? You took out the search calls from there...
> To clarify a little, if I have records A, B, C, E, F in a table and call:
cursor->set_key(D); session->truncate(NULL, cursor, NULL, 0);
> This change means the call will work as expected for column stores but fail with WT_NOTFOUND for row stores. Maybe we should do the search_near in both cases – I think that is more likely what is expected?
> Regardless, this is a minor API detail and we can change it later.
Keith comments:
> I like this idea.
> I did this originally because fixing implicit records for column-store made me realize we documented that instantiating record 5 implicitly creates records 1-4, and so applications could reasonably use those records in subsequent session.truncate calls. I think your approach makes good sense, applications might reasonably truncate parts of the name-space without knowing exactly what's there. It could figure it out, of course, the application can call cursor.search_near as easily as we can, but consistency & simplicity are good things.
> Two questions:
> First, we always succeed then, and never return WT_NOTFOUND? So, if I have records A, B, and C in a table and call:
cursor.set_key(H); session->truncate(NULL, cursor, NULL, 0);
> it would succeed?
> Second, the problem with moving it into the session level is that we need some way to do cursor comparisons and the session level doesn't know how to do that. We'd have to export some cursor API up to that level?
> I'm happy to make & test this change if you want (although we have to talk about the second question, unless you just want to bite the bullet and offer cursor.compare which does a full comparison (as opposed to cursor.equal which does simple equality).
Michael comments:
> First, we always succeed then, and never return WT_NOTFOUND? So, if I have records A, B, and C in a table and call:
>
>
> cursor.set_key(H); > session->truncate(NULL, cursor, NULL, 0); >
>
> it would succeed?
I'd probably make this one fail with WT_NOTFOUND. I think that simplifies the code, anyway:
if (start != NULL) { WT_RET(start->search_near(start, &cmp)); if (cmp < 0) WT_RET(start->next(start)); }
> Second, the problem with moving it into the session level is that we need some way to do cursor comparisons and the session level doesn't know how to do that. We'd have to export some cursor API up to that level?
We get the cmp value out of search_near already, so we can figure out if we need a next/prev without anything new.
I guess you mean the error checking, that if start != NULL and stop != NULL, then start <= stop?
> I'm happy to make & test this change if you want (although we have to talk about the second question, unless you just want to bite the bullet and offer cursor.compare which does a full comparison (as opposed to cursor.equal which does simple equality).
I'm coming around to that (replacing WT_CURSOR->equals with WT_CURSOR->compare).
It's certainly better than having both equals and compare in the cursor API, and because of the way we do collators in the native API, there will never be the problem BDB has, where comparing records can be horrendously expensive (e.g., from Java).
If you happy to make that change, that would be great: thanks!