SQLite

Check-in [636cd72329]
Login

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

Overview
Comment:Remove unused code. Test coverage enhancements. Modify the algorithm used to select column names for VIEWs of joins so that the constructed column names omits the underlying table names. (CVS 5386)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 636cd723296a8b1709011fdd99b236ffddf3f1b0
User & Date: drh 2008-07-10 00:32:42.000
Context
2008-07-10
17:52
Add the SQLITE_OPEN_NOMUTEX flag. Used for opening connections that are not protected by an internal mutex. (CVS 5387) (check-in: 7e58b78712 user: danielk1977 tags: trunk)
00:32
Remove unused code. Test coverage enhancements. Modify the algorithm used to select column names for VIEWs of joins so that the constructed column names omits the underlying table names. (CVS 5386) (check-in: 636cd72329 user: drh tags: trunk)
2008-07-09
16:51
Test coverage improvements on printf. (CVS 5385) (check-in: 2d8f7bebf0 user: drh tags: trunk)
Changes
Unified 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
/*
** 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.474 2008/07/09 11:49:47 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"












|







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.475 2008/07/10 00:32:42 drh 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"

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
** 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)]))
#ifdef SQLITE_TEST
u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){
  assert( iCell>=0 );
  assert( iCell<get2byte(&pPage->aData[pPage->hdrOffset+3]) );
  return findCell(pPage, iCell);
}
#endif

/*
** 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;
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  for(i=pPage->nOverflow-1; i>=0; i--){
    int k;







<
<
<
<
<
|
<
<

|







489
490
491
492
493
494
495





496


497
498
499
500
501
502
503
504
505
** 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)]))








/*
** This a more complex version of findCell() that works for
** pages that do contain overflow cells.  See insert
*/
static u8 *findOverflowCell(MemPage *pPage, int iCell){
  int i;
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  for(i=pPage->nOverflow-1; i>=0; i--){
    int k;
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
    pCur->validNKey = 0;
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
  if( rc!=SQLITE_OK ) goto end_insert;
  rc = balance(pPage, 1);
  /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
  /* fflush(stdout); */
  if( rc==SQLITE_OK ){
    moveToRoot(pCur);
  }
end_insert:
  return rc;
}








<
<







5788
5789
5790
5791
5792
5793
5794


5795
5796
5797
5798
5799
5800
5801
    pCur->validNKey = 0;
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
  if( rc!=SQLITE_OK ) goto end_insert;
  rc = balance(pPage, 1);


  if( rc==SQLITE_OK ){
    moveToRoot(pCur);
  }
end_insert:
  return rc;
}

Changes to src/btree.h.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.99 2008/05/29 03:01:24 shane Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem.  See comments in the source code for a detailed description
** of what each interface routine does.
**
** @(#) $Id: btree.h,v 1.100 2008/07/10 00:32:42 drh Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_

/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
*/
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeCacheOverflow(BtCursor *);

#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
int sqlite3BtreePageDump(Btree*, int, int recursive);
#endif

/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures.  So make the
** Enter and Leave procedures no-ops.
*/







<







170
171
172
173
174
175
176

177
178
179
180
181
182
183

int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeCacheOverflow(BtCursor *);

#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);

#endif

/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures.  So make the
** Enter and Leave procedures no-ops.
*/
Changes to src/btreeInt.h.
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.23 2008/07/08 19:34:07 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.











|







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.24 2008/07/10 00:32:42 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.
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
/*
** Internal routines that should be accessed by the btree layer only.
*/
int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int);
int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);
void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);
void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);
#ifdef SQLITE_TEST
u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell);
#endif
int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur);
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);
int sqlite3BtreeIsRootPage(MemPage *pPage);
void sqlite3BtreeMoveToParent(BtCursor *pCur);







<
<
<





627
628
629
630
631
632
633



634
635
636
637
638
/*
** Internal routines that should be accessed by the btree layer only.
*/
int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int);
int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);
void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);
void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);



int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur);
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);
int sqlite3BtreeIsRootPage(MemPage *pPage);
void sqlite3BtreeMoveToParent(BtCursor *pCur);
Changes to src/os_unix.c.
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.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.192 2008/06/30 10:16:05 danielk1977 Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined, then several different 
** locking implementations are provided:







|







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.
**
******************************************************************************
**
** This file contains code that is specific to Unix systems.
**
** $Id: os_unix.c,v 1.193 2008/07/10 00:32:42 drh Exp $
*/
#include "sqliteInt.h"
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/*
** If SQLITE_ENABLE_LOCKING_STYLE is defined, then several different 
** locking implementations are provided:
539
540
541
542
543
544
545

546
547
548
549
550
551
552
      sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
      free(pOpen->aPending);
      sqlite3_free(pOpen);
    }
  }
}


/*
** Tests a byte-range locking query to see if byte range locks are 
** supported, if not we fall back to dotlockLockingStyle.
*/
static int testLockingStyle(int fd){
  struct flock lockInfo;








>







539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
      sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
      free(pOpen->aPending);
      sqlite3_free(pOpen);
    }
  }
}

#ifdef SQLITE_ENABLE_LOCKING_STYLE
/*
** Tests a byte-range locking query to see if byte range locks are 
** supported, if not we fall back to dotlockLockingStyle.
*/
static int testLockingStyle(int fd){
  struct flock lockInfo;

562
563
564
565
566
567
568

569
570
571
572
573
574
575
  }
  
  /* Testing for flock() can give false positives.  So if if the above 
  ** test fails, then we fall back to using dot-file style locking.
  */  
  return LOCKING_STYLE_DOTFILE;
}


/* 
** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the 
** f_fstypename entry in the statfs structure as returned by stat() for 
** the file system hosting the database file and selects  the appropriate
** locking style based on its value.  These values and assignments are 
** based on Darwin/OSX behavior and have not been thoroughly tested on 







>







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
  }
  
  /* Testing for flock() can give false positives.  So if if the above 
  ** test fails, then we fall back to using dot-file style locking.
  */  
  return LOCKING_STYLE_DOTFILE;
}
#endif

/* 
** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the 
** f_fstypename entry in the statfs structure as returned by stat() for 
** the file system hosting the database file and selects  the appropriate
** locking style based on its value.  These values and assignments are 
** based on Darwin/OSX behavior and have not been thoroughly tested on 
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.463 2008/07/07 19:52:10 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.464 2008/07/10 00:32:42 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
** If an I/O or malloc() error occurs, the journal-file is not deleted
** and an error code is returned.
*/
static int pager_playback(Pager *pPager, int isHot){
  sqlite3_vfs *pVfs = pPager->pVfs;
  i64 szJ;                 /* Size of the journal file in bytes */
  u32 nRec;                /* Number of Records in the journal */
  int i;                   /* Loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  int rc;                  /* Result code of a subroutine */
  int res = 1;             /* Value returned by sqlite3OsAccess() */
  char *zMaster = 0;       /* Name of master journal file if any */

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.







|







1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
** If an I/O or malloc() error occurs, the journal-file is not deleted
** and an error code is returned.
*/
static int pager_playback(Pager *pPager, int isHot){
  sqlite3_vfs *pVfs = pPager->pVfs;
  i64 szJ;                 /* Size of the journal file in bytes */
  u32 nRec;                /* Number of Records in the journal */
  u32 i;                   /* Loop counter */
  Pgno mxPg = 0;           /* Size of the original file in pages */
  int rc;                  /* Result code of a subroutine */
  int res = 1;             /* Value returned by sqlite3OsAccess() */
  char *zMaster = 0;       /* Name of master journal file if any */

  /* Figure out how many records are in the journal.  Abort early if
  ** the journal is empty.
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
  if( iLimit>=-1 ){
    pPager->journalSizeLimit = iLimit;
  }
  return pPager->journalSizeLimit;
}

#ifdef SQLITE_TEST
/*
** Print a listing of all referenced pages and their ref count.
*/
void sqlite3PagerRefdump(Pager *pPager){
  PgHdr *pPg;
  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
    if( pPg->nRef<=0 ) continue;
    sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", 
       pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
  }
}
#endif

#endif /* SQLITE_OMIT_DISKIO */







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

5344
5345
5346
5347
5348
5349
5350














5351
i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
  if( iLimit>=-1 ){
    pPager->journalSizeLimit = iLimit;
  }
  return pPager->journalSizeLimit;
}















#endif /* SQLITE_OMIT_DISKIO */
Changes to src/printf.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
** The "printf" code that follows dates from the 1980's.  It is in
** the public domain.  The original comments are included here for
** completeness.  They are very out-of-date but might be useful as
** an historical reference.  Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
** $Id: printf.c,v 1.89 2008/07/09 16:51:51 drh Exp $
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
** found in the standard C library.  The following enhancements are
** supported:
**







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
** The "printf" code that follows dates from the 1980's.  It is in
** the public domain.  The original comments are included here for
** completeness.  They are very out-of-date but might be useful as
** an historical reference.  Most of the "enhancements" have been backed
** out so that the functionality is now the same as standard printf().
**
** $Id: printf.c,v 1.90 2008/07/10 00:32:42 drh Exp $
**
**************************************************************************
**
** The following modules is an enhanced replacement for the "printf" subroutines
** found in the standard C library.  The following enhancements are
** supported:
**
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
          length = 3;
          break;
        }
        if( realvalue>0.0 ){
          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
          if( realvalue>0.0 ){
            while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
            while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
          }
          if( exp>350 ){
            if( prefix=='-' ){
              bufpt = "-Inf";
            }else if( prefix=='+' ){
              bufpt = "+Inf";
            }else{
              bufpt = "Inf";







<
|
|
<







478
479
480
481
482
483
484

485
486

487
488
489
490
491
492
493
          length = 3;
          break;
        }
        if( realvalue>0.0 ){
          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }

          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }

          if( exp>350 ){
            if( prefix=='-' ){
              bufpt = "-Inf";
            }else if( prefix=='+' ){
              bufpt = "+Inf";
            }else{
              bufpt = "Inf";
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        struct SrcList_item *pItem = &pSrc->a[k];
        assert( k>=0 && k<pSrc->nSrc );
        if( pItem->zDatabase && pItem->zDatabase[0] ){
          sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
          sqlite3StrAccumAppend(pAccum, ".", 1);
        }
        sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
        length = width = 0;
        break;
      }







|







674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
        break;
      }
      case etSRCLIST: {
        SrcList *pSrc = va_arg(ap, SrcList*);
        int k = va_arg(ap, int);
        struct SrcList_item *pItem = &pSrc->a[k];
        assert( k>=0 && k<pSrc->nSrc );
        if( pItem->zDatabase ){
          sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
          sqlite3StrAccumAppend(pAccum, ".", 1);
        }
        sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
        length = width = 0;
        break;
      }
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
    if( !p->useMalloc ){
      p->tooBig = 1;
      N = p->nAlloc - p->nChar - 1;
      if( N<=0 ){
        return;
      }
    }else{
      i64 szNew = p->nAlloc;
      szNew += N + 1;
      if( szNew > p->mxAlloc ){
        p->nAlloc = p->mxAlloc;
        if( ((i64)p->nChar)+((i64)N) >= p->nAlloc ){
          sqlite3StrAccumReset(p);
          p->tooBig = 1;
          return;
        }
      }else{
        p->nAlloc = szNew;
      }
      zNew = sqlite3Malloc( p->nAlloc );
      if( zNew ){
        memcpy(zNew, p->zText, p->nChar);
        sqlite3StrAccumReset(p);







|


<
<
|
|
|
<







733
734
735
736
737
738
739
740
741
742


743
744
745

746
747
748
749
750
751
752
    if( !p->useMalloc ){
      p->tooBig = 1;
      N = p->nAlloc - p->nChar - 1;
      if( N<=0 ){
        return;
      }
    }else{
      i64 szNew = p->nChar;
      szNew += N + 1;
      if( szNew > p->mxAlloc ){


        sqlite3StrAccumReset(p);
        p->tooBig = 1;
        return;

      }else{
        p->nAlloc = szNew;
      }
      zNew = sqlite3Malloc( p->nAlloc );
      if( zNew ){
        memcpy(zNew, p->zText, p->nChar);
        sqlite3StrAccumReset(p);
Changes to src/select.c.
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.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.452 2008/07/09 01:39:44 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.







|







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.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.453 2008/07/10 00:32:42 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185


1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
    if( (zName = pEList->a[i].zName)!=0 ){
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
      zName = sqlite3DbStrDup(db, zName);
    }else if( p->op==TK_DOT 
              && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
      /* For columns of the from A.B use B as the name */


      zName = sqlite3MPrintf(db, "%T", &pR->token);
    }else if( p->span.z && p->span.z[0] ){
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf(db, "%T", &p->span);
    }else{
      /* If all else fails, make up a name */
      zName = sqlite3MPrintf(db, "column%d", i+1);
    }
    if( !zName || db->mallocFailed ){
      db->mallocFailed = 1;
      sqlite3_free(zName);
      sqlite3DeleteTable(pTab);
      return 0;
    }







|
<
|
>
>
|
|


<
<
<







1176
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190



1191
1192
1193
1194
1195
1196
1197
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
    assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
    if( (zName = pEList->a[i].zName)!=0 ){
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
      zName = sqlite3DbStrDup(db, zName);
    }else if( p->op==TK_COLUMN && p->pTab ){

      /* For columns use the column name name */
      int iCol = p->iColumn;
      if( iCol<0 ) iCol = p->pTab->iPKey;
      zName = sqlite3MPrintf(db, "%s", p->pTab->aCol[iCol].zName);
    }else{
      /* Use the original text of the column expression as its name */
      zName = sqlite3MPrintf(db, "%T", &p->span);



    }
    if( !zName || db->mallocFailed ){
      db->mallocFailed = 1;
      sqlite3_free(zName);
      sqlite3DeleteTable(pTab);
      return 0;
    }
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
        }
        for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
          Table *pTab = pFrom->pTab;
          char *zTabName = pFrom->zAlias;
          if( zTabName==0 || zTabName[0]==0 ){ 
            zTabName = pTab->zName;
          }
          if( zTName && (zTabName==0 || zTabName[0]==0 || 
                 sqlite3StrICmp(zTName, zTabName)!=0) ){
            continue;
          }
          tableSeen = 1;
          for(j=0; j<pTab->nCol; j++){
            Expr *pExpr, *pRight;
            char *zName = pTab->aCol[j].zName;








|
|







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
        }
        for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
          Table *pTab = pFrom->pTab;
          char *zTabName = pFrom->zAlias;
          if( zTabName==0 || zTabName[0]==0 ){ 
            zTabName = pTab->zName;
          }
          assert( zTabName );
          if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
            continue;
          }
          tableSeen = 1;
          for(j=0; j<pTab->nCol; j++){
            Expr *pExpr, *pRight;
            char *zName = pTab->aCol[j].zName;

1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
                ** using clause from the table on the right. */
                continue;
              }
            }
            pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
            if( pRight==0 ) break;
            setQuotedToken(pParse, &pRight->token, zName);
            if( zTabName && (longNames || pTabList->nSrc>1) ){
              Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
              pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
              if( pExpr==0 ) break;
              setQuotedToken(pParse, &pLeft->token, zTabName);
              setToken(&pExpr->span, 
                  sqlite3MPrintf(db, "%s.%s", zTabName, zName));
              pExpr->span.dyn = 1;







|







1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
                ** using clause from the table on the right. */
                continue;
              }
            }
            pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
            if( pRight==0 ) break;
            setQuotedToken(pParse, &pRight->token, zName);
            if( longNames || pTabList->nSrc>1 ){
              Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
              pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
              if( pExpr==0 ) break;
              setQuotedToken(pParse, &pLeft->token, zTabName);
              setToken(&pExpr->span, 
                  sqlite3MPrintf(db, "%s.%s", zTabName, zName));
              pExpr->span.dyn = 1;
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
** the N-th column of table iTable.
**
** If iTable==0 then transform each term of the ORDER BY clause to refer
** to a column of the result set by number.
*/
static int processCompoundOrderBy(
  Parse *pParse,        /* Parsing context.  Leave error messages here */
  Select *pSelect,      /* The SELECT statement containing the ORDER BY */
  int iTable            /* Output table for compound SELECT statements */
){
  int i;
  ExprList *pOrderBy;
  ExprList *pEList;
  sqlite3 *db;
  int moreToDo = 1;








|
<







1638
1639
1640
1641
1642
1643
1644
1645

1646
1647
1648
1649
1650
1651
1652
** the N-th column of table iTable.
**
** If iTable==0 then transform each term of the ORDER BY clause to refer
** to a column of the result set by number.
*/
static int processCompoundOrderBy(
  Parse *pParse,        /* Parsing context.  Leave error messages here */
  Select *pSelect       /* The SELECT statement containing the ORDER BY */

){
  int i;
  ExprList *pOrderBy;
  ExprList *pEList;
  sqlite3 *db;
  int moreToDo = 1;

1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
        }
        sqlite3ExprDelete(pDup);
        if( iCol<0 ){
          return 1;
        }
      }
      if( iCol>0 ){
        if( iTable ){
          pE->op = TK_COLUMN;
          pE->iTable = iTable;
          pE->iAgg = -1;
          pE->iColumn = iCol-1;
          pE->pTab = 0;
        }else{
          pE->op = TK_INTEGER;
          pE->flags |= EP_IntValue;
          pE->iTable = iCol;
        }
        pOrderBy->a[i].done = 1;
      }else{
        moreToDo = 1;
      }
    }
    pSelect = pSelect->pNext;
  }







<
<
<
<
<
<
<
|
|
|
<







1691
1692
1693
1694
1695
1696
1697







1698
1699
1700

1701
1702
1703
1704
1705
1706
1707
        }
        sqlite3ExprDelete(pDup);
        if( iCol<0 ){
          return 1;
        }
      }
      if( iCol>0 ){







        pE->op = TK_INTEGER;
        pE->flags |= EP_IntValue;
        pE->iTable = iCol;

        pOrderBy->a[i].done = 1;
      }else{
        moreToDo = 1;
      }
    }
    pSelect = pSelect->pNext;
  }
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The right-most of SELECTs to be coded */
  SelectDest *pDest     /* What to do with query results */
){
  int rc = SQLITE_OK;   /* Success code from a subroutine */
  Select *pPrior;       /* Another SELECT immediately to our left */
  Vdbe *v;              /* Generate code to this VDBE */
  int nCol;             /* Number of columns in the result set */
  int aSetP2[2];        /* Set P2 value of these op to number of columns */
  int nSetP2 = 0;       /* Number of slots in aSetP2[] used */
  SelectDest dest;      /* Alternative data destination */
  Select *pDelete = 0;  /* Chain of simple selects to delete */

  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  */
  if( p==0 || p->pPrior==0 ){







<
<
<







1863
1864
1865
1866
1867
1868
1869



1870
1871
1872
1873
1874
1875
1876
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The right-most of SELECTs to be coded */
  SelectDest *pDest     /* What to do with query results */
){
  int rc = SQLITE_OK;   /* Success code from a subroutine */
  Select *pPrior;       /* Another SELECT immediately to our left */
  Vdbe *v;              /* Generate code to this VDBE */



  SelectDest dest;      /* Alternative data destination */
  Select *pDelete = 0;  /* Chain of simple selects to delete */

  /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
  */
  if( p==0 || p->pPrior==0 ){
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
      int unionTab;    /* Cursor number of the temporary table holding result */
      int op = 0;      /* One of the SRT_ operations to apply to self */
      int priorOp;     /* The SRT_ operation to apply to prior selects */
      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
      int addr;
      SelectDest uniondest;

      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
      if( dest.eDest==priorOp && !p->pLimit && !p->pOffset ){
        /* We can reuse a temporary table generated by a SELECT to our
        ** right.
        */
        unionTab = dest.iParm;
      }else{
        /* We will need to create our own temporary table to hold the
        ** intermediate results.
        */
        unionTab = pParse->nTab++;
        if( processCompoundOrderBy(pParse, p, unionTab) ){
          rc = 1;
          goto multi_select_end;
        }
        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
        if( priorOp==SRT_Table ){
          assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
          aSetP2[nSetP2++] = addr;
        }else{
          assert( p->addrOpenEphm[0] == -1 );
          p->addrOpenEphm[0] = addr;
          p->pRightmost->usesEphm = 1;
        }
        assert( p->pEList );
      }

      /* Code the SELECT statements to our left
      */
      assert( !pPrior->pOrderBy );
      sqlite3SelectDestInit(&uniondest, priorOp, unionTab);







|










|
<
<
<

<
<
<
<
|
|
|
<







1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982



1983




1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
      int unionTab;    /* Cursor number of the temporary table holding result */
      int op = 0;      /* One of the SRT_ operations to apply to self */
      int priorOp;     /* The SRT_ operation to apply to prior selects */
      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
      int addr;
      SelectDest uniondest;

      priorOp = SRT_Union;
      if( dest.eDest==priorOp && !p->pLimit && !p->pOffset ){
        /* We can reuse a temporary table generated by a SELECT to our
        ** right.
        */
        unionTab = dest.iParm;
      }else{
        /* We will need to create our own temporary table to hold the
        ** intermediate results.
        */
        unionTab = pParse->nTab++;
        assert( p->pOrderBy==0 );



        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);




        assert( p->addrOpenEphm[0] == -1 );
        p->addrOpenEphm[0] = addr;
        p->pRightmost->usesEphm = 1;

        assert( p->pEList );
      }

      /* Code the SELECT statements to our left
      */
      assert( !pPrior->pOrderBy );
      sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101

      /* INTERSECT is different from the others since it requires
      ** two temporary tables.  Hence it has its own case.  Begin
      ** by allocating the tables we will need.
      */
      tab1 = pParse->nTab++;
      tab2 = pParse->nTab++;
      if( processCompoundOrderBy(pParse, p, tab1) ){
        rc = 1;
        goto multi_select_end;
      }

      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
      assert( p->addrOpenEphm[0] == -1 );
      p->addrOpenEphm[0] = addr;
      p->pRightmost->usesEphm = 1;
      assert( p->pEList );








|
<
<
<







2062
2063
2064
2065
2066
2067
2068
2069



2070
2071
2072
2073
2074
2075
2076

      /* INTERSECT is different from the others since it requires
      ** two temporary tables.  Hence it has its own case.  Begin
      ** by allocating the tables we will need.
      */
      tab1 = pParse->nTab++;
      tab2 = pParse->nTab++;
      assert( p->pOrderBy==0 );




      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
      assert( p->addrOpenEphm[0] == -1 );
      p->addrOpenEphm[0] = addr;
      p->pRightmost->usesEphm = 1;
      assert( p->pEList );

2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179

2180
2181

2182
2183
2184
2185
2186
2187
2188
      sqlite3VdbeResolveLabel(v, iBreak);
      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
      break;
    }
  }

  /* Set the number of columns in temporary tables
  */
  nCol = p->pEList->nExpr;
  while( nSetP2 ){
    sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol);
  }

  /* Compute collating sequences used by 
  ** temporary tables needed to implement the compound select.
  ** Attach the KeyInfo structure to all temporary tables.
  **
  ** This section is run by the right-most SELECT statement only.
  ** SELECT statements to the left always skip this part.  The right-most
  ** SELECT might also skip this part if it has no ORDER BY clause and
  ** no temp tables are required.
  */
  if( p->usesEphm ){
    int i;                        /* Loop counter */
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
    Select *pLoop;                /* For looping through SELECT statements */
    CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */


    assert( p->pRightmost==p );

    pKeyInfo = sqlite3DbMallocZero(pParse->db,
                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }








<
<
<
<
<
<
<














>


>







2127
2128
2129
2130
2131
2132
2133







2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
      sqlite3VdbeResolveLabel(v, iBreak);
      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
      break;
    }
  }








  /* Compute collating sequences used by 
  ** temporary tables needed to implement the compound select.
  ** Attach the KeyInfo structure to all temporary tables.
  **
  ** This section is run by the right-most SELECT statement only.
  ** SELECT statements to the left always skip this part.  The right-most
  ** SELECT might also skip this part if it has no ORDER BY clause and
  ** no temp tables are required.
  */
  if( p->usesEphm ){
    int i;                        /* Loop counter */
    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
    Select *pLoop;                /* For looping through SELECT statements */
    CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */
    int nCol;                     /* Number of columns in result set */

    assert( p->pRightmost==p );
    nCol = p->pEList->nExpr;
    pKeyInfo = sqlite3DbMallocZero(pParse->db,
                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
    if( !pKeyInfo ){
      rc = SQLITE_NOMEM;
      goto multi_select_end;
    }

2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536

  /* Patch up the ORDER BY clause
  */
  op = p->op;  
  pPrior = p->pPrior;
  assert( pPrior->pOrderBy==0 );
  pOrderBy = p->pOrderBy;
  if( pOrderBy ){
    if( processCompoundOrderBy(pParse, p, 0) ){
      return SQLITE_ERROR;
    }
    nOrderBy = pOrderBy->nExpr;
  }else{
    nOrderBy = 0;
  }
  /* For operators other than UNION ALL we have to make sure that
  ** the ORDER BY clause covers every term of the result set.  Add
  ** terms to the ORDER BY clause as necessary.
  */
  if( op!=TK_ALL ){
    for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
      for(j=0; j<nOrderBy; j++){







|
|
|
|
|
<
<
|







2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496


2497
2498
2499
2500
2501
2502
2503
2504

  /* Patch up the ORDER BY clause
  */
  op = p->op;  
  pPrior = p->pPrior;
  assert( pPrior->pOrderBy==0 );
  pOrderBy = p->pOrderBy;
  assert( pOrderBy );
  if( processCompoundOrderBy(pParse, p) ){
    return SQLITE_ERROR;
  }
  nOrderBy = pOrderBy->nExpr;



  /* For operators other than UNION ALL we have to make sure that
  ** the ORDER BY clause covers every term of the result set.  Add
  ** terms to the ORDER BY clause as necessary.
  */
  if( op!=TK_ALL ){
    for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
      for(j=0; j<nOrderBy; j++){
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
/*
** 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.739 2008/07/09 13:28:54 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build













|







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.740 2008/07/10 00:32:42 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
#define SQLITE_AFF_MASK     0x67

/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
*/
#define SQLITE_JUMPIFNULL   0x08  /* jumps if either operand is NULL */
#define SQLITE_NULLEQUAL    0x10  /* compare NULLs equal */
#define SQLITE_STOREP2      0x80  /* Store result in reg[P2] rather than jump */

/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table.  The case of the original
** CREATE TABLE statement is stored, but case is not significant for







<
|







830
831
832
833
834
835
836

837
838
839
840
841
842
843
844
#define SQLITE_AFF_MASK     0x67

/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
*/
#define SQLITE_JUMPIFNULL   0x08  /* jumps if either operand is NULL */

#define SQLITE_STOREP2      0x10  /* Store result in reg[P2] rather than jump */

/*
** Each SQL table is represented in memory by an instance of the
** following structure.
**
** Table.zName is the name of the table.  The case of the original
** CREATE TABLE statement is stored, but case is not significant for
Changes to src/test3.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.98 2008/06/18 17:09:10 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>








|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.99 2008/07/10 00:32:42 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
      Tcl_AppendResult(interp, errorName(rc), 0);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}

/*
** Usage:   btree_page_dump ID PAGENUM
**
** Print a disassembly of a page on standard output
*/
static int btree_page_dump(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int iPage;
  int rc;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreePageDump(pBt, iPage, 0);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_tree_dump ID PAGENUM
**
** Print a disassembly of a page and all its child pages on standard output
*/
static int btree_tree_dump(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int iPage;
  int rc;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR;
  sqlite3BtreeEnter(pBt);
  rc = sqlite3BtreePageDump(pBt, iPage, 1);
  sqlite3BtreeLeave(pBt);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:   btree_pager_stats ID
**
** Returns pager statistics
*/
static int btree_pager_stats(
  void *NotUsed,







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







469
470
471
472
473
474
475
































































476
477
478
479
480
481
482
      Tcl_AppendResult(interp, errorName(rc), 0);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}

































































/*
** Usage:   btree_pager_stats ID
**
** Returns pager statistics
*/
static int btree_pager_stats(
  void *NotUsed,
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
    sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]);
    Tcl_AppendElement(interp, zBuf);
  }
  sqlite3BtreeLeave(pBt);

  /* Release the mutex on the SQLite handle that controls this b-tree */
  sqlite3_mutex_leave(pBt->db->mutex);
  return TCL_OK;
}

/*
** Usage:   btree_pager_ref_dump ID
**
** Print out all outstanding pages.
*/
static int btree_pager_ref_dump(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TextToPtr(argv[1]);
#ifdef SQLITE_TEST
  sqlite3BtreeEnter(pBt);
  sqlite3PagerRefdump(sqlite3BtreePager(pBt));
  sqlite3BtreeLeave(pBt);
#endif
  return TCL_OK;
}

/*
** Usage:   btree_integrity_check ID ROOT ...
**
** Look through every page of the given BTree file to verify correct







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







516
517
518
519
520
521
522



























523
524
525
526
527
528
529
    sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]);
    Tcl_AppendElement(interp, zBuf);
  }
  sqlite3BtreeLeave(pBt);

  /* Release the mutex on the SQLite handle that controls this b-tree */
  sqlite3_mutex_leave(pBt->db->mutex);



























  return TCL_OK;
}

/*
** Usage:   btree_integrity_check ID ROOT ...
**
** Look through every page of the given BTree file to verify correct
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
     { "btree_commit",             (Tcl_CmdProc*)btree_commit             },
     { "btree_rollback",           (Tcl_CmdProc*)btree_rollback           },
     { "btree_create_table",       (Tcl_CmdProc*)btree_create_table       },
     { "btree_drop_table",         (Tcl_CmdProc*)btree_drop_table         },
     { "btree_clear_table",        (Tcl_CmdProc*)btree_clear_table        },
     { "btree_get_meta",           (Tcl_CmdProc*)btree_get_meta           },
     { "btree_update_meta",        (Tcl_CmdProc*)btree_update_meta        },
     { "btree_page_dump",          (Tcl_CmdProc*)btree_page_dump          },
     { "btree_tree_dump",          (Tcl_CmdProc*)btree_tree_dump          },
     { "btree_pager_stats",        (Tcl_CmdProc*)btree_pager_stats        },
     { "btree_pager_ref_dump",     (Tcl_CmdProc*)btree_pager_ref_dump     },
     { "btree_cursor",             (Tcl_CmdProc*)btree_cursor             },
     { "btree_close_cursor",       (Tcl_CmdProc*)btree_close_cursor       },
     { "btree_move_to",            (Tcl_CmdProc*)btree_move_to            },
     { "btree_delete",             (Tcl_CmdProc*)btree_delete             },
     { "btree_next",               (Tcl_CmdProc*)btree_next               },
     { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
     { "btree_eof",                (Tcl_CmdProc*)btree_eof                },







<
<

<







1558
1559
1560
1561
1562
1563
1564


1565

1566
1567
1568
1569
1570
1571
1572
     { "btree_commit",             (Tcl_CmdProc*)btree_commit             },
     { "btree_rollback",           (Tcl_CmdProc*)btree_rollback           },
     { "btree_create_table",       (Tcl_CmdProc*)btree_create_table       },
     { "btree_drop_table",         (Tcl_CmdProc*)btree_drop_table         },
     { "btree_clear_table",        (Tcl_CmdProc*)btree_clear_table        },
     { "btree_get_meta",           (Tcl_CmdProc*)btree_get_meta           },
     { "btree_update_meta",        (Tcl_CmdProc*)btree_update_meta        },


     { "btree_pager_stats",        (Tcl_CmdProc*)btree_pager_stats        },

     { "btree_cursor",             (Tcl_CmdProc*)btree_cursor             },
     { "btree_close_cursor",       (Tcl_CmdProc*)btree_close_cursor       },
     { "btree_move_to",            (Tcl_CmdProc*)btree_move_to            },
     { "btree_delete",             (Tcl_CmdProc*)btree_delete             },
     { "btree_next",               (Tcl_CmdProc*)btree_next               },
     { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
     { "btree_eof",                (Tcl_CmdProc*)btree_eof                },
Changes to src/test_btree.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test_btree.c,v 1.3 2007/08/17 01:14:39 drh Exp $
*/
#include "btreeInt.h"
#include <tcl.h>

/*
** Print a disassembly of the given page on standard output.  This routine
** is used for debugging and testing only.
*/
static int btreePageDump(
  BtShared *pBt,         /* The Btree to be dumped */
  int pgno,              /* The page to be dumped */
  int recursive,         /* True to decend into child pages */
  MemPage *pParent       /* Parent page */
){
  int rc;
  MemPage *pPage;
  int i, j, c;
  int nFree;
  u16 idx;
  int hdr;
  int nCell;
  int isInit;
  unsigned char *data;
  char range[20];
  unsigned char payload[20];

  rc = sqlite3BtreeGetPage(pBt, (Pgno)pgno, &pPage, 0);
  isInit = pPage->isInit;
  if( pPage->isInit==0 ){
    sqlite3BtreeInitPage(pPage, pParent);
  }
  if( rc ){
    return rc;
  }
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  c = data[hdr];
  pPage->intKey = (c & (PTF_INTKEY|PTF_LEAFDATA))!=0;
  pPage->zeroData = (c & PTF_ZERODATA)!=0;
  pPage->leafData = (c & PTF_LEAFDATA)!=0;
  pPage->leaf = (c & PTF_LEAF)!=0;
  pPage->hasData = !(pPage->zeroData || (!pPage->leaf && pPage->leafData));
  nCell = get2byte(&data[hdr+3]);
  sqlite3DebugPrintf("PAGE %d:  flags=0x%02x  frag=%d   parent=%d\n", pgno,
    data[hdr], data[hdr+7], 
    (pPage->isInit && pPage->pParent) ? pPage->pParent->pgno : 0);
  assert( hdr == (pgno==1 ? 100 : 0) );
  idx = hdr + 12 - pPage->leaf*4;
  for(i=0; i<nCell; i++){
    CellInfo info;
    Pgno child;
    unsigned char *pCell;
    int sz;
    int addr;

    addr = get2byte(&data[idx + 2*i]);
    pCell = &data[addr];
    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
    sz = info.nSize;
    sqlite3_snprintf(sizeof(range),range,"%d..%d", addr, addr+sz-1);
    if( pPage->leaf ){
      child = 0;
    }else{
      child = get4byte(pCell);
    }
    sz = info.nData;
    if( !pPage->intKey ) sz += info.nKey;
    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
    memcpy(payload, &pCell[info.nHeader], sz);
    for(j=0; j<sz; j++){
      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
    }
    payload[sz] = 0;
    sqlite3DebugPrintf(
      "cell %2d: i=%-10s chld=%-4d nk=%-4lld nd=%-4d payload=%s\n",
      i, range, child, info.nKey, info.nData, payload
    );
  }
  if( !pPage->leaf ){
    sqlite3DebugPrintf("right_child: %d\n", get4byte(&data[hdr+8]));
  }
  nFree = 0;
  i = 0;
  idx = get2byte(&data[hdr+1]);
  while( idx>0 && idx<pPage->pBt->usableSize ){
    int sz = get2byte(&data[idx+2]);
    sqlite3_snprintf(sizeof(range),range,"%d..%d", idx, idx+sz-1);
    nFree += sz;
    sqlite3DebugPrintf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
       i, range, sz, nFree);
    idx = get2byte(&data[idx]);
    i++;
  }
  if( idx!=0 ){
    sqlite3DebugPrintf("ERROR: next freeblock index out of range: %d\n", idx);
  }
  if( recursive && !pPage->leaf ){
    for(i=0; i<nCell; i++){
      unsigned char *pCell = sqlite3BtreeFindCell(pPage, i);
      btreePageDump(pBt, get4byte(pCell), 1, pPage);
      idx = get2byte(pCell);
    }
    btreePageDump(pBt, get4byte(&data[hdr+8]), 1, pPage);
  }
  pPage->isInit = isInit;
  sqlite3PagerUnref(pPage->pDbPage);
  fflush(stdout);
  return SQLITE_OK;
}
int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){
  return btreePageDump(p->pBt, pgno, recursive, 0);
}

/*
** Usage: sqlite3_shared_cache_report
**
** Return a list of file that are shared and the number of
** references to each file.
*/
int sqlite3BtreeSharedCacheReport(







|




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







9
10
11
12
13
14
15
16
17
18
19
20













































































































21
22
23
24
25
26
27
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test_btree.c,v 1.4 2008/07/10 00:32:42 drh Exp $
*/
#include "btreeInt.h"
#include <tcl.h>














































































































/*
** Usage: sqlite3_shared_cache_report
**
** Return a list of file that are shared and the number of
** references to each file.
*/
int sqlite3BtreeSharedCacheReport(
Changes to src/util.c.
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.235 2008/07/09 13:28:54 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>


/*







|







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.236 2008/07/10 00:32:42 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>


/*
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947
948
949
950
951
952

  magic = db->magic;
  if( magic!=SQLITE_MAGIC_SICK &&
      magic!=SQLITE_MAGIC_OPEN &&
      magic!=SQLITE_MAGIC_BUSY ) return 0;
  return 1;
}


/*
** Report a failsafe() macro failure
*/
void sqlite3Failsafe(int iCode){
  sqlite3Config.iFailsafe = iCode;

  /* The following assert is always false.  When assert() is enabled,
  ** the following causes a failsafe() failure to work like an assert()
  ** failure.  Normal operating mode for SQLite is for assert() to be
  ** disabled, however, so the following is normally a no-op.
  */
  assert( iCode==0 );   /* Always fails if assert() is enabled */
}








>













>
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
  magic = db->magic;
  if( magic!=SQLITE_MAGIC_SICK &&
      magic!=SQLITE_MAGIC_OPEN &&
      magic!=SQLITE_MAGIC_BUSY ) return 0;
  return 1;
}

#ifndef SQLITE_COVERAGE_TEST
/*
** Report a failsafe() macro failure
*/
void sqlite3Failsafe(int iCode){
  sqlite3Config.iFailsafe = iCode;

  /* The following assert is always false.  When assert() is enabled,
  ** the following causes a failsafe() failure to work like an assert()
  ** failure.  Normal operating mode for SQLite is for assert() to be
  ** disabled, however, so the following is normally a no-op.
  */
  assert( iCode==0 );   /* Always fails if assert() is enabled */
}
#endif
Changes to src/vdbe.c.
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.759 2008/07/08 19:34:07 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor







|







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.760 2008/07/10 00:32:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then
** jump to address P2.  
**
** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
** reg(P3) is NULL then take the jump.  If the SQLITE_JUMPIFNULL 
** bit is clear then fall thru if either operand is NULL.
**
** If the SQLITE_NULLEQUAL bit of P5 is set then treat NULL operands
** as being equal to one another.  Normally NULLs are not equal to 
** anything including other NULLs.
**
** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
** to coerce both inputs according to this affinity before the
** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
** affinity is used. Note that the affinity conversions are stored
** back into the input registers P1 and P3.  So this opcode can cause
** persistent changes to registers P1 and P3.







<
<
<
<







1606
1607
1608
1609
1610
1611
1612




1613
1614
1615
1616
1617
1618
1619
** Compare the values in register P1 and P3.  If reg(P3)<reg(P1) then
** jump to address P2.  
**
** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
** reg(P3) is NULL then take the jump.  If the SQLITE_JUMPIFNULL 
** bit is clear then fall thru if either operand is NULL.
**




** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made 
** to coerce both inputs according to this affinity before the
** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
** affinity is used. Note that the affinity conversions are stored
** back into the input registers P1 and P3.  So this opcode can cause
** persistent changes to registers P1 and P3.
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
  int res;
  char affinity;
  Mem x1, x3;

  flags = pIn1->flags|pIn3->flags;

  if( flags&MEM_Null ){
    if( (pOp->p5 & SQLITE_NULLEQUAL)!=0 ){
      /*
      ** When SQLITE_NULLEQUAL set and either operand is NULL
      ** then both operands are converted to integers prior to being 
      ** passed down into the normal comparison logic below.  
      ** NULL operands are converted to zero and non-NULL operands
      ** are converted to 1.  Thus, for example, with SQLITE_NULLEQUAL
      ** set,  NULL==NULL is true whereas it would normally NULL.
      ** Similarly,  NULL!=123 is true.
      */
      x1.flags = MEM_Int;
      x1.u.i = (pIn1->flags & MEM_Null)==0;
      pIn1 = &x1;
      x3.flags = MEM_Int;
      x3.u.i = (pIn3->flags & MEM_Null)==0;
      pIn3 = &x3;
    }else{
      /* If the SQLITE_NULLEQUAL bit is clear and either operand is NULL then
      ** the result is always NULL.  The jump is taken if the 
      ** SQLITE_JUMPIFNULL bit is set.
      */
      if( pOp->p5 & SQLITE_STOREP2 ){
        pOut = &p->aMem[pOp->p2];
        MemSetTypeFlag(pOut, MEM_Null);
        REGISTER_TRACE(pOp->p2, pOut);
      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
        pc = pOp->p2-1;
      }
      break;
    }
  }

  affinity = pOp->p5 & SQLITE_AFF_MASK;
  if( affinity ){
    applyAffinity(pIn1, affinity, encoding);
    applyAffinity(pIn3, affinity, encoding);
  }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<







1671
1672
1673
1674
1675
1676
1677


















1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688

1689
1690
1691
1692
1693
1694
1695
  int res;
  char affinity;
  Mem x1, x3;

  flags = pIn1->flags|pIn3->flags;

  if( flags&MEM_Null ){


















    /* If either operand is NULL then the result is always NULL.
    ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
    */
    if( pOp->p5 & SQLITE_STOREP2 ){
      pOut = &p->aMem[pOp->p2];
      MemSetTypeFlag(pOut, MEM_Null);
      REGISTER_TRACE(pOp->p2, pOut);
    }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
      pc = pOp->p2-1;
    }
    break;

  }

  affinity = pOp->p5 & SQLITE_AFF_MASK;
  if( affinity ){
    applyAffinity(pIn1, affinity, encoding);
    applyAffinity(pIn3, affinity, encoding);
  }
1772
1773
1774
1775
1776
1777
1778

1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
** and strings are less than blobs.
*/
case OP_Compare: {
  int n = pOp->p3;
  int i, p1, p2;
  const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  assert( n>0 );

  p1 = pOp->p1;
  assert( p1>0 && p1+n-1<p->nMem );
  p2 = pOp->p2;
  assert( p2>0 && p2+n-1<p->nMem );
  for(i=0; i<n; i++){
    int idx = aPermute ? aPermute[i] : i;
    CollSeq *pColl;    /* Collating sequence to use on this term */
    int bRev;          /* True for DESCENDING sort order */
    assert( pKeyInfo==0 || i<pKeyInfo->nField );
    REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
    REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);
    if( pKeyInfo ){
      assert( i<pKeyInfo->nField );
      pColl = pKeyInfo->aColl[i];
      bRev = pKeyInfo->aSortOrder[i];
    }else{
      pColl = 0;
      bRev = 0;
    }
    iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);
    if( iCompare ){
      if( bRev ) iCompare = -iCompare;
      break;
    }
  }
  aPermute = 0;







>








<


<
|
|
|
<
<
<
<







1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764

1765
1766

1767
1768
1769




1770
1771
1772
1773
1774
1775
1776
** and strings are less than blobs.
*/
case OP_Compare: {
  int n = pOp->p3;
  int i, p1, p2;
  const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  assert( n>0 );
  assert( pKeyInfo!=0 );
  p1 = pOp->p1;
  assert( p1>0 && p1+n-1<p->nMem );
  p2 = pOp->p2;
  assert( p2>0 && p2+n-1<p->nMem );
  for(i=0; i<n; i++){
    int idx = aPermute ? aPermute[i] : i;
    CollSeq *pColl;    /* Collating sequence to use on this term */
    int bRev;          /* True for DESCENDING sort order */

    REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
    REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);

    assert( i<pKeyInfo->nField );
    pColl = pKeyInfo->aColl[i];
    bRev = pKeyInfo->aSortOrder[i];




    iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);
    if( iCompare ){
      if( bRev ) iCompare = -iCompare;
      break;
    }
  }
  aPermute = 0;
Changes to src/vdbeblob.c.
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.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.23 2008/06/16 14:19:58 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB








|







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.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.24 2008/07/10 00:32:42 drh Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  do {
    Parse sParse;
    Table *pTab;

    memset(&sParse, 0, sizeof(Parse));
    sParse.db = db;

    rc = sqlite3SafetyOn(db);
    if( rc!=SQLITE_OK ){
      sqlite3_mutex_leave(db->mutex);
      return rc;
    }

    sqlite3BtreeEnterAll(db);
    pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
    if( pTab && IsVirtual(pTab) ){
      pTab = 0;
      sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);







|
<

|







92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
  do {
    Parse sParse;
    Table *pTab;

    memset(&sParse, 0, sizeof(Parse));
    sParse.db = db;

    if( sqlite3SafetyOn(db) ){

      sqlite3_mutex_leave(db->mutex);
      return SQLITE_MISUSE;
    }

    sqlite3BtreeEnterAll(db);
    pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
    if( pTab && IsVirtual(pTab) ){
      pTab = 0;
      sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
Changes to test/collate9.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is making sure that the names of collation
# sequences may be quoted using double quotes in SQL statements.
#
# $Id: collate9.test,v 1.1 2007/11/12 09:50:26 danielk1977 Exp $

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

proc reverse_sort {lhs rhs} {
  return [string compare $rhs $lhs]
}







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is making sure that the names of collation
# sequences may be quoted using double quotes in SQL statements.
#
# $Id: collate9.test,v 1.2 2008/07/10 00:32:42 drh Exp $

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

proc reverse_sort {lhs rhs} {
  return [string compare $rhs $lhs]
}
101
102
103
104
105
106
107





108
109
110
111
112
113
114
115
116
117
118
119
120
121
122










123
124
125
126
127
128
129
  }
} {one three two}
do_test collate9-2.5 {
  execsql {
    SELECT y FROM xy ORDER BY y COLLATE "reverse sort"
  }
} {two three one}






do_test collate9-3.1 {
  execsql {
    CREATE INDEX xy_i2 ON xy(y COLLATE "reverse sort");
  }
} {}
do_test collate9-3.2 {
  cksort { 
    SELECT y FROM xy ORDER BY y 
  }
} {one three two sort}
do_test collate9-3.3 {
  cksort { 
    SELECT y FROM xy ORDER BY y COLLATE "reverse sort"
  }










} {two three one nosort}

ifcapable reindex {
  do_test collate9-4.1 {
    execsql {
      REINDEX "reverse sort"
    }







>
>
>
>
>















>
>
>
>
>
>
>
>
>
>







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  }
} {one three two}
do_test collate9-2.5 {
  execsql {
    SELECT y FROM xy ORDER BY y COLLATE "reverse sort"
  }
} {two three one}
do_test collate9-2.6 {
  execsql {
    SELECT y COLLATE "reverse sort" AS aaa FROM xy ORDER BY aaa
  }
} {two three one}

do_test collate9-3.1 {
  execsql {
    CREATE INDEX xy_i2 ON xy(y COLLATE "reverse sort");
  }
} {}
do_test collate9-3.2 {
  cksort { 
    SELECT y FROM xy ORDER BY y 
  }
} {one three two sort}
do_test collate9-3.3 {
  cksort { 
    SELECT y FROM xy ORDER BY y COLLATE "reverse sort"
  }
} {two three one nosort}
do_test collate9-3.4 {
  cksort { 
    SELECT y AS aaa FROM xy ORDER BY aaa
  }
} {one three two sort}
do_test collate9-3.5 {
  cksort { 
    SELECT y COLLATE "reverse sort" AS aaa FROM xy ORDER BY aaa
  }
} {two three one nosort}

ifcapable reindex {
  do_test collate9-4.1 {
    execsql {
      REINDEX "reverse sort"
    }
157
158
159
160
161
162
163
164
    cksort {
      SELECT x FROM xy ORDER BY x COLLATE "reverse sort"
    }
  } {one three two nosort}
}

finish_test








<
172
173
174
175
176
177
178

    cksort {
      SELECT x FROM xy ORDER BY x COLLATE "reverse sort"
    }
  } {one three two nosort}
}

finish_test

Changes to test/select1.test.
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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.62 2008/07/09 01:39:44 drh Exp $

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

# Try to select on a non-existant table.
#
do_test select1-1.1 {













|







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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.63 2008/07/10 00:32:42 drh Exp $

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

# Try to select on a non-existant table.
#
do_test select1-1.1 {
529
530
531
532
533
534
535




















536
537
538
539
540
541
542
     PRAGMA short_column_names=OFF;
     PRAGMA full_column_names=ON;
  }
  execsql2 {
     SELECT 123.45;
  }
} {123.45 123.45}




















db eval {
  PRAGMA short_column_names=ON;
  PRAGMA full_column_names=OFF;
}

ifcapable compound {
do_test select1-6.10 {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







529
530
531
532
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
559
560
561
562
     PRAGMA short_column_names=OFF;
     PRAGMA full_column_names=ON;
  }
  execsql2 {
     SELECT 123.45;
  }
} {123.45 123.45}
do_test select1-6.9.6 {
  execsql2 {
     SELECT * FROM test1 a, test1 b LIMIT 1
  }
} {a.f1 11 a.f2 22 b.f1 11 b.f2 22}
do_test select1-6.9.7 {
  set x [execsql2 {
     SELECT * FROM test1 a, (select 5, 6) LIMIT 1
  }]
  regsub -all {subquery_[0-9a-fA-F]+_} $x {subquery} x
  set x
} {a.f1 11 a.f2 22 sqlite_subquery.5 5 sqlite_subquery.6 6}
do_test select1-6.9.8 {
  set x [execsql2 {
     SELECT * FROM test1 a, (select 5 AS x, 6 AS y) AS b LIMIT 1
  }]
  regsub -all {subquery_[0-9a-fA-F]+_} $x {subquery} x
  set x
} {a.f1 11 a.f2 22 b.x 5 b.y 6}

db eval {
  PRAGMA short_column_names=ON;
  PRAGMA full_column_names=OFF;
}

ifcapable compound {
do_test select1-6.10 {
750
751
752
753
754
755
756





757
758
759
760
761
762
763
  }
} {-11 0 11 22}
do_test select1-10.6 {
  execsql {
    SELECT f1-22 AS x, f2-22 as y FROM test1 WHERE x>0 AND y<50
  }
} {11 22}






# Check the ability to specify "TABLE.*" in the result set of a SELECT
#
do_test select1-11.1 {
  execsql {
    DELETE FROM t3;
    DELETE FROM t4;







>
>
>
>
>







770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
  }
} {-11 0 11 22}
do_test select1-10.6 {
  execsql {
    SELECT f1-22 AS x, f2-22 as y FROM test1 WHERE x>0 AND y<50
  }
} {11 22}
do_test select1-10.7 {
  execsql {
    SELECT f1 COLLATE nocase AS x FROM test1 ORDER BY x
  }
} {11 33}

# Check the ability to specify "TABLE.*" in the result set of a SELECT
#
do_test select1-11.1 {
  execsql {
    DELETE FROM t3;
    DELETE FROM t4;
Changes to test/sqllimits1.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests to verify that the limits defined in
# sqlite source file limits.h are enforced.
#
# $Id: sqllimits1.test,v 1.29 2008/07/08 15:26:50 drh Exp $

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

# Verify that the default per-connection limits are the same as
# the compile-time hard limits.
#







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests to verify that the limits defined in
# sqlite source file limits.h are enforced.
#
# $Id: sqllimits1.test,v 1.30 2008/07/10 00:32:42 drh Exp $

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

# Verify that the default per-connection limits are the same as
# the compile-time hard limits.
#
621
622
623
624
625
626
627




















628
629
630
631
632
633
634
  set cols [list]
  for {set i 0} {$i < $SQLITE_LIMIT_COLUMN} {incr i} {
    lappend cols "c$i"
  }
  catchsql "CREATE TABLE t2([join $cols ,])"
  catchsql "CREATE VIEW v1 AS SELECT *, c1 AS o FROM t2;"
} {1 {too many columns in result set}}





















#--------------------------------------------------------------------
# These tests - sqllimits1-9.* - test that the SQLITE_LIMIT_EXPR_DEPTH
# limit is enforced. The limit refers to the number of terms in 
# the expression.
#
if {$SQLITE_MAX_EXPR_DEPTH==0} {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  set cols [list]
  for {set i 0} {$i < $SQLITE_LIMIT_COLUMN} {incr i} {
    lappend cols "c$i"
  }
  catchsql "CREATE TABLE t2([join $cols ,])"
  catchsql "CREATE VIEW v1 AS SELECT *, c1 AS o FROM t2;"
} {1 {too many columns in result set}}
do_test sqllimits1-8.10 {
  # ORDER BY columns
  set cols [list]
  for {set i 0} {$i <= $SQLITE_LIMIT_COLUMN} {incr i} {
    lappend cols c
  }
  set sql "SELECT c FROM t1 ORDER BY [join $cols ,]"
  catchsql $sql
} {1 {too many terms in ORDER BY clause}}
do_test sqllimits1-8.11 {
  # ORDER BY columns
  set cols [list]
  for {set i 0} {$i <= $SQLITE_LIMIT_COLUMN} {incr i} {
    lappend cols [expr {$i%3 + 1}]
  }
  set sql "SELECT c, c+1, c+2 FROM t1 UNION SELECT c-1, c-2, c-3 FROM t1"
  append sql " ORDER BY [join $cols ,]"
  catchsql $sql
} {1 {too many terms in ORDER BY clause}}


#--------------------------------------------------------------------
# These tests - sqllimits1-9.* - test that the SQLITE_LIMIT_EXPR_DEPTH
# limit is enforced. The limit refers to the number of terms in 
# the expression.
#
if {$SQLITE_MAX_EXPR_DEPTH==0} {
Changes to test/subquery.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2005 January 19
#
# 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.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing correlated subqueries
#
# $Id: subquery.test,v 1.15 2007/09/18 16:53:53 drh Exp $
#

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

ifcapable !subquery {
  finish_test













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2005 January 19
#
# 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.
#
#*************************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing correlated subqueries
#
# $Id: subquery.test,v 1.16 2008/07/10 00:32:42 drh Exp $
#

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

ifcapable !subquery {
  finish_test
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    INSERT INTO t5 VALUES(10, '2002-3');
    INSERT INTO t5 VALUES(15, '2002-4');
    INSERT INTO t5 VALUES(10, '2003-1');
    INSERT INTO t5 VALUES(5, '2003-2');
    INSERT INTO t5 VALUES(25, '2003-3');
    INSERT INTO t5 VALUES(5, '2003-4');

    SELECT "a.period", vsum
    FROM (SELECT 
      a.period,
      (select sum(val) from t5 where period between a.period and '2002-4') vsum
      FROM t5 a where a.period between '2002-1' and '2002-4')
    WHERE vsum < 45 ;
  }
} {2002-2 30 2002-3 25 2002-4 15}
do_test subquery-1.10.5 {
  execsql {
    SELECT "a.period", vsum from
      (select a.period,
      (select sum(val) from t5 where period between a.period and '2002-4') vsum
    FROM t5 a where a.period between '2002-1' and '2002-4') 
    WHERE vsum < 45 ;
  }
} {2002-2 30 2002-3 25 2002-4 15}
do_test subquery-1.10.6 {







|









|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    INSERT INTO t5 VALUES(10, '2002-3');
    INSERT INTO t5 VALUES(15, '2002-4');
    INSERT INTO t5 VALUES(10, '2003-1');
    INSERT INTO t5 VALUES(5, '2003-2');
    INSERT INTO t5 VALUES(25, '2003-3');
    INSERT INTO t5 VALUES(5, '2003-4');

    SELECT period, vsum
    FROM (SELECT 
      a.period,
      (select sum(val) from t5 where period between a.period and '2002-4') vsum
      FROM t5 a where a.period between '2002-1' and '2002-4')
    WHERE vsum < 45 ;
  }
} {2002-2 30 2002-3 25 2002-4 15}
do_test subquery-1.10.5 {
  execsql {
    SELECT period, vsum from
      (select a.period,
      (select sum(val) from t5 where period between a.period and '2002-4') vsum
    FROM t5 a where a.period between '2002-1' and '2002-4') 
    WHERE vsum < 45 ;
  }
} {2002-2 30 2002-3 25 2002-4 15}
do_test subquery-1.10.6 {
Changes to test/view.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2002 February 26
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing VIEW statements.
#
# $Id: view.test,v 1.36 2008/06/30 18:12:28 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Omit this entire file if the library is not configured with views enabled.
ifcapable !view {
  finish_test
  return













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2002 February 26
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing VIEW statements.
#
# $Id: view.test,v 1.37 2008/07/10 00:32:42 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Omit this entire file if the library is not configured with views enabled.
ifcapable !view {
  finish_test
  return
135
136
137
138
139
140
141
142
143
144
145
146
147
148






149
150
151
152
153
154
155
  }
} {a 2 b 3}
do_test view-3.2 {
  execsql2 {
    SELECT * FROM v2 LIMIT 1
  }
} {x 7 a 8 b 9 c 10}
do_test view-3.3 {
  execsql2 {
    DROP VIEW v1;
    CREATE VIEW v1 AS SELECT a AS 'xyz', b+c AS 'pqr', c-b FROM t1;
    SELECT * FROM v1 LIMIT 1
  }
} {xyz 2 pqr 7 c-b 1}







ifcapable compound {
do_test  view-3.4 {
  execsql2 {
    CREATE VIEW v3 AS SELECT a FROM t1 UNION SELECT b FROM t1 ORDER BY b;
    SELECT * FROM v3 LIMIT 4;
  }







|






>
>
>
>
>
>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  }
} {a 2 b 3}
do_test view-3.2 {
  execsql2 {
    SELECT * FROM v2 LIMIT 1
  }
} {x 7 a 8 b 9 c 10}
do_test view-3.3.1 {
  execsql2 {
    DROP VIEW v1;
    CREATE VIEW v1 AS SELECT a AS 'xyz', b+c AS 'pqr', c-b FROM t1;
    SELECT * FROM v1 LIMIT 1
  }
} {xyz 2 pqr 7 c-b 1}
do_test view-3.3.2 {
  execsql2 {
    CREATE VIEW v1b AS SELECT t1.a, b+c, t1.c FROM t1;
    SELECT * FROM v1b LIMIT 1
  }
} {a 2 b+c 7 c 4}

ifcapable compound {
do_test  view-3.4 {
  execsql2 {
    CREATE VIEW v3 AS SELECT a FROM t1 UNION SELECT b FROM t1 ORDER BY b;
    SELECT * FROM v3 LIMIT 4;
  }