SQLite

Check-in [0051c87d5e]
Login

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

Overview
Comment:Fix a bug in the reverse scan logic that comes up when the table being scanned is empty. Add additional tests for the reverse scan. (CVS 797)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0051c87d5e8d07fae09da2eb7b0d8cbd1bbd3c8e
User & Date: drh 2002-12-04 22:29:28.000
Context
2002-12-07
21:45
Save the full pathname of the database file so that journalling still works even if the user changes working directories after opening the databae. Ticket #200. (CVS 798) (check-in: 1c58b4fc03 user: drh tags: trunk)
2002-12-04
22:29
Fix a bug in the reverse scan logic that comes up when the table being scanned is empty. Add additional tests for the reverse scan. (CVS 797) (check-in: 0051c87d5e user: drh tags: trunk)
21:50
Fixes to the logic that decides if the ORDER BY can be ignored due to the use of an index. Tests updated. (CVS 796) (check-in: bfb9a2aa93 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
/*
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.74 2002/12/04 13:40:26 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
/*
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.75 2002/12/04 22:29:28 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.
1491
1492
1493
1494
1495
1496
1497
1498

1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
**
** The result of comparing the key with the entry to which the
** cursor is left pointing is stored in pCur->iMatch.  The same
** value is also written to *pRes if pRes!=NULL.  The meaning of
** this value is as follows:
**
**     *pRes<0      The cursor is left pointing at an entry that
**                  is smaller than pKey.

**
**     *pRes==0     The cursor is left pointing at an entry that
**                  exactly matches pKey.
**
**     *pRes>0      The cursor is left pointing at an entry that
**                  is larger than pKey.
*/
int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){
  int rc;
  if( pCur->pPage==0 ) return SQLITE_ABORT;
  pCur->eSkip = SKIP_NONE;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  for(;;){
    int lwr, upr;
    Pgno chldPg;
    MemPage *pPage = pCur->pPage;
    int c = -1;
    lwr = 0;
    upr = pPage->nCell-1;
    while( lwr<=upr ){
      pCur->idx = (lwr+upr)/2;
      rc = sqliteBtreeKeyCompare(pCur, pKey, nKey, 0, &c);
      if( rc ) return rc;
      if( c==0 ){







|
>

















|







1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
**
** The result of comparing the key with the entry to which the
** cursor is left pointing is stored in pCur->iMatch.  The same
** value is also written to *pRes if pRes!=NULL.  The meaning of
** this value is as follows:
**
**     *pRes<0      The cursor is left pointing at an entry that
**                  is smaller than pKey or if the table is empty
**                  and the cursor is therefore left point to nothing.
**
**     *pRes==0     The cursor is left pointing at an entry that
**                  exactly matches pKey.
**
**     *pRes>0      The cursor is left pointing at an entry that
**                  is larger than pKey.
*/
int sqliteBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){
  int rc;
  if( pCur->pPage==0 ) return SQLITE_ABORT;
  pCur->eSkip = SKIP_NONE;
  rc = moveToRoot(pCur);
  if( rc ) return rc;
  for(;;){
    int lwr, upr;
    Pgno chldPg;
    MemPage *pPage = pCur->pPage;
    int c = -1;  /* pRes return if table is empty must be -1 */
    lwr = 0;
    upr = pPage->nCell-1;
    while( lwr<=upr ){
      pCur->idx = (lwr+upr)/2;
      rc = sqliteBtreeKeyCompare(pCur, pKey, nKey, 0, &c);
      if( rc ) return rc;
      if( c==0 ){
Changes to src/vdbe.c.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
**
** 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.186 2002/12/04 20:01:06 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
**
** 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.187 2002/12/04 22:29:29 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The makefile scans this source file and creates the following
** array of string constants which are the names of all VDBE opcodes.
3390
3391
3392
3393
3394
3395
3396
3397

3398
3399







3400
3401
3402
3403
3404
3405
3406
    oc = pOp->opcode;
    if( oc==OP_MoveTo && res<0 ){
      sqliteBtreeNext(pC->pCursor, &res);
      pC->recnoIsValid = 0;
      if( res && pOp->p2>0 ){
        pc = pOp->p2 - 1;
      }
    }else if( oc==OP_MoveLt && res>=0 ){

      sqliteBtreePrevious(pC->pCursor, &res);
      pC->recnoIsValid = 0;







      if( res && pOp->p2>0 ){
        pc = pOp->p2 - 1;
      }
    }
  }
  POPSTACK;
  break;







|
>
|
|
>
>
>
>
>
>
>







3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
    oc = pOp->opcode;
    if( oc==OP_MoveTo && res<0 ){
      sqliteBtreeNext(pC->pCursor, &res);
      pC->recnoIsValid = 0;
      if( res && pOp->p2>0 ){
        pc = pOp->p2 - 1;
      }
    }else if( oc==OP_MoveLt ){
      if( res>=0 ){
        sqliteBtreePrevious(pC->pCursor, &res);
        pC->recnoIsValid = 0;
      }else{
        /* res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        int keysize;
        res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0;
      }
      if( res && pOp->p2>0 ){
        pc = pOp->p2 - 1;
      }
    }
  }
  POPSTACK;
  break;
Changes to test/where.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 use of indices in WHERE clases.
#
# $Id: where.test,v 1.12 2002/12/04 21:50:16 drh Exp $

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

# Build some test data
#
do_test where-1.0 {













|







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 use of indices in WHERE clases.
#
# $Id: where.test,v 1.13 2002/12/04 22:29:29 drh Exp $

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

# Build some test data
#
do_test where-1.0 {
584
585
586
587
588
589
590



591
































































































592
  }
} {11 12 13 nosort}
do_test where-7.14 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y>100 AND y<196 ORDER BY y;
  }
} {10 11 12 nosort}




































































































finish_test







>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

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
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
  }
} {11 12 13 nosort}
do_test where-7.14 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y>100 AND y<196 ORDER BY y;
  }
} {10 11 12 nosort}
do_test where-7.15 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y<81 ORDER BY y;
  }
} {nosort}
do_test where-7.16 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y<=81 ORDER BY y;
  }
} {8 nosort}
do_test where-7.17 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y>256 ORDER BY y;
  }
} {nosort}
do_test where-7.18 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y>=256 ORDER BY y;
  }
} {15 nosort}
do_test where-7.19 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y<81 ORDER BY y DESC;
  }
} {nosort}
do_test where-7.20 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y<=81 ORDER BY y DESC;
  }
} {8 nosort}
do_test where-7.21 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y>256 ORDER BY y DESC;
  }
} {nosort}
do_test where-7.22 {
  cksort {
    SELECT w FROM t1 WHERE x=3 AND y>=256 ORDER BY y DESC;
  }
} {15 nosort}
do_test where-7.23 {
  cksort {
    SELECT w FROM t1 WHERE x=0 AND y<4 ORDER BY y;
  }
} {nosort}
do_test where-7.24 {
  cksort {
    SELECT w FROM t1 WHERE x=0 AND y<=4 ORDER BY y;
  }
} {1 nosort}
do_test where-7.25 {
  cksort {
    SELECT w FROM t1 WHERE x=6 AND y>10201 ORDER BY y;
  }
} {nosort}
do_test where-7.26 {
  cksort {
    SELECT w FROM t1 WHERE x=6 AND y>=10201 ORDER BY y;
  }
} {100 nosort}
do_test where-7.27 {
  cksort {
    SELECT w FROM t1 WHERE x=0 AND y<4 ORDER BY y DESC;
  }
} {nosort}
do_test where-7.28 {
  cksort {
    SELECT w FROM t1 WHERE x=0 AND y<=4 ORDER BY y DESC;
  }
} {1 nosort}
do_test where-7.29 {
  cksort {
    SELECT w FROM t1 WHERE x=6 AND y>10201 ORDER BY y DESC;
  }
} {nosort}
do_test where-7.30 {
  cksort {
    SELECT w FROM t1 WHERE x=6 AND y>=10201 ORDER BY y DESC;
  }
} {100 nosort}

do_test where-8.1 {
  execsql {
    CREATE TABLE t4 AS SELECT * FROM t1;
    CREATE INDEX i4xy ON t4(x,y);
  }
  cksort {
    SELECT w FROM t4 WHERE x=4 and y<1000 ORDER BY y DESC limit 3;
  }
} {30 29 28 nosort}
do_test where-8.2 {
  execsql {
    DELETE FROM t4;
  }
  cksort {
    SELECT w FROM t4 WHERE x=4 and y<1000 ORDER BY y DESC limit 3;
  }
} {nosort}


finish_test