Bug? Inside sqlite3CreateIndex. Maybe there is an incorrect code to move all REPLACE indexes to the end of the list.
(1.1) Originally by Oleg Bulatov (tibonarium) with edits by Richard Hipp (drh) on 2021-03-21 13:17:12 from 1.0 [source]
Hello,
I was reading through sqlite source code for educational purposes. And encountered something that I didn't quite understood. Maybe code or comment is incorrect. To demonstrate what I think the problem is I created this bitbucket project
https://bitbucket.org/tibonarium/list_move_to_end/src/master/
In the file build.c inside function sqlite3CreateIndex
there is a comment "Ensure all REPLACE indexes are at the end of the list". But this implementation will not move all elements with property onError=OE_Replace
to the end of the list.
if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */
Index **ppFrom = &pTab->pIndex;
Index *pThis;
for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){
Index *pNext;
if( pThis->onError!=OE_Replace ) continue;
while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){
*ppFrom = pNext;
pThis->pNext = pNext->pNext;
pNext->pNext = pThis;
ppFrom = &pNext->pNext;
}
break;
}
}
We can fix it this way
if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */
Index **ppFrom = &pTab->pIndex;
Index *pThis;
for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){
Index *pNext;
Index *pTail = pThis;
if( pThis->onError!=OE_Replace ) continue;
while( (pNext = pThis->pNext)!=0 ){
if (pNext->onError!=OE_Replace) {
*ppFrom = pNext;
pThis->pNext = pNext->pNext;
pNext->pNext = pTail;
ppFrom = &pNext->pNext;
} else {
pThis = pNext;
}
}
break;
}
}
(2) By Richard Hipp (drh) on 2021-03-21 18:25:03 in reply to 1.1 [link] [source]
The comment on this section of code is fixed to more accurately describe what it does in check-in 71e4da136bd1b5b7.