/ Check-in [924f4712]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge all the latest enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 924f471291dfd458307a11819aa640cc1a02ac63
User & Date: drh 2015-06-25 15:44:49
Context
2015-06-30
16:29
Merge all the latest enhancements from trunk. This merge include FTS5 and a number of notable performance enhancements. check-in: 39936b33 user: drh tags: sessions
2015-06-25
15:44
Merge all the latest enhancements from trunk. check-in: 924f4712 user: drh tags: sessions
15:21
Remove a NEVER() that is in fact reachable. check-in: f824e66b user: drh tags: trunk
2015-06-17
18:18
Merge all recent enhancements and fixes from trunk. check-in: 199bfb67 user: drh tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/spellfix.c.

  2650   2650     if( pCur->pFullScan ){
  2651   2651       *pRowid = sqlite3_column_int64(pCur->pFullScan, 4);
  2652   2652     }else{
  2653   2653       *pRowid = pCur->a[pCur->iRow].iRowid;
  2654   2654     }
  2655   2655     return SQLITE_OK;
  2656   2656   }
         2657  +
         2658  +/*
         2659  +** This function is called by the xUpdate() method. It returns a string
         2660  +** containing the conflict mode that xUpdate() should use for the current
         2661  +** operation. One of: "ROLLBACK", "IGNORE", "ABORT" or "REPLACE".
         2662  +*/
         2663  +static const char *spellfix1GetConflict(sqlite3 *db){
         2664  +  static const char *azConflict[] = {
         2665  +    /* Note: Instead of "FAIL" - "ABORT". */
         2666  +    "ROLLBACK", "IGNORE", "ABORT", "ABORT", "REPLACE"
         2667  +  };
         2668  +  int eConflict = sqlite3_vtab_on_conflict(db);
         2669  +
         2670  +  assert( eConflict==SQLITE_ROLLBACK || eConflict==SQLITE_IGNORE
         2671  +       || eConflict==SQLITE_FAIL || eConflict==SQLITE_ABORT
         2672  +       || eConflict==SQLITE_REPLACE
         2673  +  );
         2674  +  assert( SQLITE_ROLLBACK==1 );
         2675  +  assert( SQLITE_IGNORE==2 );
         2676  +  assert( SQLITE_FAIL==3 );
         2677  +  assert( SQLITE_ABORT==4 );
         2678  +  assert( SQLITE_REPLACE==5 );
         2679  +
         2680  +  return azConflict[eConflict-1];
         2681  +}
  2657   2682   
  2658   2683   /*
  2659   2684   ** The xUpdate() method.
  2660   2685   */
  2661   2686   static int spellfix1Update(
  2662   2687     sqlite3_vtab *pVTab,
  2663   2688     int argc,
................................................................................
  2682   2707       int iRank = sqlite3_value_int(argv[SPELLFIX_COL_RANK+2]);
  2683   2708       const unsigned char *zSoundslike =
  2684   2709              sqlite3_value_text(argv[SPELLFIX_COL_SOUNDSLIKE+2]);
  2685   2710       int nSoundslike = sqlite3_value_bytes(argv[SPELLFIX_COL_SOUNDSLIKE+2]);
  2686   2711       char *zK1, *zK2;
  2687   2712       int i;
  2688   2713       char c;
         2714  +    const char *zConflict = spellfix1GetConflict(db);
  2689   2715   
  2690   2716       if( zWord==0 ){
  2691   2717         /* Inserts of the form:  INSERT INTO table(command) VALUES('xyzzy');
  2692   2718         ** cause zWord to be NULL, so we look at the "command" column to see
  2693   2719         ** what special actions to take */
  2694   2720         const char *zCmd = 
  2695   2721            (const char*)sqlite3_value_text(argv[SPELLFIX_COL_COMMAND+2]);
................................................................................
  2742   2768                  "VALUES(%d,%d,%Q,%Q,%Q)",
  2743   2769                  p->zDbName, p->zTableName,
  2744   2770                  iRank, iLang, zWord, zK1, zK2
  2745   2771           );
  2746   2772         }else{
  2747   2773           newRowid = sqlite3_value_int64(argv[1]);
  2748   2774           spellfix1DbExec(&rc, db,
  2749         -               "INSERT INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
  2750         -               "VALUES(%lld,%d,%d,%Q,%Q,%Q)",
  2751         -               p->zDbName, p->zTableName,
  2752         -               newRowid, iRank, iLang, zWord, zK1, zK2
         2775  +            "INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
         2776  +            "VALUES(%lld,%d,%d,%Q,%Q,%Q)",
         2777  +            zConflict, p->zDbName, p->zTableName,
         2778  +            newRowid, iRank, iLang, zWord, zK1, zK2
  2753   2779           );
  2754   2780         }
  2755   2781         *pRowid = sqlite3_last_insert_rowid(db);
  2756   2782       }else{
  2757   2783         rowid = sqlite3_value_int64(argv[0]);
  2758   2784         newRowid = *pRowid = sqlite3_value_int64(argv[1]);
  2759   2785         spellfix1DbExec(&rc, db,
  2760         -             "UPDATE \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
         2786  +             "UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
  2761   2787                " word=%Q, k1=%Q, k2=%Q WHERE id=%lld",
  2762         -             p->zDbName, p->zTableName, newRowid, iRank, iLang,
         2788  +             zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang,
  2763   2789                zWord, zK1, zK2, rowid
  2764   2790         );
  2765   2791       }
  2766   2792       sqlite3_free(zK1);
  2767   2793       sqlite3_free(zK2);
  2768   2794     }
  2769   2795     return rc;

Changes to src/btree.c.

   486    486   */
   487    487   static void invalidateIncrblobCursors(
   488    488     Btree *pBtree,          /* The database file to check */
   489    489     i64 iRow,               /* The rowid that might be changing */
   490    490     int isClearTable        /* True if all rows are being deleted */
   491    491   ){
   492    492     BtCursor *p;
   493         -  BtShared *pBt = pBtree->pBt;
          493  +  if( pBtree->hasIncrblobCur==0 ) return;
   494    494     assert( sqlite3BtreeHoldsMutex(pBtree) );
   495         -  for(p=pBt->pCursor; p; p=p->pNext){
   496         -    if( (p->curFlags & BTCF_Incrblob)!=0
   497         -     && (isClearTable || p->info.nKey==iRow)
   498         -    ){
   499         -      p->eState = CURSOR_INVALID;
          495  +  pBtree->hasIncrblobCur = 0;
          496  +  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
          497  +    if( (p->curFlags & BTCF_Incrblob)!=0 ){
          498  +      pBtree->hasIncrblobCur = 1;
          499  +      if( isClearTable || p->info.nKey==iRow ){
          500  +        p->eState = CURSOR_INVALID;
          501  +      }
   500    502       }
   501    503     }
   502    504   }
   503    505   
   504    506   #else
   505    507     /* Stub function when INCRBLOB is omitted */
   506    508     #define invalidateIncrblobCursors(x,y,z)
................................................................................
   952    954   ** the page, 1 means the second cell, and so forth) return a pointer
   953    955   ** to the cell content.
   954    956   **
   955    957   ** This routine works only for pages that do not contain overflow cells.
   956    958   */
   957    959   #define findCell(P,I) \
   958    960     ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)])))
   959         -#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
   960         -
   961         -
   962         -/*
   963         -** This a more complex version of findCell() that works for
   964         -** pages that do contain overflow cells.
   965         -*/
   966         -static u8 *findOverflowCell(MemPage *pPage, int iCell){
   967         -  int i;
   968         -  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   969         -  for(i=pPage->nOverflow-1; i>=0; i--){
   970         -    int k;
   971         -    k = pPage->aiOvfl[i];
   972         -    if( k<=iCell ){
   973         -      if( k==iCell ){
   974         -        return pPage->apOvfl[i];
   975         -      }
   976         -      iCell--;
   977         -    }
   978         -  }
   979         -  return findCell(pPage, iCell);
   980         -}
   981         -
   982         -/*
   983         -** Parse a cell content block and fill in the CellInfo structure.  There
   984         -** are two versions of this function.  btreeParseCell() takes a 
   985         -** cell index as the second argument and btreeParseCellPtr() 
   986         -** takes a pointer to the body of the cell as its second argument.
   987         -*/
          961  +
          962  +/*
          963  +** This is common tail processing for btreeParseCellPtr() and
          964  +** btreeParseCellPtrIndex() for the case when the cell does not fit entirely
          965  +** on a single B-tree page.  Make necessary adjustments to the CellInfo
          966  +** structure.
          967  +*/
          968  +static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow(
          969  +  MemPage *pPage,         /* Page containing the cell */
          970  +  u8 *pCell,              /* Pointer to the cell text. */
          971  +  CellInfo *pInfo         /* Fill in this structure */
          972  +){
          973  +  /* If the payload will not fit completely on the local page, we have
          974  +  ** to decide how much to store locally and how much to spill onto
          975  +  ** overflow pages.  The strategy is to minimize the amount of unused
          976  +  ** space on overflow pages while keeping the amount of local storage
          977  +  ** in between minLocal and maxLocal.
          978  +  **
          979  +  ** Warning:  changing the way overflow payload is distributed in any
          980  +  ** way will result in an incompatible file format.
          981  +  */
          982  +  int minLocal;  /* Minimum amount of payload held locally */
          983  +  int maxLocal;  /* Maximum amount of payload held locally */
          984  +  int surplus;   /* Overflow payload available for local storage */
          985  +
          986  +  minLocal = pPage->minLocal;
          987  +  maxLocal = pPage->maxLocal;
          988  +  surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4);
          989  +  testcase( surplus==maxLocal );
          990  +  testcase( surplus==maxLocal+1 );
          991  +  if( surplus <= maxLocal ){
          992  +    pInfo->nLocal = (u16)surplus;
          993  +  }else{
          994  +    pInfo->nLocal = (u16)minLocal;
          995  +  }
          996  +  pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
          997  +  pInfo->nSize = pInfo->iOverflow + 4;
          998  +}
          999  +
         1000  +/*
         1001  +** The following routines are implementations of the MemPage.xParseCell()
         1002  +** method.
         1003  +**
         1004  +** Parse a cell content block and fill in the CellInfo structure.
         1005  +**
         1006  +** btreeParseCellPtr()        =>   table btree leaf nodes
         1007  +** btreeParseCellNoPayload()  =>   table btree internal nodes
         1008  +** btreeParseCellPtrIndex()   =>   index btree nodes
         1009  +**
         1010  +** There is also a wrapper function btreeParseCell() that works for
         1011  +** all MemPage types and that references the cell by index rather than
         1012  +** by pointer.
         1013  +*/
         1014  +static void btreeParseCellPtrNoPayload(
         1015  +  MemPage *pPage,         /* Page containing the cell */
         1016  +  u8 *pCell,              /* Pointer to the cell text. */
         1017  +  CellInfo *pInfo         /* Fill in this structure */
         1018  +){
         1019  +  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
         1020  +  assert( pPage->leaf==0 );
         1021  +  assert( pPage->noPayload );
         1022  +  assert( pPage->childPtrSize==4 );
         1023  +  pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
         1024  +  pInfo->nPayload = 0;
         1025  +  pInfo->nLocal = 0;
         1026  +  pInfo->iOverflow = 0;
         1027  +  pInfo->pPayload = 0;
         1028  +  return;
         1029  +}
   988   1030   static void btreeParseCellPtr(
         1031  +  MemPage *pPage,         /* Page containing the cell */
         1032  +  u8 *pCell,              /* Pointer to the cell text. */
         1033  +  CellInfo *pInfo         /* Fill in this structure */
         1034  +){
         1035  +  u8 *pIter;              /* For scanning through pCell */
         1036  +  u32 nPayload;           /* Number of bytes of cell payload */
         1037  +  u64 iKey;               /* Extracted Key value */
         1038  +
         1039  +  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
         1040  +  assert( pPage->leaf==0 || pPage->leaf==1 );
         1041  +  assert( pPage->intKeyLeaf || pPage->noPayload );
         1042  +  assert( pPage->noPayload==0 );
         1043  +  assert( pPage->intKeyLeaf );
         1044  +  assert( pPage->childPtrSize==0 );
         1045  +  pIter = pCell;
         1046  +
         1047  +  /* The next block of code is equivalent to:
         1048  +  **
         1049  +  **     pIter += getVarint32(pIter, nPayload);
         1050  +  **
         1051  +  ** The code is inlined to avoid a function call.
         1052  +  */
         1053  +  nPayload = *pIter;
         1054  +  if( nPayload>=0x80 ){
         1055  +    u8 *pEnd = &pIter[8];
         1056  +    nPayload &= 0x7f;
         1057  +    do{
         1058  +      nPayload = (nPayload<<7) | (*++pIter & 0x7f);
         1059  +    }while( (*pIter)>=0x80 && pIter<pEnd );
         1060  +  }
         1061  +  pIter++;
         1062  +
         1063  +  /* The next block of code is equivalent to:
         1064  +  **
         1065  +  **     pIter += getVarint(pIter, (u64*)&pInfo->nKey);
         1066  +  **
         1067  +  ** The code is inlined to avoid a function call.
         1068  +  */
         1069  +  iKey = *pIter;
         1070  +  if( iKey>=0x80 ){
         1071  +    u8 *pEnd = &pIter[7];
         1072  +    iKey &= 0x7f;
         1073  +    while(1){
         1074  +      iKey = (iKey<<7) | (*++pIter & 0x7f);
         1075  +      if( (*pIter)<0x80 ) break;
         1076  +      if( pIter>=pEnd ){
         1077  +        iKey = (iKey<<8) | *++pIter;
         1078  +        break;
         1079  +      }
         1080  +    }
         1081  +  }
         1082  +  pIter++;
         1083  +
         1084  +  pInfo->nKey = *(i64*)&iKey;
         1085  +  pInfo->nPayload = nPayload;
         1086  +  pInfo->pPayload = pIter;
         1087  +  testcase( nPayload==pPage->maxLocal );
         1088  +  testcase( nPayload==pPage->maxLocal+1 );
         1089  +  if( nPayload<=pPage->maxLocal ){
         1090  +    /* This is the (easy) common case where the entire payload fits
         1091  +    ** on the local page.  No overflow is required.
         1092  +    */
         1093  +    pInfo->nSize = nPayload + (u16)(pIter - pCell);
         1094  +    if( pInfo->nSize<4 ) pInfo->nSize = 4;
         1095  +    pInfo->nLocal = (u16)nPayload;
         1096  +    pInfo->iOverflow = 0;
         1097  +  }else{
         1098  +    btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
         1099  +  }
         1100  +}
         1101  +static void btreeParseCellPtrIndex(
   989   1102     MemPage *pPage,         /* Page containing the cell */
   990   1103     u8 *pCell,              /* Pointer to the cell text. */
   991   1104     CellInfo *pInfo         /* Fill in this structure */
   992   1105   ){
   993   1106     u8 *pIter;              /* For scanning through pCell */
   994   1107     u32 nPayload;           /* Number of bytes of cell payload */
   995   1108   
   996   1109     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   997   1110     assert( pPage->leaf==0 || pPage->leaf==1 );
   998         -  if( pPage->intKeyLeaf ){
   999         -    assert( pPage->childPtrSize==0 );
  1000         -    pIter = pCell + getVarint32(pCell, nPayload);
  1001         -    pIter += getVarint(pIter, (u64*)&pInfo->nKey);
  1002         -  }else if( pPage->noPayload ){
  1003         -    assert( pPage->childPtrSize==4 );
  1004         -    pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
  1005         -    pInfo->nPayload = 0;
  1006         -    pInfo->nLocal = 0;
  1007         -    pInfo->iOverflow = 0;
  1008         -    pInfo->pPayload = 0;
  1009         -    return;
  1010         -  }else{
  1011         -    pIter = pCell + pPage->childPtrSize;
  1012         -    pIter += getVarint32(pIter, nPayload);
  1013         -    pInfo->nKey = nPayload;
         1111  +  assert( pPage->intKeyLeaf==0 );
         1112  +  assert( pPage->noPayload==0 );
         1113  +  pIter = pCell + pPage->childPtrSize;
         1114  +  nPayload = *pIter;
         1115  +  if( nPayload>=0x80 ){
         1116  +    u8 *pEnd = &pIter[8];
         1117  +    nPayload &= 0x7f;
         1118  +    do{
         1119  +      nPayload = (nPayload<<7) | (*++pIter & 0x7f);
         1120  +    }while( *(pIter)>=0x80 && pIter<pEnd );
  1014   1121     }
         1122  +  pIter++;
         1123  +  pInfo->nKey = nPayload;
  1015   1124     pInfo->nPayload = nPayload;
  1016   1125     pInfo->pPayload = pIter;
  1017   1126     testcase( nPayload==pPage->maxLocal );
  1018   1127     testcase( nPayload==pPage->maxLocal+1 );
  1019   1128     if( nPayload<=pPage->maxLocal ){
  1020   1129       /* This is the (easy) common case where the entire payload fits
  1021   1130       ** on the local page.  No overflow is required.
  1022   1131       */
  1023   1132       pInfo->nSize = nPayload + (u16)(pIter - pCell);
  1024   1133       if( pInfo->nSize<4 ) pInfo->nSize = 4;
  1025   1134       pInfo->nLocal = (u16)nPayload;
  1026   1135       pInfo->iOverflow = 0;
  1027   1136     }else{
  1028         -    /* If the payload will not fit completely on the local page, we have
  1029         -    ** to decide how much to store locally and how much to spill onto
  1030         -    ** overflow pages.  The strategy is to minimize the amount of unused
  1031         -    ** space on overflow pages while keeping the amount of local storage
  1032         -    ** in between minLocal and maxLocal.
  1033         -    **
  1034         -    ** Warning:  changing the way overflow payload is distributed in any
  1035         -    ** way will result in an incompatible file format.
  1036         -    */
  1037         -    int minLocal;  /* Minimum amount of payload held locally */
  1038         -    int maxLocal;  /* Maximum amount of payload held locally */
  1039         -    int surplus;   /* Overflow payload available for local storage */
  1040         -
  1041         -    minLocal = pPage->minLocal;
  1042         -    maxLocal = pPage->maxLocal;
  1043         -    surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
  1044         -    testcase( surplus==maxLocal );
  1045         -    testcase( surplus==maxLocal+1 );
  1046         -    if( surplus <= maxLocal ){
  1047         -      pInfo->nLocal = (u16)surplus;
  1048         -    }else{
  1049         -      pInfo->nLocal = (u16)minLocal;
  1050         -    }
  1051         -    pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
  1052         -    pInfo->nSize = pInfo->iOverflow + 4;
         1137  +    btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo);
  1053   1138     }
  1054   1139   }
  1055   1140   static void btreeParseCell(
  1056   1141     MemPage *pPage,         /* Page containing the cell */
  1057   1142     int iCell,              /* The cell index.  First cell is 0 */
  1058   1143     CellInfo *pInfo         /* Fill in this structure */
  1059   1144   ){
  1060         -  btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
         1145  +  pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo);
  1061   1146   }
  1062   1147   
  1063   1148   /*
         1149  +** The following routines are implementations of the MemPage.xCellSize
         1150  +** method.
         1151  +**
  1064   1152   ** Compute the total number of bytes that a Cell needs in the cell
  1065   1153   ** data area of the btree-page.  The return number includes the cell
  1066   1154   ** data header and the local payload, but not any overflow page or
  1067   1155   ** the space used by the cell pointer.
         1156  +**
         1157  +** cellSizePtrNoPayload()    =>   table internal nodes
         1158  +** cellSizePtr()             =>   all index nodes & table leaf nodes
  1068   1159   */
  1069   1160   static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
  1070   1161     u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
  1071   1162     u8 *pEnd;                                /* End mark for a varint */
  1072   1163     u32 nSize;                               /* Size value to return */
  1073   1164   
  1074   1165   #ifdef SQLITE_DEBUG
  1075   1166     /* The value returned by this function should always be the same as
  1076   1167     ** the (CellInfo.nSize) value found by doing a full parse of the
  1077   1168     ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
  1078   1169     ** this function verifies that this invariant is not violated. */
  1079   1170     CellInfo debuginfo;
  1080         -  btreeParseCellPtr(pPage, pCell, &debuginfo);
         1171  +  pPage->xParseCell(pPage, pCell, &debuginfo);
  1081   1172   #endif
  1082   1173   
  1083         -  if( pPage->noPayload ){
  1084         -    pEnd = &pIter[9];
  1085         -    while( (*pIter++)&0x80 && pIter<pEnd );
  1086         -    assert( pPage->childPtrSize==4 );
  1087         -    return (u16)(pIter - pCell);
  1088         -  }
         1174  +  assert( pPage->noPayload==0 );
  1089   1175     nSize = *pIter;
  1090   1176     if( nSize>=0x80 ){
  1091         -    pEnd = &pIter[9];
         1177  +    pEnd = &pIter[8];
  1092   1178       nSize &= 0x7f;
  1093   1179       do{
  1094   1180         nSize = (nSize<<7) | (*++pIter & 0x7f);
  1095   1181       }while( *(pIter)>=0x80 && pIter<pEnd );
  1096   1182     }
  1097   1183     pIter++;
  1098   1184     if( pPage->intKey ){
................................................................................
  1116   1202         nSize = minLocal;
  1117   1203       }
  1118   1204       nSize += 4 + (u16)(pIter - pCell);
  1119   1205     }
  1120   1206     assert( nSize==debuginfo.nSize || CORRUPT_DB );
  1121   1207     return (u16)nSize;
  1122   1208   }
         1209  +static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){
         1210  +  u8 *pIter = pCell + 4; /* For looping over bytes of pCell */
         1211  +  u8 *pEnd;              /* End mark for a varint */
         1212  +
         1213  +#ifdef SQLITE_DEBUG
         1214  +  /* The value returned by this function should always be the same as
         1215  +  ** the (CellInfo.nSize) value found by doing a full parse of the
         1216  +  ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
         1217  +  ** this function verifies that this invariant is not violated. */
         1218  +  CellInfo debuginfo;
         1219  +  pPage->xParseCell(pPage, pCell, &debuginfo);
         1220  +#endif
         1221  +
         1222  +  assert( pPage->childPtrSize==4 );
         1223  +  pEnd = pIter + 9;
         1224  +  while( (*pIter++)&0x80 && pIter<pEnd );
         1225  +  assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
         1226  +  return (u16)(pIter - pCell);
         1227  +}
         1228  +
  1123   1229   
  1124   1230   #ifdef SQLITE_DEBUG
  1125   1231   /* This variation on cellSizePtr() is used inside of assert() statements
  1126   1232   ** only. */
  1127   1233   static u16 cellSize(MemPage *pPage, int iCell){
  1128         -  return cellSizePtr(pPage, findCell(pPage, iCell));
         1234  +  return pPage->xCellSize(pPage, findCell(pPage, iCell));
  1129   1235   }
  1130   1236   #endif
  1131   1237   
  1132   1238   #ifndef SQLITE_OMIT_AUTOVACUUM
  1133   1239   /*
  1134   1240   ** If the cell pCell, part of page pPage contains a pointer
  1135   1241   ** to an overflow page, insert an entry into the pointer-map
  1136   1242   ** for the overflow page.
  1137   1243   */
  1138   1244   static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
  1139   1245     CellInfo info;
  1140   1246     if( *pRC ) return;
  1141   1247     assert( pCell!=0 );
  1142         -  btreeParseCellPtr(pPage, pCell, &info);
         1248  +  pPage->xParseCell(pPage, pCell, &info);
  1143   1249     if( info.iOverflow ){
  1144   1250       Pgno ovfl = get4byte(&pCell[info.iOverflow]);
  1145   1251       ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
  1146   1252     }
  1147   1253   }
  1148   1254   #endif
  1149   1255   
................................................................................
  1199   1305       /* These conditions have already been verified in btreeInitPage()
  1200   1306       ** if PRAGMA cell_size_check=ON.
  1201   1307       */
  1202   1308       if( pc<iCellFirst || pc>iCellLast ){
  1203   1309         return SQLITE_CORRUPT_BKPT;
  1204   1310       }
  1205   1311       assert( pc>=iCellFirst && pc<=iCellLast );
  1206         -    size = cellSizePtr(pPage, &src[pc]);
         1312  +    size = pPage->xCellSize(pPage, &src[pc]);
  1207   1313       cbrk -= size;
  1208   1314       if( cbrk<iCellFirst || pc+size>usableSize ){
  1209   1315         return SQLITE_CORRUPT_BKPT;
  1210   1316       }
  1211   1317       assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
  1212   1318       testcase( cbrk+size==usableSize );
  1213   1319       testcase( pc+size==usableSize );
................................................................................
  1330   1436     gap = pPage->cellOffset + 2*pPage->nCell;
  1331   1437     assert( gap<=65536 );
  1332   1438     /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
  1333   1439     ** and the reserved space is zero (the usual value for reserved space)
  1334   1440     ** then the cell content offset of an empty page wants to be 65536.
  1335   1441     ** However, that integer is too large to be stored in a 2-byte unsigned
  1336   1442     ** integer, so a value of 0 is used in its place. */
  1337         -  top = get2byteNotZero(&data[hdr+5]);
  1338         -  if( gap>top || NEVER((u32)top>pPage->pBt->usableSize) ){
  1339         -    /* The NEVER() is because a oversize "top" value will be blocked from
  1340         -    ** reaching this point by btreeInitPage() or btreeGetUnusedPage() */
  1341         -    return SQLITE_CORRUPT_BKPT;
         1443  +  top = get2byte(&data[hdr+5]);
         1444  +  assert( top<=pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
         1445  +  if( gap>top ){
         1446  +    if( top==0 && pPage->pBt->usableSize==65536 ){
         1447  +      top = 65536;
         1448  +    }else{
         1449  +      return SQLITE_CORRUPT_BKPT;
         1450  +    }
  1342   1451     }
  1343   1452   
  1344   1453     /* If there is enough space between gap and top for one more cell pointer
  1345   1454     ** array entry offset, and if the freelist is not empty, then search the
  1346   1455     ** freelist looking for a free slot big enough to satisfy the request.
  1347   1456     */
  1348   1457     testcase( gap+2==top );
................................................................................
  1503   1612     BtShared *pBt;     /* A copy of pPage->pBt */
  1504   1613   
  1505   1614     assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  1506   1615     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  1507   1616     pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
  1508   1617     flagByte &= ~PTF_LEAF;
  1509   1618     pPage->childPtrSize = 4-4*pPage->leaf;
         1619  +  pPage->xCellSize = cellSizePtr;
  1510   1620     pBt = pPage->pBt;
  1511   1621     if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
  1512   1622       /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
  1513   1623       ** table b-tree page. */
  1514   1624       assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
  1515   1625       /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
  1516   1626       ** table b-tree page. */
  1517   1627       assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
  1518   1628       pPage->intKey = 1;
  1519         -    pPage->intKeyLeaf = pPage->leaf;
  1520         -    pPage->noPayload = !pPage->leaf;
         1629  +    if( pPage->leaf ){
         1630  +      pPage->intKeyLeaf = 1;
         1631  +      pPage->noPayload = 0;
         1632  +      pPage->xParseCell = btreeParseCellPtr;
         1633  +    }else{
         1634  +      pPage->intKeyLeaf = 0;
         1635  +      pPage->noPayload = 1;
         1636  +      pPage->xCellSize = cellSizePtrNoPayload;
         1637  +      pPage->xParseCell = btreeParseCellPtrNoPayload;
         1638  +    }
  1521   1639       pPage->maxLocal = pBt->maxLeaf;
  1522   1640       pPage->minLocal = pBt->minLeaf;
  1523   1641     }else if( flagByte==PTF_ZERODATA ){
  1524   1642       /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
  1525   1643       ** index b-tree page. */
  1526   1644       assert( (PTF_ZERODATA)==2 );
  1527   1645       /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
  1528   1646       ** index b-tree page. */
  1529   1647       assert( (PTF_ZERODATA|PTF_LEAF)==10 );
  1530   1648       pPage->intKey = 0;
  1531   1649       pPage->intKeyLeaf = 0;
  1532   1650       pPage->noPayload = 0;
         1651  +    pPage->xParseCell = btreeParseCellPtrIndex;
  1533   1652       pPage->maxLocal = pBt->maxLocal;
  1534   1653       pPage->minLocal = pBt->minLocal;
  1535   1654     }else{
  1536   1655       /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
  1537   1656       ** an error. */
  1538   1657       return SQLITE_CORRUPT_BKPT;
  1539   1658     }
................................................................................
  1620   1739         for(i=0; i<pPage->nCell; i++){
  1621   1740           pc = get2byte(&data[cellOffset+i*2]);
  1622   1741           testcase( pc==iCellFirst );
  1623   1742           testcase( pc==iCellLast );
  1624   1743           if( pc<iCellFirst || pc>iCellLast ){
  1625   1744             return SQLITE_CORRUPT_BKPT;
  1626   1745           }
  1627         -        sz = cellSizePtr(pPage, &data[pc]);
         1746  +        sz = pPage->xCellSize(pPage, &data[pc]);
  1628   1747           testcase( pc+sz==usableSize );
  1629   1748           if( pc+sz>usableSize ){
  1630   1749             return SQLITE_CORRUPT_BKPT;
  1631   1750           }
  1632   1751         }
  1633   1752         if( !pPage->leaf ) iCellLast++;
  1634   1753       }  
................................................................................
  3116   3235       if( rc ) return rc;
  3117   3236       nCell = pPage->nCell;
  3118   3237   
  3119   3238       for(i=0; i<nCell; i++){
  3120   3239         u8 *pCell = findCell(pPage, i);
  3121   3240         if( eType==PTRMAP_OVERFLOW1 ){
  3122   3241           CellInfo info;
  3123         -        btreeParseCellPtr(pPage, pCell, &info);
         3242  +        pPage->xParseCell(pPage, pCell, &info);
  3124   3243           if( info.iOverflow
  3125   3244            && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
  3126   3245            && iFrom==get4byte(&pCell[info.iOverflow])
  3127   3246           ){
  3128   3247             put4byte(&pCell[info.iOverflow], iTo);
  3129   3248             break;
  3130   3249           }
................................................................................
  4961   5080             **
  4962   5081             ** If the record is corrupt, the xRecordCompare routine may read
  4963   5082             ** up to two varints past the end of the buffer. An extra 18 
  4964   5083             ** bytes of padding is allocated at the end of the buffer in
  4965   5084             ** case this happens.  */
  4966   5085             void *pCellKey;
  4967   5086             u8 * const pCellBody = pCell - pPage->childPtrSize;
  4968         -          btreeParseCellPtr(pPage, pCellBody, &pCur->info);
         5087  +          pPage->xParseCell(pPage, pCellBody, &pCur->info);
  4969   5088             nCell = (int)pCur->info.nKey;
  4970   5089             testcase( nCell<0 );   /* True if key size is 2^32 or more */
  4971   5090             testcase( nCell==0 );  /* Invalid key size:  0x80 0x80 0x00 */
  4972   5091             testcase( nCell==1 );  /* Invalid key size:  0x80 0x80 0x01 */
  4973   5092             testcase( nCell==2 );  /* Minimum legal index key size */
  4974   5093             if( nCell<2 ){
  4975   5094               rc = SQLITE_CORRUPT_BKPT;
................................................................................
  5307   5426     if( n>=mxPage ){
  5308   5427       return SQLITE_CORRUPT_BKPT;
  5309   5428     }
  5310   5429     if( n>0 ){
  5311   5430       /* There are pages on the freelist.  Reuse one of those pages. */
  5312   5431       Pgno iTrunk;
  5313   5432       u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
         5433  +    u32 nSearch = 0;   /* Count of the number of search attempts */
  5314   5434       
  5315   5435       /* If eMode==BTALLOC_EXACT and a query of the pointer-map
  5316   5436       ** shows that the page 'nearby' is somewhere on the free-list, then
  5317   5437       ** the entire-list will be searched for that page.
  5318   5438       */
  5319   5439   #ifndef SQLITE_OMIT_AUTOVACUUM
  5320   5440       if( eMode==BTALLOC_EXACT ){
................................................................................
  5355   5475         }else{
  5356   5476           /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32
  5357   5477           ** stores the page number of the first page of the freelist, or zero if
  5358   5478           ** the freelist is empty. */
  5359   5479           iTrunk = get4byte(&pPage1->aData[32]);
  5360   5480         }
  5361   5481         testcase( iTrunk==mxPage );
  5362         -      if( iTrunk>mxPage ){
         5482  +      if( iTrunk>mxPage || nSearch++ > n ){
  5363   5483           rc = SQLITE_CORRUPT_BKPT;
  5364   5484         }else{
  5365   5485           rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
  5366   5486         }
  5367   5487         if( rc ){
  5368   5488           pTrunk = 0;
  5369   5489           goto end_allocate_page;
................................................................................
  5750   5870     CellInfo info;
  5751   5871     Pgno ovflPgno;
  5752   5872     int rc;
  5753   5873     int nOvfl;
  5754   5874     u32 ovflPageSize;
  5755   5875   
  5756   5876     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5757         -  btreeParseCellPtr(pPage, pCell, &info);
         5877  +  pPage->xParseCell(pPage, pCell, &info);
  5758   5878     *pnSize = info.nSize;
  5759   5879     if( info.iOverflow==0 ){
  5760   5880       return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  5761   5881     }
  5762   5882     if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
  5763   5883       return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  5764   5884     }
................................................................................
  5904   6024     **
  5905   6025     ** Use a call to btreeParseCellPtr() to verify that the values above
  5906   6026     ** were computed correctly.
  5907   6027     */
  5908   6028   #if SQLITE_DEBUG
  5909   6029     {
  5910   6030       CellInfo info;
  5911         -    btreeParseCellPtr(pPage, pCell, &info);
         6031  +    pPage->xParseCell(pPage, pCell, &info);
  5912   6032       assert( nHeader=(int)(info.pPayload - pCell) );
  5913   6033       assert( info.nKey==nKey );
  5914   6034       assert( *pnSize == info.nSize );
  5915   6035       assert( spaceLeft == info.nLocal );
  5916   6036       assert( pPrior == &pCell[info.iOverflow] );
  5917   6037     }
  5918   6038   #endif
................................................................................
  6092   6212     assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
  6093   6213     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  6094   6214     /* The cell should normally be sized correctly.  However, when moving a
  6095   6215     ** malformed cell from a leaf page to an interior page, if the cell size
  6096   6216     ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  6097   6217     ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
  6098   6218     ** the term after the || in the following assert(). */
  6099         -  assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
         6219  +  assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
  6100   6220     if( pPage->nOverflow || sz+2>pPage->nFree ){
  6101   6221       if( pTemp ){
  6102   6222         memcpy(pTemp, pCell, sz);
  6103   6223         pCell = pTemp;
  6104   6224       }
  6105   6225       if( iChild ){
  6106   6226         put4byte(pCell, iChild);
  6107   6227       }
  6108   6228       j = pPage->nOverflow++;
  6109   6229       assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
  6110   6230       pPage->apOvfl[j] = pCell;
  6111   6231       pPage->aiOvfl[j] = (u16)i;
         6232  +
         6233  +    /* When multiple overflows occur, they are always sequential and in
         6234  +    ** sorted order.  This invariants arise because multiple overflows can
         6235  +    ** only occur when inserting divider cells into the parent page during
         6236  +    ** balancing, and the dividers are adjacent and sorted.
         6237  +    */
         6238  +    assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */
         6239  +    assert( j==0 || i==pPage->aiOvfl[j-1]+1 );   /* Overflows are sequential */
  6112   6240     }else{
  6113   6241       int rc = sqlite3PagerWrite(pPage->pDbPage);
  6114   6242       if( rc!=SQLITE_OK ){
  6115   6243         *pRC = rc;
  6116   6244         return;
  6117   6245       }
  6118   6246       assert( sqlite3PagerIswriteable(pPage->pDbPage) );
................................................................................
  6141   6269         ** the entry for the overflow page into the pointer map.
  6142   6270         */
  6143   6271         ptrmapPutOvflPtr(pPage, pCell, pRC);
  6144   6272       }
  6145   6273   #endif
  6146   6274     }
  6147   6275   }
         6276  +
         6277  +/*
         6278  +** A CellArray object contains a cache of pointers and sizes for a
         6279  +** consecutive sequence of cells that might be held multiple pages.
         6280  +*/
         6281  +typedef struct CellArray CellArray;
         6282  +struct CellArray {
         6283  +  int nCell;              /* Number of cells in apCell[] */
         6284  +  MemPage *pRef;          /* Reference page */
         6285  +  u8 **apCell;            /* All cells begin balanced */
         6286  +  u16 *szCell;            /* Local size of all cells in apCell[] */
         6287  +};
         6288  +
         6289  +/*
         6290  +** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been
         6291  +** computed.
         6292  +*/
         6293  +static void populateCellCache(CellArray *p, int idx, int N){
         6294  +  assert( idx>=0 && idx+N<=p->nCell );
         6295  +  while( N>0 ){
         6296  +    assert( p->apCell[idx]!=0 );
         6297  +    if( p->szCell[idx]==0 ){
         6298  +      p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]);
         6299  +    }else{
         6300  +      assert( CORRUPT_DB ||
         6301  +              p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) );
         6302  +    }
         6303  +    idx++;
         6304  +    N--;
         6305  +  }
         6306  +}
         6307  +
         6308  +/*
         6309  +** Return the size of the Nth element of the cell array
         6310  +*/
         6311  +static SQLITE_NOINLINE u16 computeCellSize(CellArray *p, int N){
         6312  +  assert( N>=0 && N<p->nCell );
         6313  +  assert( p->szCell[N]==0 );
         6314  +  p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]);
         6315  +  return p->szCell[N];
         6316  +}
         6317  +static u16 cachedCellSize(CellArray *p, int N){
         6318  +  assert( N>=0 && N<p->nCell );
         6319  +  if( p->szCell[N] ) return p->szCell[N];
         6320  +  return computeCellSize(p, N);
         6321  +}
  6148   6322   
  6149   6323   /*
  6150   6324   ** Array apCell[] contains pointers to nCell b-tree page cells. The 
  6151   6325   ** szCell[] array contains the size in bytes of each cell. This function
  6152   6326   ** replaces the current contents of page pPg with the contents of the cell
  6153   6327   ** array.
  6154   6328   **
................................................................................
  6155   6329   ** Some of the cells in apCell[] may currently be stored in pPg. This
  6156   6330   ** function works around problems caused by this by making a copy of any 
  6157   6331   ** such cells before overwriting the page data.
  6158   6332   **
  6159   6333   ** The MemPage.nFree field is invalidated by this function. It is the 
  6160   6334   ** responsibility of the caller to set it correctly.
  6161   6335   */
  6162         -static void rebuildPage(
         6336  +static int rebuildPage(
  6163   6337     MemPage *pPg,                   /* Edit this page */
  6164   6338     int nCell,                      /* Final number of cells on page */
  6165   6339     u8 **apCell,                    /* Array of cells */
  6166   6340     u16 *szCell                     /* Array of cell sizes */
  6167   6341   ){
  6168   6342     const int hdr = pPg->hdrOffset;          /* Offset of header on pPg */
  6169   6343     u8 * const aData = pPg->aData;           /* Pointer to data for pPg */
................................................................................
  6180   6354     pData = pEnd;
  6181   6355     for(i=0; i<nCell; i++){
  6182   6356       u8 *pCell = apCell[i];
  6183   6357       if( pCell>aData && pCell<pEnd ){
  6184   6358         pCell = &pTmp[pCell - aData];
  6185   6359       }
  6186   6360       pData -= szCell[i];
  6187         -    memcpy(pData, pCell, szCell[i]);
  6188   6361       put2byte(pCellptr, (pData - aData));
  6189   6362       pCellptr += 2;
  6190         -    assert( szCell[i]==cellSizePtr(pPg, pCell) || CORRUPT_DB );
  6191         -    testcase( szCell[i]==cellSizePtr(pPg,pCell) );
         6363  +    if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
         6364  +    memcpy(pData, pCell, szCell[i]);
         6365  +    assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
         6366  +    testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) );
  6192   6367     }
  6193   6368   
  6194   6369     /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
  6195   6370     pPg->nCell = nCell;
  6196   6371     pPg->nOverflow = 0;
  6197   6372   
  6198   6373     put2byte(&aData[hdr+1], 0);
  6199   6374     put2byte(&aData[hdr+3], pPg->nCell);
  6200   6375     put2byte(&aData[hdr+5], pData - aData);
  6201   6376     aData[hdr+7] = 0x00;
         6377  +  return SQLITE_OK;
  6202   6378   }
  6203   6379   
  6204   6380   /*
  6205   6381   ** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
  6206   6382   ** contains the size in bytes of each such cell. This function attempts to 
  6207   6383   ** add the cells stored in the array to page pPg. If it cannot (because 
  6208   6384   ** the page needs to be defragmented before the cells will fit), non-zero
................................................................................
  6227   6403   ** cells in apCell[], then the cells do not fit and non-zero is returned.
  6228   6404   */
  6229   6405   static int pageInsertArray(
  6230   6406     MemPage *pPg,                   /* Page to add cells to */
  6231   6407     u8 *pBegin,                     /* End of cell-pointer array */
  6232   6408     u8 **ppData,                    /* IN/OUT: Page content -area pointer */
  6233   6409     u8 *pCellptr,                   /* Pointer to cell-pointer area */
         6410  +  int iFirst,                     /* Index of first cell to add */
  6234   6411     int nCell,                      /* Number of cells to add to pPg */
  6235         -  u8 **apCell,                    /* Array of cells */
  6236         -  u16 *szCell                     /* Array of cell sizes */
         6412  +  CellArray *pCArray              /* Array of cells */
  6237   6413   ){
  6238   6414     int i;
  6239   6415     u8 *aData = pPg->aData;
  6240   6416     u8 *pData = *ppData;
  6241   6417     const int bFreelist = aData[1] || aData[2];
         6418  +  int iEnd = iFirst + nCell;
  6242   6419     assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
  6243         -  for(i=0; i<nCell; i++){
  6244         -    int sz = szCell[i];
  6245         -    int rc;
         6420  +  for(i=iFirst; i<iEnd; i++){
         6421  +    int sz, rc;
  6246   6422       u8 *pSlot;
         6423  +    sz = cachedCellSize(pCArray, i);
  6247   6424       if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, &rc, 0))==0 ){
  6248   6425         pData -= sz;
  6249   6426         if( pData<pBegin ) return 1;
  6250   6427         pSlot = pData;
  6251   6428       }
  6252         -    memcpy(pSlot, apCell[i], sz);
         6429  +    memcpy(pSlot, pCArray->apCell[i], sz);
  6253   6430       put2byte(pCellptr, (pSlot - aData));
  6254   6431       pCellptr += 2;
  6255   6432     }
  6256   6433     *ppData = pData;
  6257   6434     return 0;
  6258   6435   }
  6259   6436   
................................................................................
  6264   6441   ** within the body of pPg to the pPg free-list. The cell-pointers and other
  6265   6442   ** fields of the page are not updated.
  6266   6443   **
  6267   6444   ** This function returns the total number of cells added to the free-list.
  6268   6445   */
  6269   6446   static int pageFreeArray(
  6270   6447     MemPage *pPg,                   /* Page to edit */
         6448  +  int iFirst,                     /* First cell to delete */
  6271   6449     int nCell,                      /* Cells to delete */
  6272         -  u8 **apCell,                    /* Array of cells */
  6273         -  u16 *szCell                     /* Array of cell sizes */
         6450  +  CellArray *pCArray              /* Array of cells */
  6274   6451   ){
  6275   6452     u8 * const aData = pPg->aData;
  6276   6453     u8 * const pEnd = &aData[pPg->pBt->usableSize];
  6277   6454     u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  6278   6455     int nRet = 0;
  6279   6456     int i;
         6457  +  int iEnd = iFirst + nCell;
  6280   6458     u8 *pFree = 0;
  6281   6459     int szFree = 0;
  6282   6460   
  6283         -  for(i=0; i<nCell; i++){
  6284         -    u8 *pCell = apCell[i];
         6461  +  for(i=iFirst; i<iEnd; i++){
         6462  +    u8 *pCell = pCArray->apCell[i];
  6285   6463       if( pCell>=pStart && pCell<pEnd ){
  6286         -      int sz = szCell[i];
         6464  +      int sz;
         6465  +      /* No need to use cachedCellSize() here.  The sizes of all cells that
         6466  +      ** are to be freed have already been computing while deciding which
         6467  +      ** cells need freeing */
         6468  +      sz = pCArray->szCell[i];  assert( sz>0 );
  6287   6469         if( pFree!=(pCell + sz) ){
  6288   6470           if( pFree ){
  6289   6471             assert( pFree>aData && (pFree - aData)<65536 );
  6290   6472             freeSpace(pPg, (u16)(pFree - aData), szFree);
  6291   6473           }
  6292   6474           pFree = pCell;
  6293   6475           szFree = sz;
................................................................................
  6314   6496   **
  6315   6497   ** This routine makes the necessary adjustments to pPg so that it contains
  6316   6498   ** the correct cells after being balanced.
  6317   6499   **
  6318   6500   ** The pPg->nFree field is invalid when this function returns. It is the
  6319   6501   ** responsibility of the caller to set it correctly.
  6320   6502   */
  6321         -static void editPage(
         6503  +static int editPage(
  6322   6504     MemPage *pPg,                   /* Edit this page */
  6323   6505     int iOld,                       /* Index of first cell currently on page */
  6324   6506     int iNew,                       /* Index of new first cell on page */
  6325   6507     int nNew,                       /* Final number of cells on page */
  6326         -  u8 **apCell,                    /* Array of cells */
  6327         -  u16 *szCell                     /* Array of cell sizes */
         6508  +  CellArray *pCArray              /* Array of cells and sizes */
  6328   6509   ){
  6329   6510     u8 * const aData = pPg->aData;
  6330   6511     const int hdr = pPg->hdrOffset;
  6331   6512     u8 *pBegin = &pPg->aCellIdx[nNew * 2];
  6332   6513     int nCell = pPg->nCell;       /* Cells stored on pPg */
  6333   6514     u8 *pData;
  6334   6515     u8 *pCellptr;
................................................................................
  6339   6520   #ifdef SQLITE_DEBUG
  6340   6521     u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
  6341   6522     memcpy(pTmp, aData, pPg->pBt->usableSize);
  6342   6523   #endif
  6343   6524   
  6344   6525     /* Remove cells from the start and end of the page */
  6345   6526     if( iOld<iNew ){
  6346         -    int nShift = pageFreeArray(
  6347         -        pPg, iNew-iOld, &apCell[iOld], &szCell[iOld]
  6348         -    );
         6527  +    int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
  6349   6528       memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
  6350   6529       nCell -= nShift;
  6351   6530     }
  6352   6531     if( iNewEnd < iOldEnd ){
  6353         -    nCell -= pageFreeArray(
  6354         -        pPg, iOldEnd-iNewEnd, &apCell[iNewEnd], &szCell[iNewEnd]
  6355         -    );
         6532  +    nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
  6356   6533     }
  6357   6534   
  6358   6535     pData = &aData[get2byteNotZero(&aData[hdr+5])];
  6359   6536     if( pData<pBegin ) goto editpage_fail;
  6360   6537   
  6361   6538     /* Add cells to the start of the page */
  6362   6539     if( iNew<iOld ){
  6363   6540       int nAdd = MIN(nNew,iOld-iNew);
  6364   6541       assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
  6365   6542       pCellptr = pPg->aCellIdx;
  6366   6543       memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
  6367   6544       if( pageInsertArray(
  6368   6545             pPg, pBegin, &pData, pCellptr,
  6369         -          nAdd, &apCell[iNew], &szCell[iNew]
         6546  +          iNew, nAdd, pCArray
  6370   6547       ) ) goto editpage_fail;
  6371   6548       nCell += nAdd;
  6372   6549     }
  6373   6550   
  6374   6551     /* Add any overflow cells */
  6375   6552     for(i=0; i<pPg->nOverflow; i++){
  6376   6553       int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
  6377   6554       if( iCell>=0 && iCell<nNew ){
  6378   6555         pCellptr = &pPg->aCellIdx[iCell * 2];
  6379   6556         memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
  6380   6557         nCell++;
  6381   6558         if( pageInsertArray(
  6382   6559               pPg, pBegin, &pData, pCellptr,
  6383         -            1, &apCell[iCell + iNew], &szCell[iCell + iNew]
         6560  +            iCell+iNew, 1, pCArray
  6384   6561         ) ) goto editpage_fail;
  6385   6562       }
  6386   6563     }
  6387   6564   
  6388   6565     /* Append cells to the end of the page */
  6389   6566     pCellptr = &pPg->aCellIdx[nCell*2];
  6390   6567     if( pageInsertArray(
  6391   6568           pPg, pBegin, &pData, pCellptr,
  6392         -        nNew-nCell, &apCell[iNew+nCell], &szCell[iNew+nCell]
         6569  +        iNew+nCell, nNew-nCell, pCArray
  6393   6570     ) ) goto editpage_fail;
  6394   6571   
  6395   6572     pPg->nCell = nNew;
  6396   6573     pPg->nOverflow = 0;
  6397   6574   
  6398   6575     put2byte(&aData[hdr+3], pPg->nCell);
  6399   6576     put2byte(&aData[hdr+5], pData - aData);
  6400   6577   
  6401   6578   #ifdef SQLITE_DEBUG
  6402   6579     for(i=0; i<nNew && !CORRUPT_DB; i++){
  6403         -    u8 *pCell = apCell[i+iNew];
         6580  +    u8 *pCell = pCArray->apCell[i+iNew];
  6404   6581       int iOff = get2byte(&pPg->aCellIdx[i*2]);
  6405   6582       if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
  6406   6583         pCell = &pTmp[pCell - aData];
  6407   6584       }
  6408         -    assert( 0==memcmp(pCell, &aData[iOff], szCell[i+iNew]) );
         6585  +    assert( 0==memcmp(pCell, &aData[iOff],
         6586  +            pCArray->pRef->xCellSize(pCArray->pRef, pCArray->apCell[i+iNew])) );
  6409   6587     }
  6410   6588   #endif
  6411   6589   
  6412         -  return;
         6590  +  return SQLITE_OK;
  6413   6591    editpage_fail:
  6414   6592     /* Unable to edit this page. Rebuild it from scratch instead. */
  6415         -  rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
         6593  +  populateCellCache(pCArray, iNew, nNew);
         6594  +  return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]);
  6416   6595   }
  6417   6596   
  6418   6597   /*
  6419   6598   ** The following parameters determine how many adjacent pages get involved
  6420   6599   ** in a balancing operation.  NN is the number of neighbors on either side
  6421   6600   ** of the page that participate in the balancing operation.  NB is the
  6422   6601   ** total number of pages that participate, including the target page and
................................................................................
  6474   6653     */
  6475   6654     rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
  6476   6655   
  6477   6656     if( rc==SQLITE_OK ){
  6478   6657   
  6479   6658       u8 *pOut = &pSpace[4];
  6480   6659       u8 *pCell = pPage->apOvfl[0];
  6481         -    u16 szCell = cellSizePtr(pPage, pCell);
         6660  +    u16 szCell = pPage->xCellSize(pPage, pCell);
  6482   6661       u8 *pStop;
  6483   6662   
  6484   6663       assert( sqlite3PagerIswriteable(pNew->pDbPage) );
  6485   6664       assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
  6486   6665       zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
  6487         -    rebuildPage(pNew, 1, &pCell, &szCell);
         6666  +    rc = rebuildPage(pNew, 1, &pCell, &szCell);
         6667  +    if( NEVER(rc) ) return rc;
  6488   6668       pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
  6489   6669   
  6490   6670       /* If this is an auto-vacuum database, update the pointer map
  6491   6671       ** with entries for the new page, and any pointer from the 
  6492   6672       ** cell on the page to an overflow page. If either of these
  6493   6673       ** operations fails, the return code is set, but the contents
  6494   6674       ** of the parent page are still manipulated by thh code below.
................................................................................
  6553   6733       assert( pPage->isInit );
  6554   6734   
  6555   6735       for(j=0; j<pPage->nCell; j++){
  6556   6736         CellInfo info;
  6557   6737         u8 *z;
  6558   6738        
  6559   6739         z = findCell(pPage, j);
  6560         -      btreeParseCellPtr(pPage, z, &info);
         6740  +      pPage->xParseCell(pPage, z, &info);
  6561   6741         if( info.iOverflow ){
  6562   6742           Pgno ovfl = get4byte(&z[info.iOverflow]);
  6563   6743           ptrmapGet(pBt, ovfl, &e, &n);
  6564   6744           assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
  6565   6745         }
  6566   6746         if( !pPage->leaf ){
  6567   6747           Pgno child = get4byte(z);
................................................................................
  6684   6864     MemPage *pParent,               /* Parent page of siblings being balanced */
  6685   6865     int iParentIdx,                 /* Index of "the page" in pParent */
  6686   6866     u8 *aOvflSpace,                 /* page-size bytes of space for parent ovfl */
  6687   6867     int isRoot,                     /* True if pParent is a root-page */
  6688   6868     int bBulk                       /* True if this call is part of a bulk load */
  6689   6869   ){
  6690   6870     BtShared *pBt;               /* The whole database */
  6691         -  int nCell = 0;               /* Number of cells in apCell[] */
  6692   6871     int nMaxCells = 0;           /* Allocated size of apCell, szCell, aFrom. */
  6693   6872     int nNew = 0;                /* Number of pages in apNew[] */
  6694   6873     int nOld;                    /* Number of pages in apOld[] */
  6695   6874     int i, j, k;                 /* Loop counters */
  6696   6875     int nxDiv;                   /* Next divider slot in pParent->aCell[] */
  6697   6876     int rc = SQLITE_OK;          /* The return code */
  6698   6877     u16 leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
  6699   6878     int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
  6700   6879     int usableSpace;             /* Bytes in pPage beyond the header */
  6701   6880     int pageFlags;               /* Value of pPage->aData[0] */
  6702         -  int subtotal;                /* Subtotal of bytes in cells on one page */
  6703   6881     int iSpace1 = 0;             /* First unused byte of aSpace1[] */
  6704   6882     int iOvflSpace = 0;          /* First unused byte of aOvflSpace[] */
  6705   6883     int szScratch;               /* Size of scratch memory requested */
  6706   6884     MemPage *apOld[NB];          /* pPage and up to two siblings */
  6707   6885     MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
  6708   6886     u8 *pRight;                  /* Location in parent of right-sibling pointer */
  6709   6887     u8 *apDiv[NB-1];             /* Divider cells in pParent */
  6710         -  int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
  6711         -  int cntOld[NB+2];            /* Old index in aCell[] after i-th page */
         6888  +  int cntNew[NB+2];            /* Index in b.paCell[] of cell after i-th page */
         6889  +  int cntOld[NB+2];            /* Old index in b.apCell[] */
  6712   6890     int szNew[NB+2];             /* Combined size of cells placed on i-th page */
  6713         -  u8 **apCell = 0;             /* All cells begin balanced */
  6714         -  u16 *szCell;                 /* Local size of all cells in apCell[] */
  6715   6891     u8 *aSpace1;                 /* Space for copies of dividers cells */
  6716   6892     Pgno pgno;                   /* Temp var to store a page number in */
  6717   6893     u8 abDone[NB+2];             /* True after i'th new page is populated */
  6718   6894     Pgno aPgno[NB+2];            /* Page numbers of new pages before shuffling */
  6719   6895     Pgno aPgOrder[NB+2];         /* Copy of aPgno[] used for sorting pages */
  6720   6896     u16 aPgFlags[NB+2];          /* flags field of new pages before shuffling */
         6897  +  CellArray b;                  /* Parsed information on cells being balanced */
  6721   6898   
  6722   6899     memset(abDone, 0, sizeof(abDone));
         6900  +  b.nCell = 0;
         6901  +  b.apCell = 0;
  6723   6902     pBt = pParent->pBt;
  6724   6903     assert( sqlite3_mutex_held(pBt->mutex) );
  6725   6904     assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  6726   6905   
  6727   6906   #if 0
  6728   6907     TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
  6729   6908   #endif
................................................................................
  6780   6959       }
  6781   6960       nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
  6782   6961       if( (i--)==0 ) break;
  6783   6962   
  6784   6963       if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
  6785   6964         apDiv[i] = pParent->apOvfl[0];
  6786   6965         pgno = get4byte(apDiv[i]);
  6787         -      szNew[i] = cellSizePtr(pParent, apDiv[i]);
         6966  +      szNew[i] = pParent->xCellSize(pParent, apDiv[i]);
  6788   6967         pParent->nOverflow = 0;
  6789   6968       }else{
  6790   6969         apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow);
  6791   6970         pgno = get4byte(apDiv[i]);
  6792         -      szNew[i] = cellSizePtr(pParent, apDiv[i]);
         6971  +      szNew[i] = pParent->xCellSize(pParent, apDiv[i]);
  6793   6972   
  6794   6973         /* Drop the cell from the parent page. apDiv[i] still points to
  6795   6974         ** the cell within the parent, even though it has been dropped.
  6796   6975         ** This is safe because dropping a cell only overwrites the first
  6797   6976         ** four bytes of it, and this function does not need the first
  6798   6977         ** four bytes of the divider cell. So the pointer is safe to use
  6799   6978         ** later on.  
................................................................................
  6824   7003     ** alignment */
  6825   7004     nMaxCells = (nMaxCells + 3)&~3;
  6826   7005   
  6827   7006     /*
  6828   7007     ** Allocate space for memory structures
  6829   7008     */
  6830   7009     szScratch =
  6831         -       nMaxCells*sizeof(u8*)                       /* apCell */
  6832         -     + nMaxCells*sizeof(u16)                       /* szCell */
         7010  +       nMaxCells*sizeof(u8*)                       /* b.apCell */
         7011  +     + nMaxCells*sizeof(u16)                       /* b.szCell */
  6833   7012        + pBt->pageSize;                              /* aSpace1 */
  6834   7013   
  6835   7014     /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
  6836   7015     ** that is more than 6 times the database page size. */
  6837   7016     assert( szScratch<=6*(int)pBt->pageSize );
  6838         -  apCell = sqlite3ScratchMalloc( szScratch ); 
  6839         -  if( apCell==0 ){
         7017  +  b.apCell = sqlite3ScratchMalloc( szScratch ); 
         7018  +  if( b.apCell==0 ){
  6840   7019       rc = SQLITE_NOMEM;
  6841   7020       goto balance_cleanup;
  6842   7021     }
  6843         -  szCell = (u16*)&apCell[nMaxCells];
  6844         -  aSpace1 = (u8*)&szCell[nMaxCells];
         7022  +  b.szCell = (u16*)&b.apCell[nMaxCells];
         7023  +  aSpace1 = (u8*)&b.szCell[nMaxCells];
  6845   7024     assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );
  6846   7025   
  6847   7026     /*
  6848   7027     ** Load pointers to all cells on sibling pages and the divider cells
  6849         -  ** into the local apCell[] array.  Make copies of the divider cells
         7028  +  ** into the local b.apCell[] array.  Make copies of the divider cells
  6850   7029     ** into space obtained from aSpace1[]. The divider cells have already
  6851   7030     ** been removed from pParent.
  6852   7031     **
  6853   7032     ** If the siblings are on leaf pages, then the child pointers of the
  6854   7033     ** divider cells are stripped from the cells before they are copied
  6855         -  ** into aSpace1[].  In this way, all cells in apCell[] are without
         7034  +  ** into aSpace1[].  In this way, all cells in b.apCell[] are without
  6856   7035     ** child pointers.  If siblings are not leaves, then all cell in
  6857         -  ** apCell[] include child pointers.  Either way, all cells in apCell[]
         7036  +  ** b.apCell[] include child pointers.  Either way, all cells in b.apCell[]
  6858   7037     ** are alike.
  6859   7038     **
  6860   7039     ** leafCorrection:  4 if pPage is a leaf.  0 if pPage is not a leaf.
  6861   7040     **       leafData:  1 if pPage holds key+data and pParent holds only keys.
  6862   7041     */
  6863         -  leafCorrection = apOld[0]->leaf*4;
  6864         -  leafData = apOld[0]->intKeyLeaf;
         7042  +  b.pRef = apOld[0];
         7043  +  leafCorrection = b.pRef->leaf*4;
         7044  +  leafData = b.pRef->intKeyLeaf;
  6865   7045     for(i=0; i<nOld; i++){
  6866         -    int limit;
  6867   7046       MemPage *pOld = apOld[i];
         7047  +    int limit = pOld->nCell;
         7048  +    u8 *aData = pOld->aData;
         7049  +    u16 maskPage = pOld->maskPage;
         7050  +    u8 *piCell = aData + pOld->cellOffset;
         7051  +    u8 *piEnd;
  6868   7052   
  6869   7053       /* Verify that all sibling pages are of the same "type" (table-leaf,
  6870   7054       ** table-interior, index-leaf, or index-interior).
  6871   7055       */
  6872   7056       if( pOld->aData[0]!=apOld[0]->aData[0] ){
  6873   7057         rc = SQLITE_CORRUPT_BKPT;
  6874   7058         goto balance_cleanup;
  6875   7059       }
  6876   7060   
  6877         -    limit = pOld->nCell+pOld->nOverflow;
         7061  +    /* Load b.apCell[] with pointers to all cells in pOld.  If pOld
         7062  +    ** constains overflow cells, include them in the b.apCell[] array
         7063  +    ** in the correct spot.
         7064  +    **
         7065  +    ** Note that when there are multiple overflow cells, it is always the
         7066  +    ** case that they are sequential and adjacent.  This invariant arises
         7067  +    ** because multiple overflows can only occurs when inserting divider
         7068  +    ** cells into a parent on a prior balance, and divider cells are always
         7069  +    ** adjacent and are inserted in order.  There is an assert() tagged
         7070  +    ** with "NOTE 1" in the overflow cell insertion loop to prove this
         7071  +    ** invariant.
         7072  +    **
         7073  +    ** This must be done in advance.  Once the balance starts, the cell
         7074  +    ** offset section of the btree page will be overwritten and we will no
         7075  +    ** long be able to find the cells if a pointer to each cell is not saved
         7076  +    ** first.
         7077  +    */
         7078  +    memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*limit);
  6878   7079       if( pOld->nOverflow>0 ){
  6879         -      for(j=0; j<limit; j++){
  6880         -        assert( nCell<nMaxCells );
  6881         -        apCell[nCell] = findOverflowCell(pOld, j);
  6882         -        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
  6883         -        nCell++;
  6884         -      }
  6885         -    }else{
  6886         -      u8 *aData = pOld->aData;
  6887         -      u16 maskPage = pOld->maskPage;
  6888         -      u16 cellOffset = pOld->cellOffset;
         7080  +      memset(&b.szCell[b.nCell+limit], 0, sizeof(b.szCell[0])*pOld->nOverflow);
         7081  +      limit = pOld->aiOvfl[0];
  6889   7082         for(j=0; j<limit; j++){
  6890         -        assert( nCell<nMaxCells );
  6891         -        apCell[nCell] = findCellv2(aData, maskPage, cellOffset, j);
  6892         -        szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
  6893         -        nCell++;
         7083  +        b.apCell[b.nCell] = aData + (maskPage & get2byte(piCell));
         7084  +        piCell += 2;
         7085  +        b.nCell++;
  6894   7086         }
  6895         -    }       
  6896         -    cntOld[i] = nCell;
         7087  +      for(k=0; k<pOld->nOverflow; k++){
         7088  +        assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */
         7089  +        b.apCell[b.nCell] = pOld->apOvfl[k];
         7090  +        b.nCell++;
         7091  +      }
         7092  +    }
         7093  +    piEnd = aData + pOld->cellOffset + 2*pOld->nCell;
         7094  +    while( piCell<piEnd ){
         7095  +      assert( b.nCell<nMaxCells );
         7096  +      b.apCell[b.nCell] = aData + (maskPage & get2byte(piCell));
         7097  +      piCell += 2;
         7098  +      b.nCell++;
         7099  +    }
         7100  +
         7101  +    cntOld[i] = b.nCell;
  6897   7102       if( i<nOld-1 && !leafData){
  6898   7103         u16 sz = (u16)szNew[i];
  6899   7104         u8 *pTemp;
  6900         -      assert( nCell<nMaxCells );
  6901         -      szCell[nCell] = sz;
         7105  +      assert( b.nCell<nMaxCells );
         7106  +      b.szCell[b.nCell] = sz;
  6902   7107         pTemp = &aSpace1[iSpace1];
  6903   7108         iSpace1 += sz;
  6904   7109         assert( sz<=pBt->maxLocal+23 );
  6905   7110         assert( iSpace1 <= (int)pBt->pageSize );
  6906   7111         memcpy(pTemp, apDiv[i], sz);
  6907         -      apCell[nCell] = pTemp+leafCorrection;
         7112  +      b.apCell[b.nCell] = pTemp+leafCorrection;
  6908   7113         assert( leafCorrection==0 || leafCorrection==4 );
  6909         -      szCell[nCell] = szCell[nCell] - leafCorrection;
         7114  +      b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection;
  6910   7115         if( !pOld->leaf ){
  6911   7116           assert( leafCorrection==0 );
  6912   7117           assert( pOld->hdrOffset==0 );
  6913   7118           /* The right pointer of the child page pOld becomes the left
  6914   7119           ** pointer of the divider cell */
  6915         -        memcpy(apCell[nCell], &pOld->aData[8], 4);
         7120  +        memcpy(b.apCell[b.nCell], &pOld->aData[8], 4);
  6916   7121         }else{
  6917   7122           assert( leafCorrection==4 );
  6918         -        while( szCell[nCell]<4 ){
         7123  +        while( b.szCell[b.nCell]<4 ){
  6919   7124             /* Do not allow any cells smaller than 4 bytes. If a smaller cell
  6920   7125             ** does exist, pad it with 0x00 bytes. */
  6921         -          assert( szCell[nCell]==3 || CORRUPT_DB );
  6922         -          assert( apCell[nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
         7126  +          assert( b.szCell[b.nCell]==3 || CORRUPT_DB );
         7127  +          assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
  6923   7128             aSpace1[iSpace1++] = 0x00;
  6924         -          szCell[nCell]++;
         7129  +          b.szCell[b.nCell]++;
  6925   7130           }
  6926   7131         }
  6927         -      nCell++;
         7132  +      b.nCell++;
  6928   7133       }
  6929   7134     }
  6930   7135   
  6931   7136     /*
  6932         -  ** Figure out the number of pages needed to hold all nCell cells.
         7137  +  ** Figure out the number of pages needed to hold all b.nCell cells.
  6933   7138     ** Store this number in "k".  Also compute szNew[] which is the total
  6934   7139     ** size of all cells on the i-th page and cntNew[] which is the index
  6935         -  ** in apCell[] of the cell that divides page i from page i+1.  
  6936         -  ** cntNew[k] should equal nCell.
         7140  +  ** in b.apCell[] of the cell that divides page i from page i+1.  
         7141  +  ** cntNew[k] should equal b.nCell.
  6937   7142     **
  6938   7143     ** Values computed by this block:
  6939   7144     **
  6940   7145     **           k: The total number of sibling pages
  6941   7146     **    szNew[i]: Spaced used on the i-th sibling page.
  6942         -  **   cntNew[i]: Index in apCell[] and szCell[] for the first cell to
         7147  +  **   cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to
  6943   7148     **              the right of the i-th sibling page.
  6944   7149     ** usableSpace: Number of bytes of space available on each sibling.
  6945   7150     ** 
  6946   7151     */
  6947   7152     usableSpace = pBt->usableSize - 12 + leafCorrection;
  6948         -  for(subtotal=k=i=0; i<nCell; i++){
  6949         -    assert( i<nMaxCells );
  6950         -    subtotal += szCell[i] + 2;
  6951         -    if( subtotal > usableSpace ){
  6952         -      szNew[k] = subtotal - szCell[i] - 2;
  6953         -      cntNew[k] = i;
  6954         -      if( leafData ){ i--; }
  6955         -      subtotal = 0;
  6956         -      k++;
  6957         -      if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
  6958         -    }
  6959         -  }
  6960         -  szNew[k] = subtotal;
  6961         -  cntNew[k] = nCell;
  6962         -  k++;
         7153  +  for(i=0; i<nOld; i++){
         7154  +    MemPage *p = apOld[i];
         7155  +    szNew[i] = usableSpace - p->nFree;
         7156  +    if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
         7157  +    for(j=0; j<p->nOverflow; j++){
         7158  +      szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
         7159  +    }
         7160  +    cntNew[i] = cntOld[i];
         7161  +  }
         7162  +  k = nOld;
         7163  +  for(i=0; i<k; i++){
         7164  +    int sz;
         7165  +    while( szNew[i]>usableSpace ){
         7166  +      if( i+1>=k ){
         7167  +        k = i+2;
         7168  +        if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
         7169  +        szNew[k-1] = 0;
         7170  +        cntNew[k-1] = b.nCell;
         7171  +      }
         7172  +      sz = 2 + cachedCellSize(&b, cntNew[i]-1);
         7173  +      szNew[i] -= sz;
         7174  +      if( !leafData ){
         7175  +        if( cntNew[i]<b.nCell ){
         7176  +          sz = 2 + cachedCellSize(&b, cntNew[i]);
         7177  +        }else{
         7178  +          sz = 0;
         7179  +        }
         7180  +      }
         7181  +      szNew[i+1] += sz;
         7182  +      cntNew[i]--;
         7183  +    }
         7184  +    while( cntNew[i]<b.nCell ){
         7185  +      sz = 2 + cachedCellSize(&b, cntNew[i]);
         7186  +      if( szNew[i]+sz>usableSpace ) break;
         7187  +      szNew[i] += sz;
         7188  +      cntNew[i]++;
         7189  +      if( !leafData ){
         7190  +        if( cntNew[i]<b.nCell ){
         7191  +          sz = 2 + cachedCellSize(&b, cntNew[i]);
         7192  +        }else{
         7193  +          sz = 0;
         7194  +        }
         7195  +      }
         7196  +      szNew[i+1] -= sz;
         7197  +    }
         7198  +    if( cntNew[i]>=b.nCell ){
         7199  +      k = i+1;
         7200  +    }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){
         7201  +      rc = SQLITE_CORRUPT_BKPT;
         7202  +      goto balance_cleanup;
         7203  +    }
         7204  +  }
  6963   7205   
  6964   7206     /*
  6965   7207     ** The packing computed by the previous block is biased toward the siblings
  6966   7208     ** on the left side (siblings with smaller keys). The left siblings are
  6967   7209     ** always nearly full, while the right-most sibling might be nearly empty.
  6968   7210     ** The next block of code attempts to adjust the packing of siblings to
  6969   7211     ** get a better balance.
................................................................................
  6976   7218       int szRight = szNew[i];  /* Size of sibling on the right */
  6977   7219       int szLeft = szNew[i-1]; /* Size of sibling on the left */
  6978   7220       int r;              /* Index of right-most cell in left sibling */
  6979   7221       int d;              /* Index of first cell to the left of right sibling */
  6980   7222   
  6981   7223       r = cntNew[i-1] - 1;
  6982   7224       d = r + 1 - leafData;
  6983         -    assert( d<nMaxCells );
  6984         -    assert( r<nMaxCells );
  6985         -    while( szRight==0 
  6986         -       || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2)) 
  6987         -    ){
  6988         -      szRight += szCell[d] + 2;
  6989         -      szLeft -= szCell[r] + 2;
  6990         -      cntNew[i-1]--;
  6991         -      r = cntNew[i-1] - 1;
  6992         -      d = r + 1 - leafData;
  6993         -    }
         7225  +    (void)cachedCellSize(&b, d);
         7226  +    do{
         7227  +      assert( d<nMaxCells );
         7228  +      assert( r<nMaxCells );
         7229  +      (void)cachedCellSize(&b, r);
         7230  +      if( szRight!=0
         7231  +       && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+2)) ){
         7232  +        break;
         7233  +      }
         7234  +      szRight += b.szCell[d] + 2;
         7235  +      szLeft -= b.szCell[r] + 2;
         7236  +      cntNew[i-1] = r;
         7237  +      r--;
         7238  +      d--;
         7239  +    }while( r>=0 );
  6994   7240       szNew[i] = szRight;
  6995   7241       szNew[i-1] = szLeft;
         7242  +    if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){
         7243  +      rc = SQLITE_CORRUPT_BKPT;
         7244  +      goto balance_cleanup;
         7245  +    }
  6996   7246     }
  6997   7247   
  6998   7248     /* Sanity check:  For a non-corrupt database file one of the follwing
  6999   7249     ** must be true:
  7000   7250     **    (1) We found one or more cells (cntNew[0])>0), or
  7001   7251     **    (2) pPage is a virtual root page.  A virtual root page is when
  7002   7252     **        the real root page is page 1 and we are the only child of
................................................................................
  7024   7274       }else{
  7025   7275         assert( i>0 );
  7026   7276         rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
  7027   7277         if( rc ) goto balance_cleanup;
  7028   7278         zeroPage(pNew, pageFlags);
  7029   7279         apNew[i] = pNew;
  7030   7280         nNew++;
  7031         -      cntOld[i] = nCell;
         7281  +      cntOld[i] = b.nCell;
  7032   7282   
  7033   7283         /* Set the pointer-map entry for the new sibling page. */
  7034   7284         if( ISAUTOVACUUM ){
  7035   7285           ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
  7036   7286           if( rc!=SQLITE_OK ){
  7037   7287             goto balance_cleanup;
  7038   7288           }
................................................................................
  7129   7379       MemPage *pNew = apNew[0];
  7130   7380       u8 *aOld = pNew->aData;
  7131   7381       int cntOldNext = pNew->nCell + pNew->nOverflow;
  7132   7382       int usableSize = pBt->usableSize;
  7133   7383       int iNew = 0;
  7134   7384       int iOld = 0;
  7135   7385   
  7136         -    for(i=0; i<nCell; i++){
  7137         -      u8 *pCell = apCell[i];
         7386  +    for(i=0; i<b.nCell; i++){
         7387  +      u8 *pCell = b.apCell[i];
  7138   7388         if( i==cntOldNext ){
  7139   7389           MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
  7140   7390           cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
  7141   7391           aOld = pOld->aData;
  7142   7392         }
  7143   7393         if( i==cntNew[iNew] ){
  7144   7394           pNew = apNew[++iNew];
................................................................................
  7155   7405          || pNew->pgno!=aPgno[iOld]
  7156   7406          || pCell<aOld
  7157   7407          || pCell>=&aOld[usableSize]
  7158   7408         ){
  7159   7409           if( !leafCorrection ){
  7160   7410             ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
  7161   7411           }
  7162         -        if( szCell[i]>pNew->minLocal ){
         7412  +        if( cachedCellSize(&b,i)>pNew->minLocal ){
  7163   7413             ptrmapPutOvflPtr(pNew, pCell, &rc);
  7164   7414           }
         7415  +        if( rc ) goto balance_cleanup;
  7165   7416         }
  7166   7417       }
  7167   7418     }
  7168   7419   
  7169   7420     /* Insert new divider cells into pParent. */
  7170   7421     for(i=0; i<nNew-1; i++){
  7171   7422       u8 *pCell;
  7172   7423       u8 *pTemp;
  7173   7424       int sz;
  7174   7425       MemPage *pNew = apNew[i];
  7175   7426       j = cntNew[i];
  7176   7427   
  7177   7428       assert( j<nMaxCells );
  7178         -    pCell = apCell[j];
  7179         -    sz = szCell[j] + leafCorrection;
         7429  +    assert( b.apCell[j]!=0 );
         7430  +    pCell = b.apCell[j];
         7431  +    sz = b.szCell[j] + leafCorrection;
  7180   7432       pTemp = &aOvflSpace[iOvflSpace];
  7181   7433       if( !pNew->leaf ){
  7182   7434         memcpy(&pNew->aData[8], pCell, 4);
  7183   7435       }else if( leafData ){
  7184   7436         /* If the tree is a leaf-data tree, and the siblings are leaves, 
  7185         -      ** then there is no divider cell in apCell[]. Instead, the divider 
         7437  +      ** then there is no divider cell in b.apCell[]. Instead, the divider 
  7186   7438         ** cell consists of the integer key for the right-most cell of 
  7187   7439         ** the sibling-page assembled above only.
  7188   7440         */
  7189   7441         CellInfo info;
  7190   7442         j--;
  7191         -      btreeParseCellPtr(pNew, apCell[j], &info);
         7443  +      pNew->xParseCell(pNew, b.apCell[j], &info);
  7192   7444         pCell = pTemp;
  7193   7445         sz = 4 + putVarint(&pCell[4], info.nKey);
  7194   7446         pTemp = 0;
  7195   7447       }else{
  7196   7448         pCell -= 4;
  7197   7449         /* Obscure case for non-leaf-data trees: If the cell at pCell was
  7198   7450         ** previously stored on a leaf node, and its reported size was 4
................................................................................
  7201   7453         ** any cell). But it is important to pass the correct size to 
  7202   7454         ** insertCell(), so reparse the cell now.
  7203   7455         **
  7204   7456         ** Note that this can never happen in an SQLite data file, as all
  7205   7457         ** cells are at least 4 bytes. It only happens in b-trees used
  7206   7458         ** to evaluate "IN (SELECT ...)" and similar clauses.
  7207   7459         */
  7208         -      if( szCell[j]==4 ){
         7460  +      if( b.szCell[j]==4 ){
  7209   7461           assert(leafCorrection==4);
  7210         -        sz = cellSizePtr(pParent, pCell);
         7462  +        sz = pParent->xCellSize(pParent, pCell);
  7211   7463         }
  7212   7464       }
  7213   7465       iOvflSpace += sz;
  7214   7466       assert( sz<=pBt->maxLocal+23 );
  7215   7467       assert( iOvflSpace <= (int)pBt->pageSize );
  7216   7468       insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
  7217   7469       if( rc!=SQLITE_OK ) goto balance_cleanup;
................................................................................
  7259   7511         ** only after iPg+1 has already been updated. */
  7260   7512         assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] );
  7261   7513   
  7262   7514         if( iPg==0 ){
  7263   7515           iNew = iOld = 0;
  7264   7516           nNewCell = cntNew[0];
  7265   7517         }else{
  7266         -        iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : nCell;
         7518  +        iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : b.nCell;
  7267   7519           iNew = cntNew[iPg-1] + !leafData;
  7268   7520           nNewCell = cntNew[iPg] - iNew;
  7269   7521         }
  7270   7522   
  7271         -      editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
         7523  +      rc = editPage(apNew[iPg], iOld, iNew, nNewCell, &b);
         7524  +      if( rc ) goto balance_cleanup;
  7272   7525         abDone[iPg]++;
  7273   7526         apNew[iPg]->nFree = usableSpace-szNew[iPg];
  7274   7527         assert( apNew[iPg]->nOverflow==0 );
  7275   7528         assert( apNew[iPg]->nCell==nNewCell );
  7276   7529       }
  7277   7530     }
  7278   7531   
................................................................................
  7315   7568         u32 key = get4byte(&apNew[i]->aData[8]);
  7316   7569         ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
  7317   7570       }
  7318   7571     }
  7319   7572   
  7320   7573     assert( pParent->isInit );
  7321   7574     TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
  7322         -          nOld, nNew, nCell));
         7575  +          nOld, nNew, b.nCell));
  7323   7576   
  7324   7577     /* Free any old pages that were not reused as new pages.
  7325   7578     */
  7326   7579     for(i=nNew; i<nOld; i++){
  7327   7580       freePage(apOld[i], &rc);
  7328   7581     }
  7329   7582   
................................................................................
  7338   7591     }
  7339   7592   #endif
  7340   7593   
  7341   7594     /*
  7342   7595     ** Cleanup before returning.
  7343   7596     */
  7344   7597   balance_cleanup:
  7345         -  sqlite3ScratchFree(apCell);
         7598  +  sqlite3ScratchFree(b.apCell);
  7346   7599     for(i=0; i<nOld; i++){
  7347   7600       releasePage(apOld[i]);
  7348   7601     }
  7349   7602     for(i=0; i<nNew; i++){
  7350   7603       releasePage(apNew[i]);
  7351   7604     }
  7352   7605   
................................................................................
  7648   7901             pCur->pgnoRoot, nKey, nData, pPage->pgno,
  7649   7902             loc==0 ? "overwrite" : "new entry"));
  7650   7903     assert( pPage->isInit );
  7651   7904     newCell = pBt->pTmpSpace;
  7652   7905     assert( newCell!=0 );
  7653   7906     rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
  7654   7907     if( rc ) goto end_insert;
  7655         -  assert( szNew==cellSizePtr(pPage, newCell) );
         7908  +  assert( szNew==pPage->xCellSize(pPage, newCell) );
  7656   7909     assert( szNew <= MX_CELL_SIZE(pBt) );
  7657   7910     idx = pCur->aiIdx[pCur->iPage];
  7658   7911     if( loc==0 ){
  7659   7912       u16 szOld;
  7660   7913       assert( idx<pPage->nCell );
  7661   7914       rc = sqlite3PagerWrite(pPage->pDbPage);
  7662   7915       if( rc ){
................................................................................
  7790   8043       MemPage *pLeaf = pCur->apPage[pCur->iPage];
  7791   8044       int nCell;
  7792   8045       Pgno n = pCur->apPage[iCellDepth+1]->pgno;
  7793   8046       unsigned char *pTmp;
  7794   8047   
  7795   8048       pCell = findCell(pLeaf, pLeaf->nCell-1);
  7796   8049       if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
  7797         -    nCell = cellSizePtr(pLeaf, pCell);
         8050  +    nCell = pLeaf->xCellSize(pLeaf, pCell);
  7798   8051       assert( MX_CELL_SIZE(pBt) >= nCell );
  7799   8052       pTmp = pBt->pTmpSpace;
  7800   8053       assert( pTmp!=0 );
  7801   8054       rc = sqlite3PagerWrite(pLeaf->pDbPage);
  7802   8055       insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
  7803   8056       dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
  7804   8057       if( rc ) return rc;
................................................................................
  8684   8937   
  8685   8938       /* Check payload overflow pages
  8686   8939       */
  8687   8940       pCheck->zPfx = "On tree page %d cell %d: ";
  8688   8941       pCheck->v1 = iPage;
  8689   8942       pCheck->v2 = i;
  8690   8943       pCell = findCell(pPage,i);
  8691         -    btreeParseCellPtr(pPage, pCell, &info);
         8944  +    pPage->xParseCell(pPage, pCell, &info);
  8692   8945       sz = info.nPayload;
  8693   8946       /* For intKey pages, check that the keys are in order.
  8694   8947       */
  8695   8948       if( pPage->intKey ){
  8696   8949         if( i==0 ){
  8697   8950           nMinKey = nMaxKey = info.nKey;
  8698   8951         }else if( info.nKey <= nMaxKey ){
................................................................................
  8802   9055       cellStart = hdr + 12 - 4*pPage->leaf;
  8803   9056       /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
  8804   9057       ** integer offsets to the cell contents. */
  8805   9058       for(i=0; i<nCell; i++){
  8806   9059         int pc = get2byte(&data[cellStart+i*2]);
  8807   9060         u32 size = 65536;
  8808   9061         if( pc<=usableSize-4 ){
  8809         -        size = cellSizePtr(pPage, &data[pc]);
         9062  +        size = pPage->xCellSize(pPage, &data[pc]);
  8810   9063         }
  8811   9064         if( (int)(pc+size-1)>=usableSize ){
  8812   9065           pCheck->zPfx = 0;
  8813   9066           checkAppendMsg(pCheck,
  8814   9067               "Corruption detected in cell %d on page %d",i,iPage);
  8815   9068         }else{
  8816   9069           btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
................................................................................
  9200   9453   }
  9201   9454   
  9202   9455   /* 
  9203   9456   ** Mark this cursor as an incremental blob cursor.
  9204   9457   */
  9205   9458   void sqlite3BtreeIncrblobCursor(BtCursor *pCur){
  9206   9459     pCur->curFlags |= BTCF_Incrblob;
         9460  +  pCur->pBtree->hasIncrblobCur = 1;
  9207   9461   }
  9208   9462   #endif
  9209   9463   
  9210   9464   /*
  9211   9465   ** Set both the "read version" (single byte at byte offset 18) and 
  9212   9466   ** "write version" (single byte at byte offset 19) fields in the database
  9213   9467   ** header to iVersion.

Changes to src/btreeInt.h.

   227    227   ** small cells will be rare, but they are possible.
   228    228   */
   229    229   #define MX_CELL(pBt) ((pBt->pageSize-8)/6)
   230    230   
   231    231   /* Forward declarations */
   232    232   typedef struct MemPage MemPage;
   233    233   typedef struct BtLock BtLock;
          234  +typedef struct CellInfo CellInfo;
   234    235   
   235    236   /*
   236    237   ** This is a magic string that appears at the beginning of every
   237    238   ** SQLite database in order to identify the file as a real database.
   238    239   **
   239    240   ** You can change this value at compile-time by specifying a
   240    241   ** -DSQLITE_FILE_HEADER="..." on the compiler command-line.  The
................................................................................
   291    292                          ** non-overflow cell */
   292    293     u8 *apOvfl[5];       /* Pointers to the body of overflow cells */
   293    294     BtShared *pBt;       /* Pointer to BtShared that this page is part of */
   294    295     u8 *aData;           /* Pointer to disk image of the page data */
   295    296     u8 *aDataEnd;        /* One byte past the end of usable data */
   296    297     u8 *aCellIdx;        /* The cell index area */
   297    298     DbPage *pDbPage;     /* Pager page handle */
          299  +  u16 (*xCellSize)(MemPage*,u8*);             /* cellSizePtr method */
          300  +  void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
   298    301     Pgno pgno;           /* Page number for this page */
   299    302   };
   300    303   
   301    304   /*
   302    305   ** The in-memory image of a disk page has the auxiliary information appended
   303    306   ** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
   304    307   ** that extra information.
................................................................................
   346    349   */
   347    350   struct Btree {
   348    351     sqlite3 *db;       /* The database connection holding this btree */
   349    352     BtShared *pBt;     /* Sharable content of this btree */
   350    353     u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
   351    354     u8 sharable;       /* True if we can share pBt with another db */
   352    355     u8 locked;         /* True if db currently has pBt locked */
          356  +  u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
   353    357     int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
   354    358     int nBackup;       /* Number of backup operations reading this btree */
   355    359     u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
   356    360     Btree *pNext;      /* List of other sharable Btrees from the same db */
   357    361     Btree *pPrev;      /* Back pointer of the same list */
   358    362   #ifndef SQLITE_OMIT_SHARED_CACHE
   359    363     BtLock lock;       /* Object used to lock page 1 */
................................................................................
   456    460   #define BTS_PENDING          0x0040   /* Waiting for read-locks to clear */
   457    461   
   458    462   /*
   459    463   ** An instance of the following structure is used to hold information
   460    464   ** about a cell.  The parseCellPtr() function fills in this structure
   461    465   ** based on information extract from the raw disk page.
   462    466   */
   463         -typedef struct CellInfo CellInfo;
   464    467   struct CellInfo {
   465    468     i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
   466    469     u8 *pPayload;  /* Pointer to the start of payload */
   467    470     u32 nPayload;  /* Bytes of payload */
   468    471     u16 nLocal;    /* Amount of payload held locally, not on overflow */
   469    472     u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
   470    473     u16 nSize;     /* Size of the cell content on the main b-tree page */

Changes to src/expr.c.

  2851   2851         }
  2852   2852   
  2853   2853         /* The UNLIKELY() function is a no-op.  The result is the value
  2854   2854         ** of the first argument.
  2855   2855         */
  2856   2856         if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
  2857   2857           assert( nFarg>=1 );
  2858         -        sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
         2858  +        inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
  2859   2859           break;
  2860   2860         }
  2861   2861   
  2862   2862         for(i=0; i<nFarg; i++){
  2863   2863           if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
  2864   2864             testcase( i==31 );
  2865   2865             constMask |= MASKBIT32(i);

Changes to src/resolve.c.

  1326   1326           if( ExprHasProperty(pItem->pExpr, EP_Agg) ){
  1327   1327             sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in "
  1328   1328                 "the GROUP BY clause");
  1329   1329             return WRC_Abort;
  1330   1330           }
  1331   1331         }
  1332   1332       }
         1333  +
         1334  +    /* If this is part of a compound SELECT, check that it has the right
         1335  +    ** number of expressions in the select list. */
         1336  +    if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
         1337  +      sqlite3SelectWrongNumTermsError(pParse, p->pNext);
         1338  +      return WRC_Abort;
         1339  +    }
  1333   1340   
  1334   1341       /* Advance to the next term of the compound
  1335   1342       */
  1336   1343       p = p->pPrior;
  1337   1344       nCompound++;
  1338   1345     }
  1339   1346   

Changes to src/select.c.

   362    362   */
   363    363   static void setJoinExpr(Expr *p, int iTable){
   364    364     while( p ){
   365    365       ExprSetProperty(p, EP_FromJoin);
   366    366       assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
   367    367       ExprSetVVAProperty(p, EP_NoReduce);
   368    368       p->iRightJoinTable = (i16)iTable;
          369  +    if( p->op==TK_FUNCTION && p->x.pList ){
          370  +      int i;
          371  +      for(i=0; i<p->x.pList->nExpr; i++){
          372  +        setJoinExpr(p->x.pList->a[i].pExpr, iTable);
          373  +      }
          374  +    }
   369    375       setJoinExpr(p->pLeft, iTable);
   370    376       p = p->pRight;
   371    377     } 
   372    378   }
   373    379   
   374    380   /*
   375    381   ** This routine processes the join information for a SELECT statement.
................................................................................
  1382   1388   
  1383   1389         assert( pTab && pExpr->pTab==pTab );
  1384   1390         if( pS ){
  1385   1391           /* The "table" is actually a sub-select or a view in the FROM clause
  1386   1392           ** of the SELECT statement. Return the declaration type and origin
  1387   1393           ** data for the result-set column of the sub-select.
  1388   1394           */
  1389         -        if( iCol>=0 && iCol<pS->pEList->nExpr ){
         1395  +        if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
  1390   1396             /* If iCol is less than zero, then the expression requests the
  1391   1397             ** rowid of the sub-select or view. This expression is legal (see 
  1392   1398             ** test case misc2.2.2) - it always evaluates to NULL.
         1399  +          **
         1400  +          ** The ALWAYS() is because iCol>=pS->pEList->nExpr will have been
         1401  +          ** caught already by name resolution.
  1393   1402             */
  1394   1403             NameContext sNC;
  1395   1404             Expr *p = pS->pEList->a[iCol].pExpr;
  1396   1405             sNC.pSrcList = pS->pSrc;
  1397   1406             sNC.pNext = pNC;
  1398   1407             sNC.pParse = pNC->pParse;
  1399   1408             zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); 
................................................................................
  1864   1873     CollSeq *pRet;
  1865   1874     if( p->pPrior ){
  1866   1875       pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
  1867   1876     }else{
  1868   1877       pRet = 0;
  1869   1878     }
  1870   1879     assert( iCol>=0 );
  1871         -  if( pRet==0 && iCol<p->pEList->nExpr ){
         1880  +  /* iCol must be less than p->pEList->nExpr.  Otherwise an error would
         1881  +  ** have been thrown during name resolution and we would not have gotten
         1882  +  ** this far */
         1883  +  if( pRet==0 && ALWAYS(iCol<p->pEList->nExpr) ){
  1872   1884       pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
  1873   1885     }
  1874   1886     return pRet;
  1875   1887   }
  1876   1888   
  1877   1889   /*
  1878   1890   ** The select statement passed as the second parameter is a compound SELECT
................................................................................
  2083   2095     SelectDest *pDest     /* What to do with query results */
  2084   2096   );
  2085   2097   
  2086   2098   /*
  2087   2099   ** Error message for when two or more terms of a compound select have different
  2088   2100   ** size result sets.
  2089   2101   */
  2090         -static void selectWrongNumTermsError(Parse *pParse, Select *p){
         2102  +void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
  2091   2103     if( p->selFlags & SF_Values ){
  2092   2104       sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
  2093   2105     }else{
  2094   2106       sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
  2095   2107         " do not have the same number of result columns", selectOpName(p->op));
  2096   2108     }
  2097   2109   }
................................................................................
  2109   2121   */
  2110   2122   static int multiSelectValues(
  2111   2123     Parse *pParse,        /* Parsing context */
  2112   2124     Select *p,            /* The right-most of SELECTs to be coded */
  2113   2125     SelectDest *pDest     /* What to do with query results */
  2114   2126   ){
  2115   2127     Select *pPrior;
  2116         -  int nExpr = p->pEList->nExpr;
  2117   2128     int nRow = 1;
  2118   2129     int rc = 0;
  2119   2130     assert( p->selFlags & SF_MultiValue );
  2120   2131     do{
  2121   2132       assert( p->selFlags & SF_Values );
  2122   2133       assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
  2123   2134       assert( p->pLimit==0 );
  2124   2135       assert( p->pOffset==0 );
  2125         -    if( p->pEList->nExpr!=nExpr ){
  2126         -      selectWrongNumTermsError(pParse, p);
  2127         -      return 1;
  2128         -    }
         2136  +    assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
  2129   2137       if( p->pPrior==0 ) break;
  2130   2138       assert( p->pPrior->pNext==p );
  2131   2139       p = p->pPrior;
  2132   2140       nRow++;
  2133   2141     }while(1);
  2134   2142     while( p ){
  2135   2143       pPrior = p->pPrior;
................................................................................
  2230   2238       goto multi_select_end;
  2231   2239     }
  2232   2240   
  2233   2241     /* Make sure all SELECTs in the statement have the same number of elements
  2234   2242     ** in their result sets.
  2235   2243     */
  2236   2244     assert( p->pEList && pPrior->pEList );
  2237         -  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
  2238         -    selectWrongNumTermsError(pParse, p);
  2239         -    rc = 1;
  2240         -    goto multi_select_end;
  2241         -  }
         2245  +  assert( p->pEList->nExpr==pPrior->pEList->nExpr );
  2242   2246   
  2243   2247   #ifndef SQLITE_OMIT_CTE
  2244   2248     if( p->selFlags & SF_Recursive ){
  2245   2249       generateWithRecursiveQuery(pParse, p, &dest);
  2246   2250     }else
  2247   2251   #endif
  2248   2252   
................................................................................
  2853   2857     ** collation.
  2854   2858     */
  2855   2859     aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
  2856   2860     if( aPermute ){
  2857   2861       struct ExprList_item *pItem;
  2858   2862       for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
  2859   2863         assert( pItem->u.x.iOrderByCol>0 );
  2860         -      /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
  2861         -      ** but only for well-formed SELECT statements. */
  2862         -      testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
         2864  +      assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
  2863   2865         aPermute[i] = pItem->u.x.iOrderByCol - 1;
  2864   2866       }
  2865   2867       pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
  2866   2868     }else{
  2867   2869       pKeyMerge = 0;
  2868   2870     }
  2869   2871   
................................................................................
  3425   3427       if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
  3426   3428         return 0;
  3427   3429       }
  3428   3430       for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
  3429   3431         testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
  3430   3432         testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
  3431   3433         assert( pSub->pSrc!=0 );
         3434  +      assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
  3432   3435         if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
  3433   3436          || (pSub1->pPrior && pSub1->op!=TK_ALL) 
  3434   3437          || pSub1->pSrc->nSrc<1
  3435         -       || pSub->pEList->nExpr!=pSub1->pEList->nExpr
  3436   3438         ){
  3437   3439           return 0;
  3438   3440         }
  3439   3441         testcase( pSub1->pSrc->nSrc>1 );
  3440   3442       }
  3441   3443   
  3442   3444       /* Restriction 18. */

Changes to src/shell.c.

    97     97   # define SHELL_USE_LOCAL_GETLINE 1
    98     98   #endif
    99     99   
   100    100   
   101    101   #if defined(_WIN32) || defined(WIN32)
   102    102   # include <io.h>
   103    103   # include <fcntl.h>
   104         -#define isatty(h) _isatty(h)
   105         -#ifndef access
   106         -# define access(f,m) _access((f),(m))
   107         -#endif
   108         -#undef popen
   109         -#define popen _popen
   110         -#undef pclose
   111         -#define pclose _pclose
          104  +# define isatty(h) _isatty(h)
          105  +# ifndef access
          106  +#  define access(f,m) _access((f),(m))
          107  +# endif
          108  +# undef popen
          109  +# define popen _popen
          110  +# undef pclose
          111  +# define pclose _pclose
   112    112   #else
   113         -/* Make sure isatty() has a prototype.
   114         -*/
   115         -extern int isatty(int);
          113  + /* Make sure isatty() has a prototype. */
          114  + extern int isatty(int);
   116    115   
   117         -#if !defined(__RTP__) && !defined(_WRS_KERNEL)
   118         -  /* popen and pclose are not C89 functions and so are sometimes omitted from
   119         -  ** the <stdio.h> header */
   120         -  extern FILE *popen(const char*,const char*);
   121         -  extern int pclose(FILE*);
   122         -#else
   123         -# define SQLITE_OMIT_POPEN 1
   124         -#endif
   125         -
          116  +# if !defined(__RTP__) && !defined(_WRS_KERNEL)
          117  +  /* popen and pclose are not C89 functions and so are
          118  +  ** sometimes omitted from the <stdio.h> header */
          119  +   extern FILE *popen(const char*,const char*);
          120  +   extern int pclose(FILE*);
          121  +# else
          122  +#  define SQLITE_OMIT_POPEN 1
          123  +# endif
   126    124   #endif
   127    125   
   128    126   #if defined(_WIN32_WCE)
   129    127   /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
   130    128    * thus we always assume that we have a console. That can be
   131    129    * overridden with the -batch command line option.
   132    130    */

Changes to src/sqliteInt.h.

  3578   3578   void sqlite3AlterFunctions(void);
  3579   3579   void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
  3580   3580   int sqlite3GetToken(const unsigned char *, int *);
  3581   3581   void sqlite3NestedParse(Parse*, const char*, ...);
  3582   3582   void sqlite3ExpirePreparedStatements(sqlite3*);
  3583   3583   int sqlite3CodeSubselect(Parse *, Expr *, int, int);
  3584   3584   void sqlite3SelectPrep(Parse*, Select*, NameContext*);
         3585  +void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
  3585   3586   int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
  3586   3587   int sqlite3ResolveExprNames(NameContext*, Expr*);
  3587   3588   void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
  3588   3589   void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
  3589   3590   int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
  3590   3591   void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
  3591   3592   void sqlite3AlterFinishAddColumn(Parse *, Token *);

Changes to src/treeview.c.

   174    174   
   175    175   /*
   176    176   ** Generate a human-readable explanation of an expression tree.
   177    177   */
   178    178   void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
   179    179     const char *zBinOp = 0;   /* Binary operator */
   180    180     const char *zUniOp = 0;   /* Unary operator */
          181  +  char zFlgs[30];
   181    182     pView = sqlite3TreeViewPush(pView, moreToFollow);
   182    183     if( pExpr==0 ){
   183    184       sqlite3TreeViewLine(pView, "nil");
   184    185       sqlite3TreeViewPop(pView);
   185    186       return;
          187  +  }
          188  +  if( pExpr->flags ){
          189  +    sqlite3_snprintf(sizeof(zFlgs),zFlgs,"  flags=0x%x",pExpr->flags);
          190  +  }else{
          191  +    zFlgs[0] = 0;
   186    192     }
   187    193     switch( pExpr->op ){
   188    194       case TK_AGG_COLUMN: {
   189         -      sqlite3TreeViewLine(pView, "AGG{%d:%d}",
   190         -            pExpr->iTable, pExpr->iColumn);
          195  +      sqlite3TreeViewLine(pView, "AGG{%d:%d}%s",
          196  +            pExpr->iTable, pExpr->iColumn, zFlgs);
   191    197         break;
   192    198       }
   193    199       case TK_COLUMN: {
   194    200         if( pExpr->iTable<0 ){
   195    201           /* This only happens when coding check constraints */
   196         -        sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
          202  +        sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
   197    203         }else{
   198         -        sqlite3TreeViewLine(pView, "{%d:%d}",
   199         -                             pExpr->iTable, pExpr->iColumn);
          204  +        sqlite3TreeViewLine(pView, "{%d:%d}%s",
          205  +                             pExpr->iTable, pExpr->iColumn, zFlgs);
   200    206         }
   201    207         break;
   202    208       }
   203    209       case TK_INTEGER: {
   204    210         if( pExpr->flags & EP_IntValue ){
   205    211           sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
   206    212         }else{
................................................................................
   385    391   #endif
   386    392       default: {
   387    393         sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
   388    394         break;
   389    395       }
   390    396     }
   391    397     if( zBinOp ){
   392         -    sqlite3TreeViewLine(pView, "%s", zBinOp);
          398  +    sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);
   393    399       sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
   394    400       sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
   395    401     }else if( zUniOp ){
   396         -    sqlite3TreeViewLine(pView, "%s", zUniOp);
          402  +    sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
   397    403       sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
   398    404     }
   399    405     sqlite3TreeViewPop(pView);
   400    406   }
   401    407   
   402    408   /*
   403    409   ** Generate a human-readable explanation of an expression list.

Changes to src/vdbe.c.

   588    588     assert( p->explain==0 );
   589    589     p->pResultSet = 0;
   590    590     db->busyHandler.nBusy = 0;
   591    591     if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
   592    592     sqlite3VdbeIOTraceSql(p);
   593    593   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   594    594     if( db->xProgress ){
          595  +    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
   595    596       assert( 0 < db->nProgressOps );
   596         -    nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
   597         -    if( nProgressLimit==0 ){
   598         -      nProgressLimit = db->nProgressOps;
   599         -    }else{
   600         -      nProgressLimit %= (unsigned)db->nProgressOps;
   601         -    }
          597  +    nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
   602    598     }
   603    599   #endif
   604    600   #ifdef SQLITE_DEBUG
   605    601     sqlite3BeginBenignMalloc();
   606    602     if( p->pc==0
   607    603      && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0
   608    604     ){

Changes to src/vdbemem.c.

   773    773   
   774    774   /*
   775    775   ** Make an shallow copy of pFrom into pTo.  Prior contents of
   776    776   ** pTo are freed.  The pFrom->z field is not duplicated.  If
   777    777   ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
   778    778   ** and flags gets srcType (either MEM_Ephem or MEM_Static).
   779    779   */
          780  +static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
          781  +  vdbeMemClearExternAndSetNull(pTo);
          782  +  assert( !VdbeMemDynamic(pTo) );
          783  +  sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
          784  +}
   780    785   void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
   781    786     assert( (pFrom->flags & MEM_RowSet)==0 );
   782    787     assert( pTo->db==pFrom->db );
   783         -  if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
          788  +  if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
   784    789     memcpy(pTo, pFrom, MEMCELLSIZE);
   785    790     if( (pFrom->flags&MEM_Static)==0 ){
   786    791       pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
   787    792       assert( srcType==MEM_Ephem || srcType==MEM_Static );
   788    793       pTo->flags |= srcType;
   789    794     }
   790    795   }

Changes to test/corruptI.test.

   200    200     PRAGMA auto_vacuum=0;
   201    201     CREATE TABLE t1(x);
   202    202     INSERT INTO t1 VALUES(zeroblob(300));
   203    203     INSERT INTO t1 VALUES(zeroblob(600));
   204    204   } {}
   205    205   do_test 6.1 {
   206    206     db close
   207         -  hexio_write test.db 616 EAFFFFFF0202
          207  +  hexio_write test.db 616 8FFFFFFF7F02
   208    208     sqlite3 db test.db
   209    209     breakpoint
   210    210     execsql { DELETE FROM t1 WHERE rowid=2 }
   211    211   } {}
   212    212   
   213    213   #-------------------------------------------------------------------------
   214    214   # See what happens if the sqlite_master entry associated with a PRIMARY

Changes to test/fuzzcheck.c.

     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13         -** This is a utility program designed to aid running regressions tests
    14         -** on SQLite library using data from an external fuzzer, such as American
           13  +** This is a utility program designed to aid running regressions tests on
           14  +** the SQLite library using data from an external fuzzer, such as American
    15     15   ** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
    16     16   **
    17     17   ** This program reads content from an SQLite database file with the following
    18     18   ** schema:
    19     19   **
    20     20   **     CREATE TABLE db(
    21     21   **       dbid INTEGER PRIMARY KEY, -- database id
    22     22   **       dbcontent BLOB            -- database disk file image
    23     23   **     );
    24     24   **     CREATE TABLE xsql(
    25     25   **       sqlid INTEGER PRIMARY KEY,   -- SQL script id
    26     26   **       sqltext TEXT                 -- Text of SQL statements to run
    27     27   **     );
           28  +**     CREATE TABLE IF NOT EXISTS readme(
           29  +**       msg TEXT -- Human-readable description of this test collection
           30  +**     );
    28     31   **
    29     32   ** For each database file in the DB table, the SQL text in the XSQL table
    30         -** is run against that database.  This program is looking for crashes,
    31         -** assertion faults, and/or memory leaks.  No attempt is made to verify
    32         -** the output.  The assumption is that either all of the database files
    33         -** or all of the SQL statements are malformed inputs, generated by a fuzzer,
    34         -** that need to be checked to make sure they do not present a security risk.
           33  +** is run against that database.  All README.MSG values are printed prior
           34  +** to the start of the test (unless the --quiet option is used).  If the
           35  +** DB table is empty, then all entries in XSQL are run against an empty
           36  +** in-memory database.
           37  +**
           38  +** This program is looking for crashes, assertion faults, and/or memory leaks.
           39  +** No attempt is made to verify the output.  The assumption is that either all
           40  +** of the database files or all of the SQL statements are malformed inputs,
           41  +** generated by a fuzzer, that need to be checked to make sure they do not
           42  +** present a security risk.
    35     43   **
    36     44   ** This program also includes some command-line options to help with 
    37         -** creation and maintenance of the source content database.
           45  +** creation and maintenance of the source content database.  The command
           46  +**
           47  +**     ./fuzzcheck database.db --load-sql FILE...
           48  +**
           49  +** Loads all FILE... arguments into the XSQL table.  The --load-db option
           50  +** works the same but loads the files into the DB table.  The -m option can
           51  +** be used to initialize the README table.  The "database.db" file is created
           52  +** if it does not previously exist.  Example:
           53  +**
           54  +**     ./fuzzcheck new.db --load-sql *.sql
           55  +**     ./fuzzcheck new.db --load-db *.db
           56  +**     ./fuzzcheck new.db -m 'New test cases'
           57  +**
           58  +** The three commands above will create the "new.db" file and initialize all
           59  +** tables.  Then do "./fuzzcheck new.db" to run the tests.
           60  +**
           61  +** DEBUGGING HINTS:
           62  +**
           63  +** If fuzzcheck does crash, it can be run in the debugger and the content
           64  +** of the global variable g.zTextName[] will identify the specific XSQL and
           65  +** DB values that were running when the crash occurred.
    38     66   */
    39     67   #include <stdio.h>
    40     68   #include <stdlib.h>
    41     69   #include <string.h>
    42     70   #include <stdarg.h>
    43     71   #include <ctype.h>
    44     72   #include "sqlite3.h"
           73  +
           74  +#ifdef __unix__
           75  +# include <signal.h>
           76  +# include <unistd.h>
           77  +#endif
    45     78   
    46     79   /*
    47     80   ** Files in the virtual file system.
    48     81   */
    49     82   typedef struct VFile VFile;
    50     83   struct VFile {
    51     84     char *zFilename;        /* Filename.  NULL for delete-on-close. From malloc() */
................................................................................
   107    140     va_start(ap, zFormat);
   108    141     vfprintf(stderr, zFormat, ap);
   109    142     va_end(ap);
   110    143     fprintf(stderr, "\n");
   111    144     exit(1);
   112    145   }
   113    146   
          147  +/*
          148  +** Timeout handler
          149  +*/
          150  +#ifdef __unix__
          151  +static void timeoutHandler(int NotUsed){
          152  +  (void)NotUsed;
          153  +  fatalError("timeout\n");
          154  +}
          155  +#endif
          156  +
          157  +/*
          158  +** Set the an alarm to go off after N seconds.  Disable the alarm
          159  +** if N==0
          160  +*/
          161  +static void setAlarm(int N){
          162  +#ifdef __unix__
          163  +  alarm(N);
          164  +#else
          165  +  (void)N;
          166  +#endif
          167  +}
          168  +
          169  +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
          170  +/*
          171  +** This an SQL progress handler.  After an SQL statement has run for
          172  +** many steps, we want to interrupt it.  This guards against infinite
          173  +** loops from recursive common table expressions.
          174  +**
          175  +** *pVdbeLimitFlag is true if the --limit-vdbe command-line option is used.
          176  +** In that case, hitting the progress handler is a fatal error.
          177  +*/
          178  +static int progressHandler(void *pVdbeLimitFlag){
          179  +  if( *(int*)pVdbeLimitFlag ) fatalError("too many VDBE cycles");
          180  +  return 1;
          181  +}
          182  +#endif
          183  +
   114    184   /*
   115    185   ** Reallocate memory.  Show and error and quit if unable.
   116    186   */
   117    187   static void *safe_realloc(void *pOld, int szNew){
   118    188     void *pNew = realloc(pOld, szNew);
   119    189     if( pNew==0 ) fatalError("unable to realloc for %d bytes", szNew);
   120    190     return pNew;
................................................................................
   582    652             }
   583    653           }
   584    654         }         
   585    655         sqlite3_finalize(pStmt);
   586    656       }
   587    657     }
   588    658   }
          659  +
          660  +/*
          661  +** Rebuild the database file.
          662  +**
          663  +**    (1)  Remove duplicate entries
          664  +**    (2)  Put all entries in order
          665  +**    (3)  Vacuum
          666  +*/
          667  +static void rebuild_database(sqlite3 *db){
          668  +  int rc;
          669  +  rc = sqlite3_exec(db, 
          670  +     "BEGIN;\n"
          671  +     "CREATE TEMP TABLE dbx AS SELECT DISTINCT dbcontent FROM db;\n"
          672  +     "DELETE FROM db;\n"
          673  +     "INSERT INTO db(dbid, dbcontent) SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n"
          674  +     "DROP TABLE dbx;\n"
          675  +     "CREATE TEMP TABLE sx AS SELECT DISTINCT sqltext FROM xsql;\n"
          676  +     "DELETE FROM xsql;\n"
          677  +     "INSERT INTO xsql(sqlid,sqltext) SELECT NULL, sqltext FROM sx ORDER BY 2;\n"
          678  +     "DROP TABLE sx;\n"
          679  +     "COMMIT;\n"
          680  +     "PRAGMA page_size=1024;\n"
          681  +     "VACUUM;\n", 0, 0, 0);
          682  +  if( rc ) fatalError("cannot rebuild: %s", sqlite3_errmsg(db));
          683  +}
   589    684   
   590    685   /*
   591    686   ** Print sketchy documentation for this utility program
   592    687   */
   593    688   static void showHelp(void){
   594    689     printf("Usage: %s [options] SOURCE-DB ?ARGS...?\n", g.zArgv0);
   595    690     printf(
   596    691   "Read databases and SQL scripts from SOURCE-DB and execute each script against\n"
   597    692   "each database, checking for crashes and memory leaks.\n"
   598    693   "Options:\n"
   599    694   "  --cell-size-check     Set the PRAGMA cell_size_check=ON\n"
   600    695   "  --dbid N              Use only the database where dbid=N\n"
   601         -"  --help                Show this help text\n"    
          696  +"  --help                Show this help text\n"
   602    697   "  -q                    Reduced output\n"
   603    698   "  --quiet               Reduced output\n"
          699  +"  --limit-vdbe          Panic if an sync SQL runs for more than 100,000 cycles\n"
   604    700   "  --load-sql ARGS...    Load SQL scripts fro files into SOURCE-DB\n"
   605    701   "  --load-db ARGS...     Load template databases from files into SOURCE_DB\n"
   606    702   "  -m TEXT               Add a description to the database\n"
   607    703   "  --native-vfs          Use the native VFS for initially empty database files\n"
          704  +"  --rebuild             Rebuild and vacuum the database file\n"
   608    705   "  --result-trace        Show the results of each SQL command\n"
   609    706   "  --sqlid N             Use only SQL where sqlid=N\n"
          707  +"  --timeline N          Abort if any single test case needs more than N seconds\n"
   610    708   "  -v                    Increased output\n"
   611    709   "  --verbose             Increased output\n"
   612    710     );
   613    711   }
   614    712   
   615    713   int main(int argc, char **argv){
   616    714     sqlite3_int64 iBegin;        /* Start time of this program */
................................................................................
   623    721     int rc;                      /* Result code from SQLite interface calls */
   624    722     Blob *pSql;                  /* For looping over SQL scripts */
   625    723     Blob *pDb;                   /* For looping over template databases */
   626    724     int i;                       /* Loop index for the argv[] loop */
   627    725     int onlySqlid = -1;          /* --sqlid */
   628    726     int onlyDbid = -1;           /* --dbid */
   629    727     int nativeFlag = 0;          /* --native-vfs */
          728  +  int rebuildFlag = 0;         /* --rebuild */
          729  +  int vdbeLimitFlag = 0;       /* --limit-vdbe */
          730  +  int timeoutTest = 0;         /* undocumented --timeout-test flag */
   630    731     int runFlags = 0;            /* Flags sent to runSql() */
   631    732     char *zMsg = 0;              /* Add this message */
   632    733     int nSrcDb = 0;              /* Number of source databases */
   633    734     char **azSrcDb = 0;          /* Array of source database names */
   634    735     int iSrcDb;                  /* Loop over all source databases */
   635    736     int nTest = 0;               /* Total number of tests performed */
   636    737     char *zDbName = "";          /* Appreviated name of a source database */
   637    738     const char *zFailCode = 0;   /* Value of the TEST_FAILURE environment variable */
   638    739     int cellSzCkFlag = 0;        /* --cell-size-check */
          740  +  int sqlFuzz = 0;             /* True for SQL fuzz testing. False for DB fuzz */
          741  +  int iTimeout = 120;          /* Default 120-second timeout */
   639    742   
   640    743     iBegin = timeOfDay();
          744  +#ifdef __unix__
          745  +  signal(SIGALRM, timeoutHandler);
          746  +#endif
   641    747     g.zArgv0 = argv[0];
   642    748     zFailCode = getenv("TEST_FAILURE");
   643    749     for(i=1; i<argc; i++){
   644    750       const char *z = argv[i];
   645    751       if( z[0]=='-' ){
   646    752         z++;
   647    753         if( z[0]=='-' ) z++;
................................................................................
   651    757         if( strcmp(z,"dbid")==0 ){
   652    758           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   653    759           onlyDbid = atoi(argv[++i]);
   654    760         }else
   655    761         if( strcmp(z,"help")==0 ){
   656    762           showHelp();
   657    763           return 0;
          764  +      }else
          765  +      if( strcmp(z,"limit-vdbe")==0 ){
          766  +        vdbeLimitFlag = 1;
   658    767         }else
   659    768         if( strcmp(z,"load-sql")==0 ){
   660    769           zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
   661    770           iFirstInsArg = i+1;
   662    771           break;
   663    772         }else
   664    773         if( strcmp(z,"load-db")==0 ){
................................................................................
   672    781         }else
   673    782         if( strcmp(z,"native-vfs")==0 ){
   674    783           nativeFlag = 1;
   675    784         }else
   676    785         if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
   677    786           quietFlag = 1;
   678    787           verboseFlag = 0;
          788  +      }else
          789  +      if( strcmp(z,"rebuild")==0 ){
          790  +        rebuildFlag = 1;
   679    791         }else
   680    792         if( strcmp(z,"result-trace")==0 ){
   681    793           runFlags |= SQL_OUTPUT;
   682    794         }else
   683    795         if( strcmp(z,"sqlid")==0 ){
   684    796           if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
   685    797           onlySqlid = atoi(argv[++i]);
          798  +      }else
          799  +      if( strcmp(z,"timeout")==0 ){
          800  +        if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
          801  +        iTimeout = atoi(argv[++i]);
          802  +      }else
          803  +      if( strcmp(z,"timeout-test")==0 ){
          804  +        timeoutTest = 1;
          805  +#ifndef __unix__
          806  +        fatalError("timeout is not available on non-unix systems");
          807  +#endif
   686    808         }else
   687    809         if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
   688    810           quietFlag = 0;
   689    811           verboseFlag = 1;
   690    812           runFlags |= SQL_TRACE;
   691    813         }else
   692    814         {
................................................................................
   711    833     /* Process each source database separately */
   712    834     for(iSrcDb=0; iSrcDb<nSrcDb; iSrcDb++){
   713    835       rc = sqlite3_open(azSrcDb[iSrcDb], &db);
   714    836       if( rc ){
   715    837         fatalError("cannot open source database %s - %s",
   716    838         azSrcDb[iSrcDb], sqlite3_errmsg(db));
   717    839       }
   718         -    rc = sqlite3_exec(db, 
          840  +    rc = sqlite3_exec(db,
   719    841          "CREATE TABLE IF NOT EXISTS db(\n"
   720    842          "  dbid INTEGER PRIMARY KEY, -- database id\n"
   721    843          "  dbcontent BLOB            -- database disk file image\n"
   722    844          ");\n"
   723    845          "CREATE TABLE IF NOT EXISTS xsql(\n"
   724    846          "  sqlid INTEGER PRIMARY KEY,   -- SQL script id\n"
   725    847          "  sqltext TEXT                 -- Text of SQL statements to run\n"
................................................................................
   749    871           sqlite3_step(pStmt);
   750    872           rc = sqlite3_reset(pStmt);
   751    873           if( rc ) fatalError("insert failed for %s", argv[i]);
   752    874         }
   753    875         sqlite3_finalize(pStmt);
   754    876         rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
   755    877         if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
          878  +      rebuild_database(db);
   756    879         sqlite3_close(db);
   757    880         return 0;
   758    881       }
   759    882     
   760    883       /* Load all SQL script content and all initial database images from the
   761    884       ** source db
   762    885       */
................................................................................
   767    890                          &g.nDb, &g.pFirstDb);
   768    891       if( g.nDb==0 ){
   769    892         g.pFirstDb = safe_realloc(0, sizeof(Blob));
   770    893         memset(g.pFirstDb, 0, sizeof(Blob));
   771    894         g.pFirstDb->id = 1;
   772    895         g.pFirstDb->seq = 0;
   773    896         g.nDb = 1;
          897  +      sqlFuzz = 1;
   774    898       }
   775    899     
   776    900       /* Print the description, if there is one */
   777    901       if( !quietFlag ){
   778    902         int i;
   779    903         zDbName = azSrcDb[iSrcDb];
   780    904         i = strlen(zDbName) - 1;
................................................................................
   782    906         zDbName += i;
   783    907         sqlite3_prepare_v2(db, "SELECT msg FROM readme", -1, &pStmt, 0);
   784    908         if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
   785    909           printf("%s: %s\n", zDbName, sqlite3_column_text(pStmt,0));
   786    910         }
   787    911         sqlite3_finalize(pStmt);
   788    912       }
          913  +
          914  +    /* Rebuild the database, if requested */
          915  +    if( rebuildFlag ){
          916  +      if( !quietFlag ){
          917  +        printf("%s: rebuilding... ", zDbName);
          918  +        fflush(stdout);
          919  +      }
          920  +      rebuild_database(db);
          921  +      if( !quietFlag ) printf("done\n");
          922  +    }
   789    923     
   790    924       /* Close the source database.  Verify that no SQLite memory allocations are
   791    925       ** outstanding.
   792    926       */
   793    927       sqlite3_close(db);
   794    928       if( sqlite3_memory_used()>0 ){
   795    929         fatalError("SQLite has memory in use before the start of testing");
................................................................................
   827    961           if( nativeFlag && pDb->sz==0 ){
   828    962             openFlags |= SQLITE_OPEN_MEMORY;
   829    963             zVfs = 0;
   830    964           }
   831    965           rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
   832    966           if( rc ) fatalError("cannot open inmem database");
   833    967           if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
   834         -        runSql(db, (char*)pSql->a, runFlags);
          968  +        setAlarm(iTimeout);
          969  +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
          970  +        if( sqlFuzz || vdbeLimitFlag ){
          971  +          sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag);
          972  +        }
          973  +#endif
          974  +        do{
          975  +          runSql(db, (char*)pSql->a, runFlags);
          976  +        }while( timeoutTest );
          977  +        setAlarm(0);
   835    978           sqlite3_close(db);
   836    979           if( sqlite3_memory_used()>0 ) fatalError("memory leak");
   837    980           reformatVfs();
   838    981           nTest++;
   839    982           g.zTestName[0] = 0;
   840    983   
   841    984           /* Simulate an error if the TEST_FAILURE environment variable is "5".

Changes to test/fuzzdata1.db.

cannot compute difference between binary files

Changes to test/fuzzdata3.db.

cannot compute difference between binary files

Changes to test/in.test.

   446    446   ifcapable compound {
   447    447   do_test in-12.10 {
   448    448     catchsql {
   449    449       SELECT * FROM t2 WHERE a IN (
   450    450         SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
   451    451       );
   452    452     }
   453         -} {1 {only a single result allowed for a SELECT that is part of an expression}}
          453  +} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
   454    454   do_test in-12.11 {
   455    455     catchsql {
   456    456       SELECT * FROM t2 WHERE a IN (
   457    457         SELECT a FROM t3 UNION SELECT a, b FROM t2
   458    458       );
   459    459     }
   460         -} {1 {only a single result allowed for a SELECT that is part of an expression}}
          460  +} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
   461    461   do_test in-12.12 {
   462    462     catchsql {
   463    463       SELECT * FROM t2 WHERE a IN (
   464    464         SELECT a FROM t3 EXCEPT SELECT a, b FROM t2
   465    465       );
   466    466     }
   467         -} {1 {only a single result allowed for a SELECT that is part of an expression}}
          467  +} {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}}
   468    468   do_test in-12.13 {
   469    469     catchsql {
   470    470       SELECT * FROM t2 WHERE a IN (
   471    471         SELECT a FROM t3 INTERSECT SELECT a, b FROM t2
   472    472       );
          473  +  }
          474  +} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}}
          475  +do_test in-12.14 {
          476  +  catchsql {
          477  +    SELECT * FROM t2 WHERE a IN (
          478  +      SELECT a, b FROM t3 UNION ALL SELECT a, b FROM t2
          479  +    );
   473    480     }
   474    481   } {1 {only a single result allowed for a SELECT that is part of an expression}}
          482  +do_test in-12.15 {
          483  +  catchsql {
          484  +    SELECT * FROM t2 WHERE a IN (
          485  +      SELECT a, b FROM t3 UNION ALL SELECT a FROM t2
          486  +    );
          487  +  }
          488  +} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
   475    489   }; #ifcapable compound
   476    490   
   477    491   
   478    492   #------------------------------------------------------------------------
   479    493   # The following tests check that NULL is handled correctly when it 
   480    494   # appears as part of a set of values on the right-hand side of an
   481    495   # IN or NOT IN operator.

Changes to test/malloc5.test.

   185    185       SELECT * FROM abc;
   186    186     }
   187    187     execsql {
   188    188       SELECT * FROM sqlite_master;
   189    189       BEGIN;
   190    190       SELECT * FROM def;
   191    191     } db2
   192         -  sqlite3_release_memory
   193         -} [expr $::pgalloc * 2]
          192  +  value_in_range [expr $::pgalloc*2] 0.99 [sqlite3_release_memory]
          193  +} [value_in_range [expr $::pgalloc * 2] 0.99]
   194    194   do_test malloc5-3.2 {
   195    195     concat \
   196    196       [execsql {SELECT * FROM abc; COMMIT}] \
   197    197       [execsql {SELECT * FROM def; COMMIT} db2]
   198    198   } {1 2 3 4 5 6 7 8 9 10 11 12}
   199    199   
   200    200   db2 close

Changes to test/select7.test.

    11     11   # views.
    12     12   #
    13     13   # $Id: select7.test,v 1.11 2007/09/12 17:01:45 danielk1977 Exp $
    14     14   
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
           18  +set testprefix select7
    18     19   
    19     20   ifcapable compound {
    20     21   
    21     22   # A 3-way INTERSECT.  Ticket #875
    22     23   ifcapable tempdb {
    23     24     do_test select7-1.1 {
    24     25       execsql {
................................................................................
   196    197   do_test select7-7.7 {
   197    198     execsql {
   198    199       CREATE TABLE t5(a TEXT, b INT);
   199    200       INSERT INTO t5 VALUES(123, 456);
   200    201       SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
   201    202     }
   202    203   } {text 123}
          204  +
          205  +do_execsql_test 8.0 { 
          206  +  CREATE TABLE t01(x, y);
          207  +  CREATE TABLE t02(x, y);
          208  +}
          209  +
          210  +do_catchsql_test 8.1 {
          211  +  SELECT * FROM (
          212  +    SELECT * FROM t01 UNION SELECT x FROM t02
          213  +  ) WHERE y=1
          214  +} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
          215  +
          216  +do_catchsql_test 8.2 {
          217  +  CREATE VIEW v0 as SELECT x, y FROM t01 UNION SELECT x FROM t02;
          218  +  EXPLAIN QUERY PLAN SELECT * FROM v0 WHERE x='0' OR y;
          219  +} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
          220  +
   203    221   
   204    222   finish_test
          223  +
          224  +

Changes to test/speedtest1.c.

    39     39   #include <assert.h>
    40     40   #include <stdio.h>
    41     41   #include <stdlib.h>
    42     42   #include <stdarg.h>
    43     43   #include <string.h>
    44     44   #include <ctype.h>
    45     45   
           46  +#if SQLITE_VERSION_NUMBER<3005000
           47  +# define sqlite3_int64 sqlite_int64
           48  +#endif
    46     49   #ifdef SQLITE_ENABLE_OTA
    47     50   # include "sqlite3ota.h"
    48     51   #endif
    49     52   
    50     53   /* All global state is held in this structure */
    51     54   static struct Global {
    52     55     sqlite3 *db;               /* The open database connection */
................................................................................
   139    142     }
   140    143     if( v>0x7fffffff ) fatal_error("parameter too large - max 2147483648");
   141    144     return (int)(isNeg? -v : v);
   142    145   }
   143    146   
   144    147   /* Return the current wall-clock time, in milliseconds */
   145    148   sqlite3_int64 speedtest1_timestamp(void){
          149  +#if SQLITE_VERSION_NUMBER<3005000
          150  +  return 0;
          151  +#else
   146    152     static sqlite3_vfs *clockVfs = 0;
   147    153     sqlite3_int64 t;
   148    154     if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
   149    155   #if SQLITE_VERSION_NUMBER>=3007000
   150    156     if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
   151    157       clockVfs->xCurrentTimeInt64(clockVfs, &t);
   152    158     }else
................................................................................
   153    159   #endif
   154    160     {
   155    161       double r;
   156    162       clockVfs->xCurrentTime(clockVfs, &r);
   157    163       t = (sqlite3_int64)(r*86400000.0);
   158    164     }
   159    165     return t;
          166  +#endif
   160    167   }
   161    168   
   162    169   /* Return a pseudo-random unsigned integer */
   163    170   unsigned int speedtest1_random(void){
   164    171     g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001);
   165    172     g.y = g.y*1103515245 + 12345;
   166    173     return g.x ^ g.y;
................................................................................
   302    309   /* Print an SQL statement to standard output */
   303    310   static void printSql(const char *zSql){
   304    311     int n = (int)strlen(zSql);
   305    312     while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; }
   306    313     if( g.bExplain ) printf("EXPLAIN ");
   307    314     printf("%.*s;\n", n, zSql);
   308    315     if( g.bExplain
   309         -#if SQLITE_VERSION_NUMBER>=3007010 
          316  +#if SQLITE_VERSION_NUMBER>=3007017 
   310    317      && ( sqlite3_strglob("CREATE *", zSql)==0
   311    318        || sqlite3_strglob("DROP *", zSql)==0
   312    319        || sqlite3_strglob("ALTER *", zSql)==0
   313    320         )
   314    321   #endif
   315    322     ){
   316    323       printf("%.*s;\n", n, zSql);
................................................................................
   370    377         if( g.nResult+len<sizeof(g.zResult)-2 ){
   371    378           if( g.nResult>0 ) g.zResult[g.nResult++] = ' ';
   372    379           memcpy(g.zResult + g.nResult, z, len+1);
   373    380           g.nResult += len;
   374    381         }
   375    382       }
   376    383     }
          384  +#if SQLITE_VERSION_NUMBER>=3006001
   377    385     if( g.bReprepare ){
   378    386       sqlite3_stmt *pNew;
   379    387       sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
   380    388       sqlite3_finalize(g.pStmt);
   381    389       g.pStmt = pNew;
   382         -  }else{
          390  +  }else
          391  +#endif
          392  +  {
   383    393       sqlite3_reset(g.pStmt);
   384    394     }
   385    395   }
   386    396   
   387    397   /* The sqlite3_trace() callback function */
   388    398   static void traceCallback(void *NotUsed, const char *zSql){
   389    399     int n = (int)strlen(zSql);
................................................................................
  1269   1279       }
  1270   1280     }
  1271   1281   #if 0
  1272   1282     if( zDbName==0 ){
  1273   1283       fatal_error(zHelp, argv[0]);
  1274   1284     }
  1275   1285   #endif
         1286  +#if SQLITE_VERSION_NUMBER>=3006001
  1276   1287     if( nHeap>0 ){
  1277   1288       pHeap = malloc( nHeap );
  1278   1289       if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
  1279   1290       rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
  1280   1291       if( rc ) fatal_error("heap configuration failed: %d\n", rc);
  1281   1292     }
  1282   1293     if( nPCache>0 && szPCache>0 ){
................................................................................
  1292   1303                                    nScratch*(sqlite3_int64)szScratch);
  1293   1304       rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
  1294   1305       if( rc ) fatal_error("scratch configuration failed: %d\n", rc);
  1295   1306     }
  1296   1307     if( nLook>0 ){
  1297   1308       sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
  1298   1309     }
         1310  +#endif
  1299   1311    
  1300   1312     /* Open the database and the input file */
  1301   1313     if( sqlite3_open(zDbName, &g.db) ){
  1302   1314       fatal_error("Cannot open database file: %s\n", zDbName);
  1303   1315     }
         1316  +#if SQLITE_VERSION_NUMBER>=3006001
  1304   1317     if( nLook>0 && szLook>0 ){
  1305   1318       pLook = malloc( nLook*szLook );
  1306   1319       rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
  1307   1320       if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
  1308   1321     }
         1322  +#endif
  1309   1323   
  1310   1324     /* Set database connection options */
  1311   1325     sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
  1312   1326     if( doTrace ) sqlite3_trace(g.db, traceCallback, 0);
  1313   1327     speedtest1_exec("PRAGMA threads=%d", nThread);
  1314   1328     if( zKey ){
  1315   1329       speedtest1_exec("PRAGMA key('%s')", zKey);
................................................................................
  1383   1397       sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0);
  1384   1398       printf("-- Statement Heap Usage:        %d bytes\n", iCur); 
  1385   1399     }
  1386   1400   #endif
  1387   1401   
  1388   1402     sqlite3_close(g.db);
  1389   1403   
         1404  +#if SQLITE_VERSION_NUMBER>=3006001
  1390   1405     /* Global memory usage statistics printed after the database connection
  1391   1406     ** has closed.  Memory usage should be zero at this point. */
  1392   1407     if( showStats ){
  1393   1408       sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0);
  1394   1409       printf("-- Memory Used (bytes):         %d (max %d)\n", iCur,iHi);
  1395   1410   #if SQLITE_VERSION_NUMBER>=3007000
  1396   1411       sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0);
................................................................................
  1403   1418       sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0);
  1404   1419       printf("-- Largest Allocation:          %d bytes\n",iHi);
  1405   1420       sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
  1406   1421       printf("-- Largest Pcache Allocation:   %d bytes\n",iHi);
  1407   1422       sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
  1408   1423       printf("-- Largest Scratch Allocation:  %d bytes\n", iHi);
  1409   1424     }
         1425  +#endif
  1410   1426   
  1411   1427     /* Release memory */
  1412   1428     free( pLook );
  1413   1429     free( pPCache );
  1414   1430     free( pScratch );
  1415   1431     free( pHeap );
  1416   1432     return 0;
  1417   1433   }

Changes to test/spellfix.test.

   279    279     do_tracesql_test 6.2.3 {
   280    280       SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
   281    281     } {keener 300
   282    282       {SELECT id, word, rank, k1  FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
   283    283     }
   284    284   }
   285    285   
          286  +#------------------------------------------------------------------------- 
          287  +# Test that the spellfix1 table supports conflict handling (OR REPLACE 
          288  +# and so on).
          289  +#
          290  +do_execsql_test 7.1 {
          291  +  CREATE VIRTUAL TABLE t4 USING spellfix1;
          292  +  PRAGMA table_info = t4;
          293  +} {
          294  +  0 word {} 0 {} 0 
          295  +  1 rank {} 0 {} 0 
          296  +  2 distance {} 0 {} 0 
          297  +  3 langid {} 0 {} 0 
          298  +  4 score {} 0 {} 0 
          299  +  5 matchlen {} 0 {} 0
          300  +}
          301  +
          302  +do_execsql_test 7.2.1 {
          303  +  INSERT INTO t4(rowid, word) VALUES(1, 'Archilles');
          304  +  INSERT INTO t4(rowid, word) VALUES(2, 'Pluto');
          305  +  INSERT INTO t4(rowid, word) VALUES(3, 'Atrides');
          306  +  INSERT OR REPLACE INTO t4(rowid, word) VALUES(2, 'Apollo');
          307  +  SELECT rowid, word FROM t4;
          308  +} {
          309  +  1 Archilles   2 Apollo   3 Atrides
          310  +}
          311  +do_catchsql_test 7.2.2 {
          312  +  INSERT OR ABORT INTO t4(rowid, word) VALUES(1, 'Leto');
          313  +} {1 {constraint failed}}
          314  +do_catchsql_test 7.2.3 {
          315  +  INSERT OR ROLLBACK INTO t4(rowid, word) VALUES(3, 'Zeus');
          316  +} {1 {constraint failed}}
          317  +do_catchsql_test 7.2.4 {
          318  +  INSERT OR FAIL INTO t4(rowid, word) VALUES(3, 'Zeus');
          319  +} {1 {constraint failed}}
          320  +do_execsql_test 7.2.5 {
          321  +  INSERT OR IGNORE INTO t4(rowid, word) VALUES(3, 'Zeus');
          322  +  SELECT rowid, word FROM t4;
          323  +} {
          324  +  1 Archilles   2 Apollo   3 Atrides
          325  +}
          326  +
          327  +do_execsql_test 7.3.1 {
          328  +  UPDATE OR REPLACE t4 SET rowid=3 WHERE rowid=1;
          329  +  SELECT rowid, word FROM t4;
          330  +} {2 Apollo 3 Archilles}
          331  +do_catchsql_test 7.3.2 {
          332  +  UPDATE OR ABORT t4 SET rowid=3 WHERE rowid=2;
          333  +} {1 {constraint failed}}
          334  +do_catchsql_test 7.3.3 {
          335  +  UPDATE OR ROLLBACK t4 SET rowid=3 WHERE rowid=2;
          336  +} {1 {constraint failed}}
          337  +do_catchsql_test 7.3.4 {
          338  +  UPDATE OR FAIL t4 SET rowid=3 WHERE rowid=2;
          339  +} {1 {constraint failed}}
          340  +do_execsql_test 7.3.5 {
          341  +  UPDATE OR IGNORE t4 SET rowid=3 WHERE rowid=2;
          342  +  SELECT rowid, word FROM t4;
          343  +} {2 Apollo  3 Archilles}
          344  +
          345  +do_execsql_test 7.4.1 {
          346  +  DELETE FROM t4;
          347  +  INSERT INTO t4(rowid, word) VALUES(10, 'Agamemnon');
          348  +  INSERT INTO t4(rowid, word) VALUES(20, 'Patroclus');
          349  +  INSERT INTO t4(rowid, word) VALUES(30, 'Chryses');
          350  +
          351  +  CREATE TABLE t5(i, w);
          352  +  INSERT INTO t5 VALUES(5,  'Poseidon');
          353  +  INSERT INTO t5 VALUES(20, 'Chronos');
          354  +  INSERT INTO t5 VALUES(30, 'Hera');
          355  +}
          356  +
          357  +db_save_and_close
          358  +foreach {tn conflict err bRollback res} {
          359  +  0 ""            {1 {constraint failed}} 0
          360  +                  {10 Agamemnon 20 Patroclus 30 Chryses}
          361  +  1 "OR REPLACE"  {0 {}} 0
          362  +                  {5 Poseidon 10 Agamemnon 20 Chronos 30 Hera}
          363  +  2 "OR ABORT"    {1 {constraint failed}} 0
          364  +                  {10 Agamemnon 20 Patroclus 30 Chryses}
          365  +  3 "OR ROLLBACK" {1 {constraint failed}} 1
          366  +                  {10 Agamemnon 20 Patroclus 30 Chryses}
          367  +  5 "OR IGNORE"   {0 {}} 0
          368  +                  {5 Poseidon 10 Agamemnon 20 Patroclus 30 Chryses}
          369  +} {
          370  +  db_restore_and_reopen
          371  +  load_static_extension db spellfix nextchar
          372  +
          373  +  execsql BEGIN
          374  +  set sql "INSERT $conflict INTO t4(rowid, word) SELECT i, w FROM t5"
          375  +  do_catchsql_test 7.4.2.$tn.1 $sql $err
          376  +  do_execsql_test 7.4.2.$tn.2 { SELECT rowid, word FROM t4 } $res
          377  +
          378  +  do_test 7.4.2.$tn.3 { sqlite3_get_autocommit db } $bRollback
          379  +  catchsql ROLLBACK
          380  +}
   286    381   
          382  +foreach {tn conflict err bRollback res} {
          383  +  0 ""            {1 {constraint failed}} 0
          384  +                  {10 Agamemnon 20 Patroclus 30 Chryses}
          385  +  1 "OR REPLACE"  {0 {}} 0
          386  +                  {15 Agamemnon 45 Chryses}
          387  +  2 "OR ABORT"    {1 {constraint failed}} 0
          388  +                  {10 Agamemnon 20 Patroclus 30 Chryses}
          389  +  3 "OR ROLLBACK" {1 {constraint failed}} 1
          390  +                  {10 Agamemnon 20 Patroclus 30 Chryses}
          391  +  5 "OR IGNORE"   {0 {}} 0
          392  +                  {15 Agamemnon 20 Patroclus 45 Chryses}
          393  +} {
          394  +  db_restore_and_reopen
          395  +  load_static_extension db spellfix nextchar
   287    396   
          397  +  execsql BEGIN
          398  +  set sql "UPDATE $conflict t4 SET rowid=rowid + (rowid/2)"
          399  +  do_catchsql_test 7.5.2.$tn.1 $sql $err
          400  +  do_execsql_test 7.5.2.$tn.2 { SELECT rowid, word FROM t4 } $res
          401  +  do_test 7.5.2.$tn.3 { sqlite3_get_autocommit db } $bRollback
          402  +  catchsql ROLLBACK
          403  +}
   288    404   
   289    405   finish_test
          406  +

Changes to test/whereG.test.

   225    225   } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}}
   226    226   do_eqp_test 5.3.2 {
   227    227     SELECT * FROM t1 WHERE likelihood(a=?, 0.9)
   228    228   } {0 0 0 {SCAN TABLE t1}}
   229    229   do_eqp_test 5.3.3 {
   230    230     SELECT * FROM t1 WHERE likely(a=?)
   231    231   } {0 0 0 {SCAN TABLE t1}}
          232  +
          233  +# 2015-06-18
          234  +# Ticket [https://www.sqlite.org/see/tktview/472f0742a1868fb58862bc588ed70]
          235  +#
          236  +do_execsql_test 6.0 {
          237  +  DROP TABLE IF EXISTS t1;
          238  +  CREATE TABLE t1(i int, x, y, z);
          239  +  INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4);
          240  +  DROP TABLE IF EXISTS t2;
          241  +  CREATE TABLE t2(i int, bool char);
          242  +  INSERT INTO t2 VALUES(1,'T'), (2,'F');
          243  +  SELECT count(*) FROM t1 LEFT JOIN t2 ON t1.i=t2.i AND bool='T';
          244  +  SELECT count(*) FROM t1 LEFT JOIN t2 ON likely(t1.i=t2.i) AND bool='T';
          245  +} {4 4}
          246  +
          247  +# 2015-06-20
          248  +# Crash discovered by AFL
          249  +#
          250  +do_execsql_test 7.0 {
          251  +  DROP TABLE IF EXISTS t1;
          252  +  CREATE TABLE t1(a, b, PRIMARY KEY(a,b));
          253  +  INSERT INTO t1 VALUES(9,1),(1,2);
          254  +  DROP TABLE IF EXISTS t2;
          255  +  CREATE TABLE t2(x, y, PRIMARY KEY(x,y));
          256  +  INSERT INTO t2 VALUES(3,3),(4,4);
          257  +  SELECT likely(a), x FROM t1, t2 ORDER BY 1, 2;
          258  +} {1 3 1 4 9 3 9 4}
          259  +do_execsql_test 7.1 {
          260  +  SELECT unlikely(a), x FROM t1, t2 ORDER BY 1, 2;
          261  +} {1 3 1 4 9 3 9 4}
          262  +do_execsql_test 7.2 {
          263  +  SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2;
          264  +} {1 3 1 4 9 3 9 4}
          265  +do_execsql_test 7.3 {
          266  +  SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2;
          267  +} {1 3 1 4 9 3 9 4}
          268  +
   232    269   
   233    270   finish_test