SQLite

Check-in [93f811ec74]
Login

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

Overview
Comment:Change a few selected functions to macros to speed things up. (CVS 4015)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 93f811ec747f6a42daf9ee27cd8b013f248552a1
User & Date: danielk1977 2007-05-16 17:28:43.000
Context
2007-05-16
17:50
Avoid passing a negative value to isspace() in a couple places. (CVS 4016) (check-in: d5db8be368 user: danielk1977 tags: trunk)
17:28
Change a few selected functions to macros to speed things up. (CVS 4015) (check-in: 93f811ec74 user: danielk1977 tags: trunk)
14:23
Omit some extra code when OMIT_INCRBLOB is defined. (CVS 4014) (check-in: 1d89be287d user: danielk1977 tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19











-
+







/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.381 2007/05/12 10:41:48 danielk1977 Exp $
** $Id: btree.c,v 1.382 2007/05/16 17:28:43 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

415
416
417
418
419
420
421


422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

448
449
450
451
452
453
454



455
456
457
458
459
460
461
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466







+
+




-
+




















-
+







+
+
+







/*
** Given a btree page and a cell index (0 means the first cell on
** the page, 1 means the second cell, and so forth) return a pointer
** to the cell content.
**
** This routine works only for pages that do not contain overflow cells.
*/
#define findCell(pPage, iCell) \
  ((pPage)->aData + get2byte(&(pPage)->aData[(pPage)->cellOffset+2*(iCell)]))
u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){
  u8 *data = pPage->aData;
  assert( iCell>=0 );
  assert( iCell<get2byte(&data[pPage->hdrOffset+3]) );
  return data + get2byte(&data[pPage->cellOffset+2*iCell]);
  return findCell(pPage, iCell);
}

/*
** This a more complex version of sqlite3BtreeFindCell() that works for
** pages that do contain overflow cells.  See insert
*/
static u8 *findOverflowCell(MemPage *pPage, int iCell){
  int i;
  for(i=pPage->nOverflow-1; i>=0; i--){
    int k;
    struct _OvflCell *pOvfl;
    pOvfl = &pPage->aOvfl[i];
    k = pOvfl->idx;
    if( k<=iCell ){
      if( k==iCell ){
        return pOvfl->pCell;
      }
      iCell--;
    }
  }
  return sqlite3BtreeFindCell(pPage, iCell);
  return findCell(pPage, iCell);
}

/*
** Parse a cell content block and fill in the CellInfo structure.  There
** are two versions of this function.  sqlite3BtreeParseCell() takes a 
** cell index as the second argument and sqlite3BtreeParseCellPtr() 
** takes a pointer to the body of the cell as its second argument.
**
** Within this file, the parseCell() macro can be called instead of
** sqlite3BtreeParseCellPtr(). Using some compilers, this will be faster.
*/
void sqlite3BtreeParseCellPtr(
  MemPage *pPage,         /* Page containing the cell */
  u8 *pCell,              /* Pointer to the cell text. */
  CellInfo *pInfo         /* Fill in this structure */
){
  int n;                  /* Number bytes in cell content header */
515
516
517
518
519
520
521


522
523
524
525
526
527

528
529
530
531
532
533
534
520
521
522
523
524
525
526
527
528
529
530
531
532
533

534
535
536
537
538
539
540
541







+
+





-
+







    }else{
      pInfo->nLocal = minLocal;
    }
    pInfo->iOverflow = pInfo->nLocal + n;
    pInfo->nSize = pInfo->iOverflow + 4;
  }
}
#define parseCell(pPage, iCell, pInfo) \
  sqlite3BtreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
void sqlite3BtreeParseCell(
  MemPage *pPage,         /* Page containing the cell */
  int iCell,              /* The cell index.  First cell is 0 */
  CellInfo *pInfo         /* Fill in this structure */
){
  sqlite3BtreeParseCellPtr(pPage, sqlite3BtreeFindCell(pPage, iCell), pInfo);
  parseCell(pPage, iCell, pInfo);
}

/*
** Compute the total number of bytes that a Cell needs in the cell
** data area of the btree-page.  The return number includes the cell
** data header and the local payload, but not any overflow page or
** the space used by the cell pointer.
1657
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667
1668
1669
1670
1671
1664
1665
1666
1667
1668
1669
1670

1671
1672
1673
1674
1675
1676
1677
1678







-
+







  int isInitOrig = pPage->isInit;
  Pgno pgno = pPage->pgno;

  sqlite3BtreeInitPage(pPage, 0);
  nCell = pPage->nCell;

  for(i=0; i<nCell; i++){
    u8 *pCell = sqlite3BtreeFindCell(pPage, i);
    u8 *pCell = findCell(pPage, i);

    rc = ptrmapPutOvflPtr(pPage, pCell);
    if( rc!=SQLITE_OK ){
      goto set_child_ptrmaps_out;
    }

    if( !pPage->leaf ){
1712
1713
1714
1715
1716
1717
1718
1719

1720
1721
1722
1723
1724
1725
1726
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1733







-
+







    int i;
    int nCell;

    sqlite3BtreeInitPage(pPage, 0);
    nCell = pPage->nCell;

    for(i=0; i<nCell; i++){
      u8 *pCell = sqlite3BtreeFindCell(pPage, i);
      u8 *pCell = findCell(pPage, i);
      if( eType==PTRMAP_OVERFLOW1 ){
        CellInfo info;
        sqlite3BtreeParseCellPtr(pPage, pCell, &info);
        if( info.iOverflow ){
          if( iFrom==get4byte(&pCell[info.iOverflow]) ){
            put4byte(&pCell[info.iOverflow], iTo);
            break;
2451
2452
2453
2454
2455
2456
2457


2458
2459


2460
2461
2462
2463
2464
2465
2466
2467
2468

2469
2470
2471
2472



2473
2474
2475







2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492

2493
2494
2495
2496
2497
2498
2499
2458
2459
2460
2461
2462
2463
2464
2465
2466


2467
2468
2469
2470
2471
2472




2473
2474
2475
2476
2477
2478
2479
2480
2481
2482


2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505

2506
2507
2508
2509
2510
2511
2512
2513







+
+
-
-
+
+




-
-
-
-

+




+
+
+

-
-
+
+
+
+
+
+
+
















-
+







void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){
  if( pCur->pPage ){
    sqlite3PagerUnref(pCur->pPage->pDbPage);
  }
}

/*
** The GET_CELL_INFO() macro. Takes one argument, a pointer to a valid
** btree cursor (type BtCursor*).  This macro makes sure the BtCursor.info
** Make sure the BtCursor.info field of the given cursor is valid.
** If it is not already valid, call sqlite3BtreeParseCell() to fill it in.
** field of the given cursor is valid.  If it is not already valid, call
** sqlite3BtreeParseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to sqlite3BtreeParseCell().
*/
static void getCellInfo(BtCursor *pCur){
  if( pCur->info.nSize==0 ){
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);
  }else{
#ifndef NDEBUG
  static void assertCellInfo(BtCursor *pCur){
    CellInfo info;
    memset(&info, 0, sizeof(info));
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &info);
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
  }
#else
  #define assertCellInfo(x)
#endif
  }
}

#define GET_CELL_INFO(pCur)                                             \
  if( pCur->info.nSize==0 )                                             \
    sqlite3BtreeParseCell(pCur->pPage, pCur->idx, &pCur->info);         \
  else                                                                  \
    assertCellInfo(pCur);
   

/*
** Set *pSize to the size of the buffer needed to hold the value of
** the key for the current entry.  If the cursor is not pointing
** to a valid entry, *pSize is set to 0. 
**
** For a table with the INTKEY flag set, this routine returns the key
** itself, not the number of bytes in the key.
*/
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
  int rc = restoreOrClearCursorPosition(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
    if( pCur->eState==CURSOR_INVALID ){
      *pSize = 0;
    }else{
      getCellInfo(pCur);
      GET_CELL_INFO(pCur);
      *pSize = pCur->info.nKey;
    }
  }
  return rc;
}

/*
2507
2508
2509
2510
2511
2512
2513
2514

2515
2516
2517
2518
2519
2520
2521
2521
2522
2523
2524
2525
2526
2527

2528
2529
2530
2531
2532
2533
2534
2535







-
+







  int rc = restoreOrClearCursorPosition(pCur);
  if( rc==SQLITE_OK ){
    assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
    if( pCur->eState==CURSOR_INVALID ){
      /* Not pointing at a valid entry - set *pSize to 0. */
      *pSize = 0;
    }else{
      getCellInfo(pCur);
      GET_CELL_INFO(pCur);
      *pSize = pCur->info.nData;
    }
  }
  return rc;
}

/*
2680
2681
2682
2683
2684
2685
2686
2687

2688
2689
2690
2691
2692
2693
2694
2694
2695
2696
2697
2698
2699
2700

2701
2702
2703
2704
2705
2706
2707
2708







-
+







  BtShared *pBt = pCur->pBtree->pBt;   /* Btree this cursor belongs to */

  assert( pPage );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  assert( offset>=0 );

  getCellInfo(pCur);
  GET_CELL_INFO(pCur);
  aPayload = pCur->info.pCell + pCur->info.nHeader;
  nKey = (pPage->intKey ? 0 : pCur->info.nKey);

  if( skipKey ){
    offset += nKey;
  }
  if( offset+amt > nKey+pCur->info.nData ){
2870
2871
2872
2873
2874
2875
2876
2877

2878
2879
2880
2881
2882
2883
2884
2884
2885
2886
2887
2888
2889
2890

2891
2892
2893
2894
2895
2896
2897
2898







-
+







  u32 nKey;
  int nLocal;

  assert( pCur!=0 && pCur->pPage!=0 );
  assert( pCur->eState==CURSOR_VALID );
  pPage = pCur->pPage;
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  getCellInfo(pCur);
  GET_CELL_INFO(pCur);
  aPayload = pCur->info.pCell;
  aPayload += pCur->info.nHeader;
  if( pPage->intKey ){
    nKey = 0;
  }else{
    nKey = pCur->info.nKey;
  }
3041
3042
3043
3044
3045
3046
3047
3048

3049
3050
3051
3052
3053
3054
3055
3055
3056
3057
3058
3059
3060
3061

3062
3063
3064
3065
3066
3067
3068
3069







-
+







  Pgno pgno;
  int rc;
  MemPage *pPage;

  assert( pCur->eState==CURSOR_VALID );
  while( !(pPage = pCur->pPage)->leaf ){
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    pgno = get4byte(sqlite3BtreeFindCell(pPage, pCur->idx));
    pgno = get4byte(findCell(pPage, pCur->idx));
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
  }
  return SQLITE_OK;
}

/*
3178
3179
3180
3181
3182
3183
3184
3185

3186
3187
3188
3189
3190
3191
3192
3192
3193
3194
3195
3196
3197
3198

3199
3200
3201
3202
3203
3204
3205
3206







-
+







    }
    if( lwr<=upr ) for(;;){
      void *pCellKey;
      i64 nCellKey;
      pCur->info.nSize = 0;
      if( pPage->intKey ){
        u8 *pCell;
        pCell = sqlite3BtreeFindCell(pPage, pCur->idx) + pPage->childPtrSize;
        pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize;
        if( pPage->hasData ){
          u32 dummy;
          pCell += getVarint32(pCell, &dummy);
        }
        getVarint(pCell, (u64 *)&nCellKey);
        if( nCellKey<nKey ){
          c = -1;
3233
3234
3235
3236
3237
3238
3239
3240

3241
3242
3243
3244
3245
3246
3247
3247
3248
3249
3250
3251
3252
3253

3254
3255
3256
3257
3258
3259
3260
3261







-
+







    assert( lwr==upr+1 );
    assert( pPage->isInit );
    if( pPage->leaf ){
      chldPg = 0;
    }else if( lwr>=pPage->nCell ){
      chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
    }else{
      chldPg = get4byte(sqlite3BtreeFindCell(pPage, lwr));
      chldPg = get4byte(findCell(pPage, lwr));
    }
    if( chldPg==0 ){
      assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
      if( pRes ) *pRes = c;
      return SQLITE_OK;
    }
    pCur->idx = lwr;
3360
3361
3362
3363
3364
3365
3366
3367

3368
3369
3370
3371
3372
3373
3374
3374
3375
3376
3377
3378
3379
3380

3381
3382
3383
3384
3385
3386
3387
3388







-
+







  }
  pCur->skip = 0;

  pPage = pCur->pPage;
  assert( pPage->isInit );
  assert( pCur->idx>=0 );
  if( !pPage->leaf ){
    pgno = get4byte( sqlite3BtreeFindCell(pPage, pCur->idx) );
    pgno = get4byte( findCell(pPage, pCur->idx) );
    rc = moveToChild(pCur, pgno);
    if( rc ) return rc;
    rc = moveToRightmost(pCur);
  }else{
    while( pCur->idx==0 ){
      if( sqlite3BtreeIsRootPage(pPage) ){
        pCur->eState = CURSOR_INVALID;
3929
3930
3931
3932
3933
3934
3935
3936

3937
3938
3939
3940
3941
3942
3943
3943
3944
3945
3946
3947
3948
3949

3950
3951
3952
3953
3954
3955
3956
3957







-
+







  int i;
  BtShared *pBt = pPage->pBt;
  int rc = SQLITE_OK;

  if( pPage->leaf ) return SQLITE_OK;

  for(i=0; i<pPage->nCell; i++){
    u8 *pCell = sqlite3BtreeFindCell(pPage, i);
    u8 *pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = reparentPage(pBt, get4byte(pCell), pPage, i);
      if( rc!=SQLITE_OK ) return rc;
    }
  }
  if( !pPage->leaf ){
    rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), 
4183
4184
4185
4186
4187
4188
4189
4190

4191
4192
4193
4194
4195
4196
4197
4197
4198
4199
4200
4201
4202
4203

4204
4205
4206
4207
4208
4209
4210
4211







-
+







  sqlite3PagerRef(pParent->pDbPage);

  /* pPage is currently the right-child of pParent. Change this
  ** so that the right-child is the new page allocated above and
  ** pPage is the next-to-right child. 
  */
  assert( pPage->nCell>0 );
  pCell = sqlite3BtreeFindCell(pPage, pPage->nCell-1);
  pCell = findCell(pPage, pPage->nCell-1);
  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  assert( parentSize<64 );
  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
4333
4334
4335
4336
4337
4338
4339
4340

4341
4342
4343
4344
4345
4346
4347
4347
4348
4349
4350
4351
4352
4353

4354
4355
4356
4357
4358
4359
4360
4361







-
+







  ** is the rightmost child of pParent then set idx to pParent->nCell 
  */
  if( pParent->idxShift ){
    Pgno pgno;
    pgno = pPage->pgno;
    assert( pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
    for(idx=0; idx<pParent->nCell; idx++){
      if( get4byte(sqlite3BtreeFindCell(pParent, idx))==pgno ){
      if( get4byte(findCell(pParent, idx))==pgno ){
        break;
      }
    }
    assert( idx<pParent->nCell
             || get4byte(&pParent->aData[pParent->hdrOffset+8])==pgno );
  }else{
    idx = pPage->idxParent;
4367
4368
4369
4370
4371
4372
4373
4374

4375
4376
4377
4378
4379
4380
4381
4381
4382
4383
4384
4385
4386
4387

4388
4389
4390
4391
4392
4393
4394
4395







-
+







  }
  if( nxDiv<0 ){
    nxDiv = 0;
  }
  nDiv = 0;
  for(i=0, k=nxDiv; i<NB; i++, k++){
    if( k<pParent->nCell ){
      apDiv[i] = sqlite3BtreeFindCell(pParent, k);
      apDiv[i] = findCell(pParent, k);
      nDiv++;
      assert( !pParent->leaf );
      pgnoOld[i] = get4byte(apDiv[i]);
    }else if( k==pParent->nCell ){
      pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]);
    }else{
      break;
4868
4869
4870
4871
4872
4873
4874
4875

4876
4877
4878
4879
4880
4881
4882
4882
4883
4884
4885
4886
4887
4888

4889
4890
4891
4892
4893
4894
4895
4896







-
+







      assert( pChild->nOverflow==0 );
      if( pChild->nFree>=100 ){
        /* The child information will fit on the root page, so do the
        ** copy */
        int i;
        zeroPage(pPage, pChild->aData[0]);
        for(i=0; i<pChild->nCell; i++){
          apCell[i] = sqlite3BtreeFindCell(pChild,i);
          apCell[i] = findCell(pChild,i);
          szCell[i] = cellSizePtr(pChild, apCell[i]);
        }
        assemblePage(pPage, pChild->nCell, apCell, szCell);
        /* Copy the right-pointer of the child to the parent. */
        put4byte(&pPage->aData[pPage->hdrOffset+8], 
            get4byte(&pChild->aData[pChild->hdrOffset+8]));
        freePage(pChild);
5101
5102
5103
5104
5105
5106
5107
5108

5109
5110
5111
5112
5113
5114
5115
5115
5116
5117
5118
5119
5120
5121

5122
5123
5124
5125
5126
5127
5128
5129







-
+







  rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
  if( rc ) goto end_insert;
  assert( szNew==cellSizePtr(pPage, newCell) );
  assert( szNew<=MX_CELL_SIZE(pBt) );
  if( loc==0 && CURSOR_VALID==pCur->eState ){
    int szOld;
    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
    oldCell = sqlite3BtreeFindCell(pPage, pCur->idx);
    oldCell = findCell(pPage, pCur->idx);
    if( !pPage->leaf ){
      memcpy(newCell, oldCell, 4);
    }
    szOld = cellSizePtr(pPage, oldCell);
    rc = clearCell(pPage, oldCell);
    if( rc ) goto end_insert;
    dropCell(pPage, pCur->idx, szOld);
5173
5174
5175
5176
5177
5178
5179
5180

5181
5182
5183
5184
5185
5186
5187
5187
5188
5189
5190
5191
5192
5193

5194
5195
5196
5197
5198
5199
5200
5201







-
+







    return rc;
  }

  /* Locate the cell within it's page and leave pCell pointing to the
  ** data. The clearCell() call frees any overflow pages associated with the
  ** cell. The cell itself is still intact.
  */
  pCell = sqlite3BtreeFindCell(pPage, pCur->idx);
  pCell = findCell(pPage, pCur->idx);
  if( !pPage->leaf ){
    pgnoChild = get4byte(pCell);
  }
  rc = clearCell(pPage, pCell);
  if( rc ) return rc;

  if( !pPage->leaf ){
5205
5206
5207
5208
5209
5210
5211
5212

5213
5214
5215
5216
5217
5218
5219
5219
5220
5221
5222
5223
5224
5225

5226
5227
5228
5229
5230
5231
5232
5233







-
+







    if( rc==SQLITE_OK ){
      rc = sqlite3PagerWrite(leafCur.pPage->pDbPage);
    }
    if( rc==SQLITE_OK ){
      TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
         pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno));
      dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
      pNext = sqlite3BtreeFindCell(leafCur.pPage, leafCur.idx);
      pNext = findCell(leafCur.pPage, leafCur.idx);
      szNext = cellSizePtr(leafCur.pPage, pNext);
      assert( MX_CELL_SIZE(pBt)>=szNext+4 );
      tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) );
      if( tempCell==0 ){
        rc = SQLITE_NOMEM;
      }
    }
5396
5397
5398
5399
5400
5401
5402
5403

5404
5405
5406
5407
5408
5409
5410
5410
5411
5412
5413
5414
5415
5416

5417
5418
5419
5420
5421
5422
5423
5424







-
+







  if( pgno>sqlite3PagerPagecount(pBt->pPager) ){
    return SQLITE_CORRUPT_BKPT;
  }

  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
  if( rc ) goto cleardatabasepage_out;
  for(i=0; i<pPage->nCell; i++){
    pCell = sqlite3BtreeFindCell(pPage, i);
    pCell = findCell(pPage, i);
    if( !pPage->leaf ){
      rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1);
      if( rc ) goto cleardatabasepage_out;
    }
    rc = clearCell(pPage, pCell);
    if( rc ) goto cleardatabasepage_out;
  }
5883
5884
5885
5886
5887
5888
5889
5890

5891
5892
5893
5894
5895
5896
5897
5897
5898
5899
5900
5901
5902
5903

5904
5905
5906
5907
5908
5909
5910
5911







-
+







    int sz;
    CellInfo info;

    /* Check payload overflow pages
    */
    sqlite3_snprintf(sizeof(zContext), zContext,
             "On tree page %d cell %d: ", iPage, i);
    pCell = sqlite3BtreeFindCell(pPage,i);
    pCell = findCell(pPage,i);
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
    sz = info.nData;
    if( !pPage->intKey ) sz += info.nKey;
    assert( sz==info.nPayload );
    if( sz>info.nLocal ){
      int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
      Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
Changes to src/btreeInt.h.
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19











-
+







/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btreeInt.h,v 1.3 2007/05/16 14:23:00 danielk1977 Exp $
** $Id: btreeInt.h,v 1.4 2007/05/16 17:28:43 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
566
567
568
569
570
571
572
573


574
575
576
577
578
579
580
581
582
566
567
568
569
570
571
572

573
574
575

576
577
578
579
580
581
582







-
+
+

-







  char *zErrMsg;    /* An error message.  NULL if no errors seen. */
  int nErr;         /* Number of messages written to zErrMsg so far */
};

/*
** Read or write a two- and four-byte big-endian integer values.
*/
#define get2byte(x) ((x)[0]<<8 | (x)[1])
#define get2byte(x)   ((x)[0]<<8 | (x)[1])
#define put2byte(p,v) ((p)[0] = (v)>>8, (p)[1] = (v))
#define get4byte sqlite3Get4byte
#define put2byte sqlite3Put2byte
#define put4byte sqlite3Put4byte

/*
** Internal routines that should be accessed by the btree layer only.
*/
int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int);
int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);
Changes to src/malloc.c.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Memory allocation functions used throughout sqlite.
**
**
** $Id: malloc.c,v 1.1 2007/05/05 11:48:54 drh Exp $
** $Id: malloc.c,v 1.2 2007/05/16 17:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
784
785
786
787
788
789
790
791

792
793
794

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817


818
819
820
821
822
823
824
784
785
786
787
788
789
790

791
792
793

794
795
796
797
798
799
800
801








802
803
804
805
806
807


808
809
810
811
812
813
814
815
816







-
+


-
+







-
-
-
-
-
-
-
-






-
-
+
+







** function. However, if a malloc() failure has occured since the previous
** invocation SQLITE_NOMEM is returned instead. 
**
** If the first argument, db, is not NULL and a malloc() error has occured,
** then the connection error-code (the value returned by sqlite3_errcode())
** is set to SQLITE_NOMEM.
*/
static int mallocHasFailed = 0;
int sqlite3_mallocHasFailed = 0;
int sqlite3ApiExit(sqlite3* db, int rc){
  if( sqlite3MallocFailed() ){
    mallocHasFailed = 0;
    sqlite3_mallocHasFailed = 0;
    sqlite3OsLeaveMutex();
    sqlite3Error(db, SQLITE_NOMEM, 0);
    rc = SQLITE_NOMEM;
  }
  return rc & (db ? db->errMask : 0xff);
}

/* 
** Return true is a malloc has failed in this thread since the last call
** to sqlite3ApiExit(), or false otherwise.
*/
int sqlite3MallocFailed(){
  return (mallocHasFailed && sqlite3OsInMutex(1));
}

/* 
** Set the "malloc has failed" condition to true for this thread.
*/
void sqlite3FailedMalloc(){
  if( !sqlite3MallocFailed() ){
    sqlite3OsEnterMutex();
    assert( mallocHasFailed==0 );
    mallocHasFailed = 1;
    assert( sqlite3_mallocHasFailed==0 );
    sqlite3_mallocHasFailed = 1;
  }
}

#ifdef SQLITE_MEMDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.568 2007/05/15 16:51:37 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.569 2007/05/16 17:28:43 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#include "limits.h"


#if defined(SQLITE_TCL) || defined(TCLSH)
250
251
252
253
254
255
256










257
258
259
260
261
262
263
264
265
266
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275







+
+
+
+
+
+
+
+
+
+


-







#define sqliteRealloc(x,y)       sqlite3Realloc(x,y)
#define sqliteStrDup(x)          sqlite3StrDup(x)
#define sqliteStrNDup(x,y)       sqlite3StrNDup(x,y)
#define sqliteReallocOrFree(x,y) sqlite3ReallocOrFree(x,y)

#endif

/* Variable sqlite3_mallocHasFailed is set to true after a malloc() 
** failure occurs. 
**
** The sqlite3MallocFailed() macro returns true if a malloc has failed
** in this thread since the last call to sqlite3ApiExit(), or false 
** otherwise.
*/
extern int sqlite3_mallocHasFailed;
#define sqlite3MallocFailed() (sqlite3_mallocHasFailed && sqlite3OsInMutex(1))

#define sqliteFree(x)          sqlite3FreeX(x)
#define sqliteAllocSize(x)     sqlite3AllocSize(x)


/*
** An instance of this structure might be allocated to store information
** specific to a single thread.
*/
struct ThreadData {
  int dummy;               /* So that this structure is never empty */
328
329
330
331
332
333
334


335
336
337
338
339
340
341
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352







+
+







typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct TriggerStack TriggerStack;
typedef struct TriggerStep TriggerStep;
typedef struct Trigger Trigger;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;

#include "os.h"

/*
** Each database file to be accessed by the system is an instance
** of the following structure.  There are normally two of these structures
** in the sqlite.aDb[] array.  aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables.  Additional
** databases may be attached.
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1885
1886
1887
1888
1889
1890
1891

1892
1893
1894
1895
1896
1897
1898







-







Schema *sqlite3SchemaGet(Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  void (*)(sqlite3_context*,int,sqlite3_value **),
  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3MallocFailed(void);
void sqlite3FailedMalloc(void);
void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *);
int sqlite3OpenTempDatabase(Parse *);

#ifndef SQLITE_OMIT_LOAD_EXTENSION
  void sqlite3CloseExtensions(sqlite3*);
  int sqlite3AutoLoadExtensions(sqlite3*);
Changes to src/util.c.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.203 2007/05/15 16:51:37 drh Exp $
** $Id: util.c,v 1.204 2007/05/16 17:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>


533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
533
534
535
536
537
538
539

540
541



542
543
544




545
546
547
548
549
550
551







-
+

-
-
-



-
-
-
-







    v >>= 7;
  }while( v!=0 && i<9 );
  return i;
}


/*
** Read or write a two- and four-byte big-endian integer values.
** Read or write a four-byte big-endian integer value.
*/
u32 sqlite3Get2byte(const u8 *p){
  return (p[0]<<8) | p[1];
}
u32 sqlite3Get4byte(const u8 *p){
  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
void sqlite3Put2byte(unsigned char *p, u32 v){
  p[0] = v>>8;
  p[1] = v;
}
void sqlite3Put4byte(unsigned char *p, u32 v){
  p[0] = v>>24;
  p[1] = v>>16;
  p[2] = v>>8;
  p[3] = v;
}

Changes to src/vdbe.c.
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.620 2007/05/16 14:23:00 danielk1977 Exp $
** $Id: vdbe.c,v 1.621 2007/05/16 17:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <math.h>
#include "vdbeInt.h"

147
148
149
150
151
152
153






154
155
156
157
158
159
160
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166







+
+
+
+
+
+







** string that the stack entry itself controls.  In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string.
*/
#define Deephemeralize(P) \
   if( ((P)->flags&MEM_Ephem)!=0 \
       && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}

/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
** P if required.
*/
#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)

/*
** Argument pMem points at a memory cell that will be passed to a
** user-defined function or returned to the user as the result of a query.
** The second argument, 'db_enc' is the text encoding used by the vdbe for
** stack variables.  This routine sets the pMem->enc and pMem->type
** variables used by the sqlite3_value_*() routines.
*/
1466
1467
1468
1469
1470
1471
1472
1473

1474
1475
1476
1477
1478
1479
1480
1472
1473
1474
1475
1476
1477
1478

1479
1480
1481
1482
1483
1484
1485
1486







-
+







*/
case OP_ToText: {                  /* same as TK_TO_TEXT, no-push */
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ) break;
  assert( MEM_Str==(MEM_Blob>>3) );
  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
  applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
  rc = sqlite3VdbeMemExpandBlob(pTos);
  rc = ExpandBlob(pTos);
  assert( pTos->flags & MEM_Str );
  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
  break;
}

/* Opcode: ToBlob * * *
**
1671
1672
1673
1674
1675
1676
1677
1678
1679


1680
1681
1682
1683
1684
1685
1686
1677
1678
1679
1680
1681
1682
1683


1684
1685
1686
1687
1688
1689
1690
1691
1692







-
-
+
+







  affinity = pOp->p1 & 0xFF;
  if( affinity ){
    applyAffinity(pNos, affinity, encoding);
    applyAffinity(pTos, affinity, encoding);
  }

  assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
  sqlite3VdbeMemExpandBlob(pNos);
  sqlite3VdbeMemExpandBlob(pTos);
  ExpandBlob(pNos);
  ExpandBlob(pTos);
  res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
  switch( pOp->opcode ){
    case OP_Eq:    res = res==0;     break;
    case OP_Ne:    res = res!=0;     break;
    case OP_Lt:    res = res<0;      break;
    case OP_Le:    res = res<=0;     break;
    case OP_Gt:    res = res>0;      break;
2271
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
2277
2278
2279
2280
2281
2282
2283

2284
2285
2286
2287
2288
2289
2290
2291







-
+







    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
    }
    if( pRec->flags&MEM_Null ){
      containsNull = 1;
    }
    if( pRec->flags&MEM_Zero && pRec->n>0 ){
      sqlite3VdbeMemExpandBlob(pRec);
      ExpandBlob(pRec);
    }
    serial_type = sqlite3VdbeSerialType(pRec, file_format);
    len = sqlite3VdbeSerialTypeLen(serial_type);
    nData += len;
    nHdr += sqlite3VarintLen(serial_type);
    if( pRec->flags & MEM_Zero ){
      /* Only pure zero-filled BLOBs can be input to this Opcode.
2924
2925
2926
2927
2928
2929
2930
2931

2932
2933
2934
2935
2936
2937
2938
2930
2931
2932
2933
2934
2935
2936

2937
2938
2939
2940
2941
2942
2943
2944







-
+







      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->lastRowid = pTos->u.i;
      pC->rowidIsValid = res==0;
    }else{
      assert( pTos->flags & MEM_Blob );
      sqlite3VdbeMemExpandBlob(pTos);
      ExpandBlob(pTos);
      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pC->rowidIsValid = 0;
    }
    pC->deferredMoveto = 0;
3827
3828
3829
3830
3831
3832
3833
3834

3835
3836
3837
3838
3839
3840
3841
3833
3834
3835
3836
3837
3838
3839

3840
3841
3842
3843
3844
3845
3846
3847







-
+







  BtCursor *pCrsr;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos->flags & MEM_Blob );
  if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
    assert( pC->isTable==0 );
    rc = sqlite3VdbeMemExpandBlob(pTos);
    rc = ExpandBlob(pTos);
    if( rc==SQLITE_OK ){
      int nKey = pTos->n;
      const char *zKey = pTos->z;
      rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p2);
      assert( pC->deferredMoveto==0 );
      pC->cacheStatus = CACHE_STALE;
    }
3963
3964
3965
3966
3967
3968
3969
3970

3971
3972
3973
3974
3975
3976
3977
3969
3970
3971
3972
3973
3974
3975

3976
3977
3978
3979
3980
3981
3982
3983







-
+







  assert( p->apCsr[i]!=0 );
  assert( pTos>=p->aStack );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
    int res;
 
    assert( pTos->flags & MEM_Blob );  /* Created using OP_MakeRecord */
    assert( pC->deferredMoveto==0 );
    sqlite3VdbeMemExpandBlob(pTos);
    ExpandBlob(pTos);
    *pC->pIncrKey = pOp->p3!=0;
    assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
    rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
    *pC->pIncrKey = 0;
    if( rc!=SQLITE_OK ){
      break;
    }
Changes to src/vdbemem.c.
17
18
19
20
21
22
23






24
25
26
27
28
29
30
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36







+
+
+
+
+
+







*/
#include "sqliteInt.h"
#include "os.h"
#include <math.h>
#include <ctype.h>
#include "vdbeInt.h"

/*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
** P if required.
*/
#define expandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)

/*
** If pMem is an object with a valid string representation, this routine
** ensures the internal encoding for the string representation is
** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
**
** If pMem is not a string object, or the encoding of the string
** representation is already stored using the requested encoding, then this
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79







-
+







** Make the given Mem object MEM_Dyn.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemDynamicify(Mem *pMem){
  int n;
  u8 *z;
  sqlite3VdbeMemExpandBlob(pMem);
  expandBlob(pMem);
  if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
    return SQLITE_OK;
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  n = pMem->n;
  assert( pMem->flags & (MEM_Str|MEM_Blob) );
  z = sqliteMallocRaw( n+2 );
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136







-
+







** of the Mem.z[] array can be modified.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
  int n;
  u8 *z;
  sqlite3VdbeMemExpandBlob(pMem);
  expandBlob(pMem);
  if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
    return SQLITE_OK;
  }
  assert( (pMem->flags & MEM_Dyn)==0 );
  assert( pMem->flags & (MEM_Str|MEM_Blob) );
  if( (n = pMem->n)+2<sizeof(pMem->zShort) ){
    z = (u8*)pMem->zShort;
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
838
839
840
841
842
843
844

845
846
847
848
849
850
851
852







-
+







  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );

  if( pVal->flags&MEM_Null ){
    return 0;
  }
  assert( (MEM_Blob>>3) == MEM_Str );
  pVal->flags |= (pVal->flags & MEM_Blob)>>3;
  sqlite3VdbeMemExpandBlob(pVal);
  expandBlob(pVal);
  if( pVal->flags&MEM_Str ){
    sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
    if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){
      assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
      if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
        return 0;
      }