SQLite Forum

Bug? Inside sqlite3CreateIndex. Maybe there is an incorrect code to move all REPLACE indexes to the end of the list.
Login

Bug? Inside sqlite3CreateIndex. Maybe there is an incorrect code to move all REPLACE indexes to the end of the list.

(1) By Oleg Bulatov (tibonarium) on 2021-03-21 12:32:47 updated by 1.1 [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](https://github.com/sqlite/sqlite/blob/master/src/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.
```c
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
```c
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;
  }
}
```

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 [link] [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.