SQLite

Check-in [bcc7d722ce]
Login

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

Overview
Comment:All regression tests now pass. But I am sure there must still be problems. New tests need to be added. (CVS 2666)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bcc7d722cea4487a3adf9d9b2af4b74bfbfc5f39
User & Date: drh 2005-09-08 00:13:27.000
Context
2005-09-08
01:58
Optimizations and refinements. Improvements to test coverage. (CVS 2667) (check-in: 7283f7c29d user: drh tags: trunk)
00:13
All regression tests now pass. But I am sure there must still be problems. New tests need to be added. (CVS 2666) (check-in: bcc7d722ce user: drh tags: trunk)
2005-09-07
23:05
More bug fixes. All of the "quick" tests pass. The full test suite still shows problems. (CVS 2665) (check-in: a1b6d910cd user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.345 2005/09/07 21:22:46 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.346 2005/09/08 00:13:27 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503

2504
2505
2506
2507
2508
2509
2510
** number of array entries allocated on the initial allocation.
*/
int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){
  char *p;
  int *an = (int*)&ppArray[1];
  if( an[0]>=an[1] ){
    void *pNew;

    an[1] = an[1]*2 + initSize;
    pNew = sqliteRealloc(*ppArray, an[1]*szEntry);
    if( pNew==0 ){
      return -1;
    }

    *ppArray = pNew;
  }
  p = *ppArray;
  memset(&p[an[0]*szEntry], 0, szEntry);
  return an[0]++;
}








>
|
|



>







2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
** number of array entries allocated on the initial allocation.
*/
int sqlite3ArrayAllocate(void **ppArray, int szEntry, int initSize){
  char *p;
  int *an = (int*)&ppArray[1];
  if( an[0]>=an[1] ){
    void *pNew;
    int newSize;
    newSize = an[1]*2 + initSize;
    pNew = sqliteRealloc(*ppArray, newSize*szEntry);
    if( pNew==0 ){
      return -1;
    }
    an[1] = newSize;
    *ppArray = pNew;
  }
  p = *ppArray;
  memset(&p[an[0]*szEntry], 0, szEntry);
  return an[0]++;
}

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.263 2005/09/07 22:48:16 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.







|







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.264 2005/09/08 00:13:28 drh Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
2796
2797
2798
2799
2800
2801
2802

2803
2804
2805
2806
2807
2808
2809
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
        goto select_end;
      }
    }


    /* Processing for aggregates with GROUP BY is very different and
    ** much more complex tha aggregates without a GROUP BY.
    */
    if( pGroupBy ){
      KeyInfo *pKeyInfo;  /* Keying information for the group by clause */








>







2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
    }
    sAggInfo.nAccumulator = sAggInfo.nColumn;
    for(i=0; i<sAggInfo.nFunc; i++){
      if( sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->pList) ){
        goto select_end;
      }
    }
    if( sqlite3_malloc_failed ) goto select_end;

    /* Processing for aggregates with GROUP BY is very different and
    ** much more complex tha aggregates without a GROUP BY.
    */
    if( pGroupBy ){
      KeyInfo *pKeyInfo;  /* Keying information for the group by clause */

2869
2870
2871
2872
2873
2874
2875

2876
2877
2878
2879
2880
2881
2882
      /* Begin a loop that will extract all source rows in GROUP BY order.
      ** This might involve two separate loops with an OP_Sort in between, or
      ** it might be a single loop that uses an index to extract information
      ** in the right order to begin with.
      */
      sqlite3VdbeResolveLabel(v, addrInitializeLoop);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy);

      if( pGroupBy==0 ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenVirtual table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        pGroupBy = p->pGroupBy;
        groupBySort = 0;







>







2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
      /* Begin a loop that will extract all source rows in GROUP BY order.
      ** This might involve two separate loops with an OP_Sort in between, or
      ** it might be a single loop that uses an index to extract information
      ** in the right order to begin with.
      */
      sqlite3VdbeResolveLabel(v, addrInitializeLoop);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy);
      if( pWInfo==0 ) goto select_end;
      if( pGroupBy==0 ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenVirtual table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        pGroupBy = p->pGroupBy;
        groupBySort = 0;
2977
2978
2979
2980
2981
2982
2983

2984
2985
2986
2987
2988
2989
2990
    else {
      /* This case runs if the aggregate has no GROUP BY clause.  The
      ** processing is much simpler since there is only a single row
      ** of output.
      */
      resetAccumulator(pParse, &sAggInfo);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);

      updateAccumulator(pParse, &sAggInfo);
      sqlite3WhereEnd(pWInfo);
      finalizeAggFunctions(pParse, &sAggInfo);
      pOrderBy = 0;
      if( pHaving ){
        sqlite3ExprIfFalse(pParse, pHaving, addrEnd, 1);
      }







>







2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
    else {
      /* This case runs if the aggregate has no GROUP BY clause.  The
      ** processing is much simpler since there is only a single row
      ** of output.
      */
      resetAccumulator(pParse, &sAggInfo);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0);
      if( pWInfo==0 ) goto select_end;
      updateAccumulator(pParse, &sAggInfo);
      sqlite3WhereEnd(pWInfo);
      finalizeAggFunctions(pParse, &sAggInfo);
      pOrderBy = 0;
      if( pHaving ){
        sqlite3ExprIfFalse(pParse, pHaving, addrEnd, 1);
      }
Changes to src/vdbeapi.c.
261
262
263
264
265
266
267

268
269
270
271
272
273
274
  Mem *pMem = p->pMem;
  if( (pMem->flags & MEM_Agg)==0 ){
    if( nByte==0 ){
      assert( pMem->flags==MEM_Null );
      pMem->z = 0;
    }else{
      pMem->flags = MEM_Agg;

      *(FuncDef**)&pMem->i = p->pFunc;
      if( nByte<=NBFS ){
        pMem->z = pMem->zShort;
        memset(pMem->z, 0, nByte);
      }else{
        pMem->z = sqliteMalloc( nByte );
      }







>







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
  Mem *pMem = p->pMem;
  if( (pMem->flags & MEM_Agg)==0 ){
    if( nByte==0 ){
      assert( pMem->flags==MEM_Null );
      pMem->z = 0;
    }else{
      pMem->flags = MEM_Agg;
      pMem->xDel = sqlite3FreeX;
      *(FuncDef**)&pMem->i = p->pFunc;
      if( nByte<=NBFS ){
        pMem->z = pMem->zShort;
        memset(pMem->z, 0, nByte);
      }else{
        pMem->z = sqliteMalloc( nByte );
      }
Changes to test/malloc.test.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#***********************************************************************
# This file attempts to check the library in an out-of-memory situation.
# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
# command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
# special feature is used to see what happens in the library if a malloc
# were to really fail due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.23 2005/08/19 01:07:16 drh Exp $

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

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#***********************************************************************
# This file attempts to check the library in an out-of-memory situation.
# When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special
# command (sqlite_malloc_fail N) which causes the N-th malloc to fail.  This
# special feature is used to see what happens in the library if a malloc
# were to really fail due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.24 2005/09/08 00:13:28 drh Exp $

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

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
  array set ::mallocopts $args

  set ::go 1
  for {set ::n 1} {$::go} {incr ::n} {

    do_test malloc-$tn.$::n {

      sqlite_malloc_fail 0
      catch {db close}
      catch {file delete -force test.db}
      catch {file delete -force test.db-journal}
      catch {file delete -force test2.db}







<







52
53
54
55
56
57
58

59
60
61
62
63
64
65
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
  array set ::mallocopts $args

  set ::go 1
  for {set ::n 1} {$::go} {incr ::n} {

    do_test malloc-$tn.$::n {

      sqlite_malloc_fail 0
      catch {db close}
      catch {file delete -force test.db}
      catch {file delete -force test.db-journal}
      catch {file delete -force test2.db}