/ Check-in [2bca9224]
Login

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

Overview
Comment:Get the code back to the point where it will compile the btree.c tests. Move the default key comparison routine from btree.c into vdbeaux.c. Commented out code in vdbe.c that will need to be fixed. (CVS 1326)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2bca92240b16a51f78661c3ba4d779d231780f8d
User & Date: drh 2004-05-08 10:56:11
Context
2004-05-08
20:07
More btree.c bug fixes. (CVS 1327) check-in: e9f84ff3 user: drh tags: trunk
10:56
Get the code back to the point where it will compile the btree.c tests. Move the default key comparison routine from btree.c into vdbeaux.c. Commented out code in vdbe.c that will need to be fixed. (CVS 1326) check-in: 2bca9224 user: drh tags: trunk
10:11
Minor change to main.c so that it will compile with GCC 2.96. (CVS 1325) check-in: 1a09a1ad user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
....
3249
3250
3251
3252
3253
3254
3255
3256

3257
3258

3259
3260
3261
3262


3263
3264

3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
....
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
....
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
** 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.114 2004/05/08 08:23:21 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.
................................................................................
      assert( (tsize += psize)>0 );
      addr = pbegin;
    }
  }
  assert( tsize+data[pPage->hdrOffset+5]==pPage->nFree );
}

#if 0
/*
** The following is the default comparison function for (non-integer)
** keys in the btrees.  This function returns negative, zero, or
** positive if the first key is less than, equal to, or greater than
** the second.
**
** The key consists of multiple fields.  Each field begins with a variable
** length integer which determines the field type and the number of bytes
** of key data to follow for that field.
**
**   initial varint     bytes to follow    type
**   --------------     ---------------    ---------------
**      0                     0            NULL
**      1                     1            signed integer
**      2                     2            signed integer
**      3                     4            signed integer
**      4                     8            signed integer
**      5                     8            IEEE float
**     6..12                               reserved for expansion
**    N>=12 and even       (N-12)/2        BLOB
**    N>=13 and odd        (N-13)/2        text
**
** For a particular database, text is always either UTF-8, UTF-16BE, or
** UTF-16LE.  Which of these three formats to use is determined by one
** of the meta values in the file header.
**
*/
static int keyComp(
  void *userData,
  int nKey1, const unsigned char *aKey1, 
  int nKey2, const unsigned char *aKey2,
){
  KeyClass *pKeyClass = (KeyClass*)userData;
  i1 = i2 = 0;
  for(i1=i2=0; pKeyClass!=0; pKeyClass=pKeyClass->pNext){
    if( varint32(aKey1, &i1, nKey1, &n1) ) goto bad_key;
    if( varint32(aKey2, &i2, nKey2, &n2) ) goto bad_key;
    if( n1==0 ){
      if( n2>0 ) return -1;
      /* both values are NULL.  consider them equal for sorting purposes. */
    }else if( n2==0 ){
      /* right value is NULL but the left value is not.  right comes first */
      return +1;
    }else if( n1<=5 ){
      if( n2>5 ) return -1;
      /* both values are numbers.  sort them numerically */
      ...
    }else if( n2<=5 ){
      /* right value is numeric and left is TEXT or BLOB.  right comes first */
      return +1;
    }else if( n1<12 || n2<12 ){
      /* bad coding for either the left or the right value */
      goto bad_key;
    }else if( (n1&0x01)==0 ){
      if( n2&0x01)!=0 ) return -1;
      /* both values are BLOB.  use memcmp() */
      n1 = (n1-12)/2;
      n2 = (n2-12)/2;
      if( i1+n1>nKey1 || i2+n2>nKey2 ) goto bad_key;
      c = memcmp(&aKey1[i1], &aKey2[i2], n1<n2 ? n1 : n2);
      if( c!=0 ){
        return c | 1;
      }
      if( n1!=n2 ){
        return (n1-n2) | 1;
      }
      i1 += n1;
      i2 += n2;
    }else if( n2&0x01)!=0 ){
      /* right value if BLOB and left is TEXT.  BLOB comes first */
      return +1;
    }else{
      /* both values are TEXT.  use the supplied comparison function */
      n1 = (n1-13)/2;
      n2 = (n2-13)/2;
      if( i1+n1>nKey1 || i2+n2>nKey2 ) goto bad_key;
      c = pKeyClass->xCompare(pKeyClass->pUser, n1, &aKey1[i1], n2, &aKey2[i2]);
      if( c!=0 ){
        return c | 1;
      }
      i1 += n1;
      i2 += n2;
    } 
  }
  return 0;

bad_key:
  return 1;
}
#endif

/*
** Resize the aCell[] array of the given page so that it is able to
** hold at least nNewSz entries.
**
** Return SQLITE_OK or SQLITE_NOMEM.
*/
static int resizeCellArray(MemPage *pPage, int nNewSz){
................................................................................
#ifdef SQLITE_TEST
int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
  int rc;
  MemPage *pPage;
  int i, j;
  int nFree;
  u16 idx;
  int hdrOffset;

  char range[20];
  unsigned char payload[20];

  rc = getPage(pBt, (Pgno)pgno, &pPage);
  if( rc ){
    return rc;
  }


  printf("PAGE %d:  flags=0x%02x  frag=%d\n", pgno,
    pPage->aData[pPage->hdrOffset], pPage->aData[pPage->hdrOffset+5]);

  i = 0;
  assert( pPage->hdrOffset == (pgno==1 ? 100 : 0) );
  idx = get2byte(&pPage->aData[hdrOffset+3]);
  while( idx>0 && idx<=pBt->pageSize ){
    u64 nData, nKey;
    int nHeader;
    Pgno child;
    unsigned char *pCell = &pPage->aData[idx];
    int sz = cellSize(pPage, pCell);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    parseCellHeader(pPage, pCell, &nData, &nKey, &nHeader);
    if( pPage->leaf ){
      child = 0;
    }else{
      child = get4byte(&pCell[2]);
................................................................................
    i++;
    idx = get2byte(pCell);
  }
  if( idx!=0 ){
    printf("ERROR: next cell index out of range: %d\n", idx);
  }
  if( !pPage->leaf ){
    printf("right_child: %d\n", get4byte(&pPage->aData[6]));
  }
  nFree = 0;
  i = 0;
  idx = get2byte(&pPage->aData[hdrOffset+1]);
  while( idx>0 && idx<pPage->pBt->pageSize ){
    int sz = get2byte(&pPage->aData[idx+2]);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    nFree += sz;
    printf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
       i, range, sz, nFree);
    idx = get2byte(&pPage->aData[idx]);
    i++;
  }
  if( idx!=0 ){
    printf("ERROR: next freeblock index out of range: %d\n", idx);
  }
  if( recursive && !pPage->leaf ){
    idx = get2byte(&pPage->aData[hdrOffset+3]);
    while( idx>0 && idx<pBt->pageSize ){
      unsigned char *pCell = &pPage->aData[idx];
      sqlite3BtreePageDump(pBt, get4byte(&pCell[2]), 1);
      idx = get2byte(pCell);
    }
    sqlite3BtreePageDump(pBt, get4byte(&pPage->aData[hdrOffset+6]), 1);
  }
  sqlite3pager_unref(pPage->aData);
  return SQLITE_OK;
}
#endif

#ifdef SQLITE_TEST
/*
** Return the flag byte at the beginning of the page that the cursor
................................................................................
    rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
  }
  if( rc ){
    sqlite3BtreeRollback(pBtTo);
  }
  return rc;  
}

int sqlite3BtreeKeyCompare(
  BtCursor *pCur,       /* Pointer to entry to compare against */
  const void *pKey,     /* Key to compare against entry that pCur points to */
  int nKey,             /* Number of bytes in pKey */
  int nIgnore,          /* Ignore this many bytes at the end of pCur */
  int *pResult          /* Write the result here */
){
  void *pCellKey;
  u64 nCellKey;
  int rc;

  sqlite3BtreeKeySize(pCur, &nCellKey);
  nCellKey = nCellKey - nIgnore;
  if( nCellKey<=0 ){
    *pResult = 0;
    return SQLITE_OK;
  }

  pCellKey = sqlite3BtreeKeyFetch(pCur);
  if( pCellKey ){
    *pResult = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
    return SQLITE_OK;
  }

  pCellKey = sqliteMalloc( nCellKey );
  if( pCellKey==0 ) return SQLITE_NOMEM;

  rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
  *pResult = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
  sqliteFree(pCellKey);

  return rc;
}










|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
>


>




>
>

<
>

|
|




|







 







|



|

|




|






|

|



|

|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
553
554
555
556
557
558
559




























































































560
561
562
563
564
565
566
....
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175

3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
....
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
....
3672
3673
3674
3675
3676
3677
3678





































** 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.115 2004/05/08 10:56:11 drh 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.
................................................................................
      assert( (tsize += psize)>0 );
      addr = pbegin;
    }
  }
  assert( tsize+data[pPage->hdrOffset+5]==pPage->nFree );
}





























































































/*
** Resize the aCell[] array of the given page so that it is able to
** hold at least nNewSz entries.
**
** Return SQLITE_OK or SQLITE_NOMEM.
*/
static int resizeCellArray(MemPage *pPage, int nNewSz){
................................................................................
#ifdef SQLITE_TEST
int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
  int rc;
  MemPage *pPage;
  int i, j;
  int nFree;
  u16 idx;
  int hdr;
  unsigned char *data;
  char range[20];
  unsigned char payload[20];

  rc = getPage(pBt, (Pgno)pgno, &pPage);
  if( rc ){
    return rc;
  }
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  printf("PAGE %d:  flags=0x%02x  frag=%d\n", pgno,

    data[hdr], data[hdr+5]);
  i = 0;
  assert( hdr == (pgno==1 ? 100 : 0) );
  idx = get2byte(&data[hdr+3]);
  while( idx>0 && idx<=pBt->pageSize ){
    u64 nData, nKey;
    int nHeader;
    Pgno child;
    unsigned char *pCell = &data[idx];
    int sz = cellSize(pPage, pCell);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    parseCellHeader(pPage, pCell, &nData, &nKey, &nHeader);
    if( pPage->leaf ){
      child = 0;
    }else{
      child = get4byte(&pCell[2]);
................................................................................
    i++;
    idx = get2byte(pCell);
  }
  if( idx!=0 ){
    printf("ERROR: next cell index out of range: %d\n", idx);
  }
  if( !pPage->leaf ){
    printf("right_child: %d\n", get4byte(&data[6]));
  }
  nFree = 0;
  i = 0;
  idx = get2byte(&data[hdr+1]);
  while( idx>0 && idx<pPage->pBt->pageSize ){
    int sz = get2byte(&data[idx+2]);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    nFree += sz;
    printf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
       i, range, sz, nFree);
    idx = get2byte(&data[idx]);
    i++;
  }
  if( idx!=0 ){
    printf("ERROR: next freeblock index out of range: %d\n", idx);
  }
  if( recursive && !pPage->leaf ){
    idx = get2byte(&data[hdr+3]);
    while( idx>0 && idx<pBt->pageSize ){
      unsigned char *pCell = &data[idx];
      sqlite3BtreePageDump(pBt, get4byte(&pCell[2]), 1);
      idx = get2byte(pCell);
    }
    sqlite3BtreePageDump(pBt, get4byte(&data[hdr+6]), 1);
  }
  sqlite3pager_unref(data);
  return SQLITE_OK;
}
#endif

#ifdef SQLITE_TEST
/*
** Return the flag byte at the beginning of the page that the cursor
................................................................................
    rc = sqlite3pager_truncate(pBtTo->pPager, nPage);
  }
  if( rc ){
    sqlite3BtreeRollback(pBtTo);
  }
  return rc;  
}





































Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2740
2741
2742
2743
2744
2745
2746

2747

2748
2749
2750
2751
2752
2753
2754
....
3468
3469
3470
3471
3472
3473
3474

3475

3476
3477
3478
3479
3480
3481
3482
....
3589
3590
3591
3592
3593
3594
3595

3596

3597
3598
3599
3600
3601
3602
3603
....
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
**
** 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.269 2004/05/08 08:23:40 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
    if( res<0 ){
      rc = sqlite3BtreeNext(pCrsr, &res);
      if( res ){
        pc = pOp->p2 - 1;
        break;
      }
    }

    rc = sqlite3BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res); 

    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res>0 ){
      pc = pOp->p2 - 1;
      break;
    }

    /* At this point, pCrsr is pointing to an entry in P1 where all but
................................................................................
      assert( nKey >= 4 );
      rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      while( res!=0 ){
        int c;
        /* TODO: sqlite3BtreeKeySize(pCrsr, &n); */
        if( n==nKey

            && sqlite3BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK

           && c==0
        ){
          rc = SQLITE_CONSTRAINT;
          if( pOp->p3 && pOp->p3[0] ){
            sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
          }
          goto abort_due_to_error;
................................................................................
  assert( i>=0 && i<p->nCursor );
  assert( pTos>=p->aStack );
  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int res, rc;
 
    Stringify(pTos);
    assert( p->aCsr[i].deferredMoveto==0 );

    rc = sqlite3BtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);

    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;
    }else if( pOp->opcode==OP_IdxGE ){
      res++;
................................................................................
    rc = SQLITE_MISUSE;
  }else{
    rc = SQLITE_INTERRUPT;
  }
  sqlite3SetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  goto vdbe_halt;
}










|







 







>

>







 







>

>







 







>

>







 







<
<
<
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
....
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
....
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
....
4910
4911
4912
4913
4914
4915
4916



**
** 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.270 2004/05/08 10:56:12 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
    if( res<0 ){
      rc = sqlite3BtreeNext(pCrsr, &res);
      if( res ){
        pc = pOp->p2 - 1;
        break;
      }
    }
/******** FIX ME
    rc = sqlite3BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res); 
*/rc=SQLITE_INTERNAL;
    if( rc!=SQLITE_OK ) goto abort_due_to_error;
    if( res>0 ){
      pc = pOp->p2 - 1;
      break;
    }

    /* At this point, pCrsr is pointing to an entry in P1 where all but
................................................................................
      assert( nKey >= 4 );
      rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      while( res!=0 ){
        int c;
        /* TODO: sqlite3BtreeKeySize(pCrsr, &n); */
        if( n==nKey
/***** FIX ME
            && sqlite3BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK
*/
           && c==0
        ){
          rc = SQLITE_CONSTRAINT;
          if( pOp->p3 && pOp->p3[0] ){
            sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
          }
          goto abort_due_to_error;
................................................................................
  assert( i>=0 && i<p->nCursor );
  assert( pTos>=p->aStack );
  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int res, rc;
 
    Stringify(pTos);
    assert( p->aCsr[i].deferredMoveto==0 );
/****** FIX ME
    rc = sqlite3BtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
*/rc=SQLITE_INTERNAL;
    if( rc!=SQLITE_OK ){
      break;
    }
    if( pOp->opcode==OP_IdxLT ){
      res = -res;
    }else if( pOp->opcode==OP_IdxGE ){
      res++;
................................................................................
    rc = SQLITE_MISUSE;
  }else{
    rc = SQLITE_INTERRUPT;
  }
  sqlite3SetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  goto vdbe_halt;
}



Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
104
105
106
107
108
109
110

111
112
113
114
115
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.72 2004/05/08 08:23:45 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeFinalize(Vdbe*,char**);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
void sqlite3VdbeTrace(Vdbe*,FILE*);
void sqlite3VdbeCompressSpace(Vdbe*,int);
int sqlite3VdbeReset(Vdbe*,char **);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);


#endif










|







 







>


<
<
<
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
104
105
106
107
108
109
110
111
112
113



*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.73 2004/05/08 10:56:17 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeFinalize(Vdbe*,char**);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
void sqlite3VdbeTrace(Vdbe*,FILE*);
void sqlite3VdbeCompressSpace(Vdbe*,int);
int sqlite3VdbeReset(Vdbe*,char **);
int sqliteVdbeSetVariables(Vdbe*,int,const char**);
int sqlite3VdbeKeyCompare(void*,int,const u8*,int, const u8*);

#endif



Changes to src/vdbeaux.c.

1057
1058
1059
1060
1061
1062
1063































































1064



























    sqlite_search_count++;
    p->deferredMoveto = 0;
  }
  return SQLITE_OK;
}




































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
    sqlite_search_count++;
    p->deferredMoveto = 0;
  }
  return SQLITE_OK;
}


/*
** The following is the comparison function for (non-integer)
** keys in the btrees.  This function returns negative, zero, or
** positive if the first key is less than, equal to, or greater than
** the second.
**
** The key consists of multiple fields.  Each field begins with a variable
** length integer which determines the field type and the number of bytes
** of key data to follow for that field.
**
**   initial varint     bytes to follow    type
**   --------------     ---------------    ---------------
**      0                     0            NULL
**      1                     1            signed integer
**      2                     2            signed integer
**      3                     4            signed integer
**      4                     8            signed integer
**      5                     8            IEEE float
**     6..12                               reserved for expansion
**    N>=12 and even       (N-12)/2        BLOB
**    N>=13 and odd        (N-13)/2        text
**
** For a particular database, text is always either UTF-8, UTF-16BE, or
** UTF-16LE.  Which of these three formats to use is determined by one
** of the meta values in the file header.
**
*/
#if 0
int sqlite3VdbeKeyCompare(
  void *userData,
  int nKey1, const unsigned char *aKey1, 
  int nKey2, const unsigned char *aKey2,
){
  KeyClass *pKeyClass = (KeyClass*)userData;
  i1 = i2 = 0;
  for(i1=i2=0; pKeyClass!=0; pKeyClass=pKeyClass->pNext){
    if( varint32(aKey1, &i1, nKey1, &n1) ) goto bad_key;
    if( varint32(aKey2, &i2, nKey2, &n2) ) goto bad_key;
    if( n1==0 ){
      if( n2>0 ) return -1;
      /* both values are NULL.  consider them equal for sorting purposes. */
    }else if( n2==0 ){
      /* right value is NULL but the left value is not.  right comes first */
      return +1;
    }else if( n1<=5 ){
      if( n2>5 ) return -1;
      /* both values are numbers.  sort them numerically */
      /******* Finish this ********/
    }else if( n2<=5 ){
      /* right value is numeric and left is TEXT or BLOB.  right comes first */
      return +1;
    }else if( n1<12 || n2<12 ){
      /* bad coding for either the left or the right value */
      goto bad_key;
    }else if( (n1&0x01)==0 ){
      if( n2&0x01)!=0 ) return -1;
      /* both values are BLOB.  use memcmp() */
      n1 = (n1-12)/2;
      n2 = (n2-12)/2;
      if( i1+n1>nKey1 || i2+n2>nKey2 ) goto bad_key;
      c = memcmp(&aKey1[i1], &aKey2[i2], n1<n2 ? n1 : n2);
      if( c!=0 ){
        return c | 1;
      }
      if( n1!=n2 ){
        return (n1-n2) | 1;
      }
      i1 += n1;
      i2 += n2;
    }else if( n2&0x01)!=0 ){
      /* right value if BLOB and left is TEXT.  BLOB comes first */
      return +1;
    }else{
      /* both values are TEXT.  use the supplied comparison function */
      n1 = (n1-13)/2;
      n2 = (n2-13)/2;
      if( i1+n1>nKey1 || i2+n2>nKey2 ) goto bad_key;
      c = pKeyClass->xCompare(pKeyClass->pUser, n1, &aKey1[i1], n2, &aKey2[i2]);
      if( c!=0 ){
        return c | 1;
      }
      i1 += n1;
      i2 += n2;
    } 
  }
  return 0;

bad_key:
  return 1;
}
#endif

Changes to test/btree.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is btree database backend
#
# $Id: btree.test,v 1.18 2004/05/08 02:03:23 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Basic functionality.  Open and close a database.
#
................................................................................
    set key [format %03d $i]
    set data "*** $key *** $key *** $key *** $key ***"
    btree_insert $::c1 $key $data
  }
  select_keys $::c1
} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020}
#btree_page_dump $::b1 7
#btree_page_dump $::b1 2
#btree_page_dump $::b1 6
do_test btree-10.4 {
  btree_move_to $::c1 011
  btree_delete $::c1
  select_keys $::c1
} {001 002 003 004 005 006 007 008 009 010 012 013 014 015 016 017 018 019 020}
#btree_tree_dump $::b1 2







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is btree database backend
#
# $Id: btree.test,v 1.19 2004/05/08 10:56:20 drh Exp $


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Basic functionality.  Open and close a database.
#
................................................................................
    set key [format %03d $i]
    set data "*** $key *** $key *** $key *** $key ***"
    btree_insert $::c1 $key $data
  }
  select_keys $::c1
} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020}
#btree_page_dump $::b1 7
btree_page_dump $::b1 1
#btree_page_dump $::b1 6
do_test btree-10.4 {
  btree_move_to $::c1 011
  btree_delete $::c1
  select_keys $::c1
} {001 002 003 004 005 006 007 008 009 010 012 013 014 015 016 017 018 019 020}
#btree_tree_dump $::b1 2