SQLite

Check-in [21adf4bd99]
Login

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

Overview
Comment:The SUM() aggregate function returns an integer result if all inputs are integers. Any single non-integer input causes the result to be a floating point value. (CVS 2669)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 21adf4bd99e732650a1e8e9a1cc954126983a654
User & Date: drh 2005-09-08 10:37:01.000
Context
2005-09-08
10:58
Fix a comment in sqlite.h. Ticket #1321. (CVS 2670) (check-in: ed4e9e751b user: drh tags: trunk)
10:37
The SUM() aggregate function returns an integer result if all inputs are integers. Any single non-integer input causes the result to be a floating point value. (CVS 2669) (check-in: 21adf4bd99 user: drh tags: trunk)
02:00
Changes to comments only in sqliteInt.h. No changes to code. (CVS 2668) (check-in: cc2a61650e user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/func.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.107 2005/09/06 20:36:49 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.108 2005/09/08 10:37:01 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
815
816
817
818
819
820
821

822
823
824
825
826
827
828

829
830
831

832
833

834
835
836
837
838



839



840
841
842
843
844
845
846
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
  int cnt;        /* Number of elements summed */

};

/*
** Routines used to compute the sum or average.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  SumCtx *p;

  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( p && SQLITE_NULL!=sqlite3_value_type(argv[0]) ){

    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;

  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);



  sqlite3_result_double(context, p ? p->sum : 0.0);



}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }







>







>


|
>


>





>
>
>
|
>
>
>







815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
typedef struct SumCtx SumCtx;
struct SumCtx {
  double sum;     /* Sum of terms */
  int cnt;        /* Number of elements summed */
  int isFloat;    /* True if there has been any floating point value */
};

/*
** Routines used to compute the sum or average.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
  SumCtx *p;
  int type;
  if( argc<1 ) return;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_type(argv[0]);
  if( p && type!=SQLITE_NULL ){
    p->sum += sqlite3_value_double(argv[0]);
    p->cnt++;
    if( type==SQLITE_FLOAT ) p->isFloat = 1;
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p==0 ){
    sqlite3_result_int(context, 0);
  }else if( p->isFloat ){
    sqlite3_result_double(context, p->sum);
  }else{
    sqlite3_result_int64(context, (i64)p->sum);
  }
}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->sum/(double)p->cnt);
  }
Changes to test/autovacuum.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: autovacuum.test,v 1.17 2005/03/09 13:09:45 danielk1977 Exp $

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

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum} {













|







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: autovacuum.test,v 1.18 2005/09/08 10:37:01 drh Exp $

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

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum} {
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
  for {set i 0} {$i<100} {incr i} {
    execsql "INSERT INTO av1 VALUES($i, '[string repeat X 200]');"
  }
  execsql "INSERT INTO av1 VALUES(99, '[string repeat X 200]');"
  execsql {
    SELECT sum(a) FROM av1;
  }
} {5049.0}
do_test autovacuum-4.2 {
  catchsql {
    CREATE UNIQUE INDEX av1_i ON av1(a);
  }
} {1 {indexed columns are not unique}}
do_test autovacuum-4.3 {
  execsql {
    SELECT sum(a) FROM av1;
  }
} {5049.0}
do_test autovacuum-4.4 {
  execsql {
    COMMIT;
  }
} {}

finish_test







|









|







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
  for {set i 0} {$i<100} {incr i} {
    execsql "INSERT INTO av1 VALUES($i, '[string repeat X 200]');"
  }
  execsql "INSERT INTO av1 VALUES(99, '[string repeat X 200]');"
  execsql {
    SELECT sum(a) FROM av1;
  }
} {5049}
do_test autovacuum-4.2 {
  catchsql {
    CREATE UNIQUE INDEX av1_i ON av1(a);
  }
} {1 {indexed columns are not unique}}
do_test autovacuum-4.3 {
  execsql {
    SELECT sum(a) FROM av1;
  }
} {5049}
do_test autovacuum-4.4 {
  execsql {
    COMMIT;
  }
} {}

finish_test
Changes to test/func.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 built-in functions.
#
# $Id: func.test,v 1.37 2005/08/12 23:20:53 drh Exp $

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

# Create a table to work with.
#
do_test func-0.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 built-in functions.
#
# $Id: func.test,v 1.38 2005/09/08 10:37:01 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
do_test func-8.1 {
  ifcapable explain {
    execsql {EXPLAIN SELECT sum(a) FROM t2;}
  }
  execsql {
    SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
  }
} {68236.0 3 22745.33 1 67890 5}
do_test func-8.2 {
  execsql {
    SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
  }
} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}

ifcapable tempdb {







|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
do_test func-8.1 {
  ifcapable explain {
    execsql {EXPLAIN SELECT sum(a) FROM t2;}
  }
  execsql {
    SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
  }
} {68236 3 22745.33 1 67890 5}
do_test func-8.2 {
  execsql {
    SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
  }
} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}

ifcapable tempdb {
491
492
493
494
495
496
497

















498
499
500
  proc testfunc1 args {error "Error %d with %s percents %p"}
  db function testfunc1 ::testfunc1
  catchsql {
    SELECT testfunc1(1,2,3);
  }
} {1 {Error %d with %s percents %p}}




















finish_test







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



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
  proc testfunc1 args {error "Error %d with %s percents %p"}
  db function testfunc1 ::testfunc1
  catchsql {
    SELECT testfunc1(1,2,3);
  }
} {1 {Error %d with %s percents %p}}

# The SUM function should return integer results when all inputs are integer.
#
do_test func-18.1 {
  execsql {
    CREATE TABLE t5(x);
    INSERT INTO t5 VALUES(1);
    INSERT INTO t5 VALUES(-99);
    INSERT INTO t5 VALUES(10000);
    SELECT sum(x) FROM t5;
  }
} {9902}
do_test func-18.2 {
  execsql {
    INSERT INTO t5 VALUES(0.0);
    SELECT sum(x) FROM t5;
  }
} {9902.0}


finish_test
Changes to test/limit.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 implements regression tests for SQLite library.  The
# focus of this file is testing the LIMIT ... OFFSET ... clause
#  of SELECT statements.
#
# $Id: limit.test,v 1.24 2005/02/05 12:48:49 danielk1977 Exp $

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

# Build some test data
#
execsql {







|







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 implements regression tests for SQLite library.  The
# focus of this file is testing the LIMIT ... OFFSET ... clause
#  of SELECT statements.
#
# $Id: limit.test,v 1.25 2005/09/08 10:37:01 drh Exp $

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

# Build some test data
#
execsql {
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
do_test limit-5.5 {
  execsql {
    DELETE FROM t5;
    INSERT INTO t5 SELECT a.x*100+b.x, a.y*100+b.y FROM t1 AS a, t1 AS b
                   ORDER BY 1, 2 LIMIT 1000;
    SELECT count(*), sum(x), sum(y), min(x), max(x), min(y), max(y) FROM t5;
  }
} {1000 1528204.0 593161.0 0 3107 505 1005}

# There is some contraversy about whether LIMIT 0 should be the same as
# no limit at all or if LIMIT 0 should result in zero output rows.
#
do_test limit-6.1 {
  execsql {
    BEGIN;







|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
do_test limit-5.5 {
  execsql {
    DELETE FROM t5;
    INSERT INTO t5 SELECT a.x*100+b.x, a.y*100+b.y FROM t1 AS a, t1 AS b
                   ORDER BY 1, 2 LIMIT 1000;
    SELECT count(*), sum(x), sum(y), min(x), max(x), min(y), max(y) FROM t5;
  }
} {1000 1528204 593161 0 3107 505 1005}

# There is some contraversy about whether LIMIT 0 should be the same as
# no limit at all or if LIMIT 0 should result in zero output rows.
#
do_test limit-6.1 {
  execsql {
    BEGIN;
Changes to test/minmax.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that contain
# aggregate min() and max() functions and which are handled as
# as a special case.
#
# $Id: minmax.test,v 1.16 2005/01/21 04:25:47 danielk1977 Exp $

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

do_test minmax-1.0 {
  execsql {
    BEGIN;







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that contain
# aggregate min() and max() functions and which are handled as
# as a special case.
#
# $Id: minmax.test,v 1.17 2005/09/08 10:37:01 drh Exp $

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

do_test minmax-1.0 {
  execsql {
    BEGIN;
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  } {1 20}
  do_test minmax-4.2 {
    execsql {
      SELECT y, sum(x) FROM
        (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1)
      GROUP BY y ORDER BY y;
    }
  } {1 1.0 2 5.0 3 22.0 4 92.0 5 90.0 6 0.0}
  do_test minmax-4.3 {
    execsql {
      SELECT y, count(x), count(*) FROM
        (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1)
      GROUP BY y ORDER BY y;
    }
  } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1}







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  } {1 20}
  do_test minmax-4.2 {
    execsql {
      SELECT y, sum(x) FROM
        (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1)
      GROUP BY y ORDER BY y;
    }
  } {1 1 2 5 3 22 4 92 5 90 6 0}
  do_test minmax-4.3 {
    execsql {
      SELECT y, count(x), count(*) FROM
        (SELECT null, y+1 FROM t1 UNION SELECT * FROM t1)
      GROUP BY y ORDER BY y;
    }
  } {1 1 1 2 2 3 3 4 5 4 8 9 5 5 6 6 0 1}
Changes to test/misc1.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.37 2005/08/19 03:03:52 drh Exp $

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

# Mimic the SQLite 2 collation type NUMERIC.
db collate numeric numeric_collate
proc numeric_collate {lhs rhs} {







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.38 2005/09/08 10:37:01 drh Exp $

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

# Mimic the SQLite 2 collation type NUMERIC.
db collate numeric numeric_collate
proc numeric_collate {lhs rhs} {
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    COMMIT
  }
  execsql {SELECT count(*) FROM agger}
} 6
do_test misc1-2.2 {
  execsql {SELECT sum(one), two, four FROM agger
           GROUP BY two, four ORDER BY sum(one) desc}
} {8.0 two no 6.0 one yes 4.0 two yes 3.0 thr yes}
do_test misc1-2.3 {
  execsql {SELECT sum((one)), (two), (four) FROM agger
           GROUP BY (two), (four) ORDER BY sum(one) desc}
} {8.0 two no 6.0 one yes 4.0 two yes 3.0 thr yes}

# Here's a test for a bug found by Joel Lucsy.  The code below
# was causing an assertion failure.
#
do_test misc1-3.1 {
  set r [execsql {
    CREATE TABLE t1(a);







|



|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    COMMIT
  }
  execsql {SELECT count(*) FROM agger}
} 6
do_test misc1-2.2 {
  execsql {SELECT sum(one), two, four FROM agger
           GROUP BY two, four ORDER BY sum(one) desc}
} {8 two no 6 one yes 4 two yes 3 thr yes}
do_test misc1-2.3 {
  execsql {SELECT sum((one)), (two), (four) FROM agger
           GROUP BY (two), (four) ORDER BY sum(one) desc}
} {8 two no 6 one yes 4 two yes 3 thr yes}

# Here's a test for a bug found by Joel Lucsy.  The code below
# was causing an assertion failure.
#
do_test misc1-3.1 {
  set r [execsql {
    CREATE TABLE t1(a);
Changes to test/misc4.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc4.test,v 1.19 2005/09/08 01:58:43 drh Exp $

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

# Prepare a statement that will create a temporary table.  Then do
# a rollback.  Then try to execute the prepared statement.
#







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc4.test,v 1.20 2005/09/08 10:37:01 drh Exp $

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

# Prepare a statement that will create a temporary table.  Then do
# a rollback.  Then try to execute the prepared statement.
#
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
      insert into b values ('+1',3);
      insert into b values ('+1',4);
      
      select a.*, x.*
        from a, (select key,sum(period) from b group by key) as x
        where a.key=x.key;
    }
  } {01 data01 01 3.0 +1 data+1 +1 7.0}

  # This test case tests the same property as misc4-4.1, but it is
  # a bit smaller which makes it easier to work with while debugging.
  do_test misc4-4.2 {
    execsql {
      CREATE TABLE ab(a TEXT, b TEXT);
      INSERT INTO ab VALUES('01', '1');







|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
      insert into b values ('+1',3);
      insert into b values ('+1',4);
      
      select a.*, x.*
        from a, (select key,sum(period) from b group by key) as x
        where a.key=x.key;
    }
  } {01 data01 01 3 +1 data+1 +1 7}

  # This test case tests the same property as misc4-4.1, but it is
  # a bit smaller which makes it easier to work with while debugging.
  do_test misc4-4.2 {
    execsql {
      CREATE TABLE ab(a TEXT, b TEXT);
      INSERT INTO ab VALUES('01', '1');
Changes to test/null.test.
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# Check to see that NULL values are ignored in aggregate functions.
#
do_test null-3.1 {
  execsql {
    select count(*), count(b), count(c), sum(b), sum(c), 
           avg(b), avg(c), min(b), max(b) from t1;
  }
} {7 4 6 2.0 3.0 0.5 0.5 0 1}

# Check to see how WHERE clauses handle NULL values.  A NULL value
# is the same as UNKNOWN.  The WHERE clause should only select those
# rows that are TRUE.  FALSE and UNKNOWN rows are rejected.
#
do_test null-4.1 {
  execsql {







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# Check to see that NULL values are ignored in aggregate functions.
#
do_test null-3.1 {
  execsql {
    select count(*), count(b), count(c), sum(b), sum(c), 
           avg(b), avg(c), min(b), max(b) from t1;
  }
} {7 4 6 2 3 0.5 0.5 0 1}

# Check to see how WHERE clauses handle NULL values.  A NULL value
# is the same as UNKNOWN.  The WHERE clause should only select those
# rows that are TRUE.  FALSE and UNKNOWN rows are rejected.
#
do_test null-4.1 {
  execsql {
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.42 2005/01/21 04:25:47 danielk1977 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.43 2005/09/08 10:37:01 drh Exp $

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

# Try to select on a non-existant table.
#
do_test select1-1.1 {
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
do_test select1-2.14 {
  set v [catch {execsql {SELECT SUM(*) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function SUM()}}
do_test select1-2.15 {
  set v [catch {execsql {SELECT Sum(f1) FROM test1}} msg]
  lappend v $msg
} {0 44.0}
do_test select1-2.16 {
  set v [catch {execsql {SELECT sum(f1,f2) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function sum()}}
do_test select1-2.17 {
  set v [catch {execsql {SELECT SUM(f1)+1 FROM test1}} msg]
  lappend v $msg
} {0 45.0}
do_test select1-2.17.1 {
  execsql {SELECT sum(a) FROM t3}
} {44.0}
do_test select1-2.18 {
  set v [catch {execsql {SELECT XYZZY(f1) FROM test1}} msg]
  lappend v $msg
} {1 {no such function: XYZZY}}
do_test select1-2.19 {
  set v [catch {execsql {SELECT SUM(min(f1,f2)) FROM test1}} msg]
  lappend v $msg
} {0 44.0}
do_test select1-2.20 {
  set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg]
  lappend v $msg
} {1 {misuse of aggregate function min()}}

# WHERE clause expressions
#







|







|


|







|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
do_test select1-2.14 {
  set v [catch {execsql {SELECT SUM(*) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function SUM()}}
do_test select1-2.15 {
  set v [catch {execsql {SELECT Sum(f1) FROM test1}} msg]
  lappend v $msg
} {0 44}
do_test select1-2.16 {
  set v [catch {execsql {SELECT sum(f1,f2) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function sum()}}
do_test select1-2.17 {
  set v [catch {execsql {SELECT SUM(f1)+1 FROM test1}} msg]
  lappend v $msg
} {0 45}
do_test select1-2.17.1 {
  execsql {SELECT sum(a) FROM t3}
} {44}
do_test select1-2.18 {
  set v [catch {execsql {SELECT XYZZY(f1) FROM test1}} msg]
  lappend v $msg
} {1 {no such function: XYZZY}}
do_test select1-2.19 {
  set v [catch {execsql {SELECT SUM(min(f1,f2)) FROM test1}} msg]
  lappend v $msg
} {0 44}
do_test select1-2.20 {
  set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg]
  lappend v $msg
} {1 {misuse of aggregate function min()}}

# WHERE clause expressions
#
Changes to test/select3.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 implements regression tests for SQLite library.  The
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select3.test,v 1.13 2005/04/01 10:47:40 drh Exp $

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

# Build some test data
#
do_test select3-1.0 {







|







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 implements regression tests for SQLite library.  The
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select3.test,v 1.14 2005/09/08 10:37:01 drh Exp $

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

# Build some test data
#
do_test select3-1.0 {
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  execsql {SELECT count(*) FROM t1}
} {31}
do_test select3-1.2 {
  execsql {
    SELECT min(n),min(log),max(n),max(log),sum(n),sum(log),avg(n),avg(log)
    FROM t1
  }
} {1 0 31 5 496.0 124.0 16.0 4.0}
do_test select3-1.3 {
  execsql {SELECT max(n)/avg(n), max(log)/avg(log) FROM t1}
} {1.9375 1.25}

# Try some basic GROUP BY clauses
#
do_test select3-2.1 {







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  execsql {SELECT count(*) FROM t1}
} {31}
do_test select3-1.2 {
  execsql {
    SELECT min(n),min(log),max(n),max(log),sum(n),sum(log),avg(n),avg(log)
    FROM t1
  }
} {1 0 31 5 496 124 16.0 4.0}
do_test select3-1.3 {
  execsql {SELECT max(n)/avg(n), max(log)/avg(log) FROM t1}
} {1.9375 1.25}

# Try some basic GROUP BY clauses
#
do_test select3-2.1 {
Changes to test/select5.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 implements regression tests for SQLite library.  The
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select5.test,v 1.11 2005/09/07 22:48:16 drh Exp $

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

# Build some test data
#
execsql {







|







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 implements regression tests for SQLite library.  The
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select5.test,v 1.12 2005/09/08 10:37:01 drh Exp $

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

# Build some test data
#
execsql {
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    SELECT max(x) FROM t1 WHERE x>100
  }
} {{}}
do_test select5-4.5 {
  execsql {
    SELECT sum(x) FROM t1 WHERE x>100
  }
} {0.0}

# Some tests for queries with a GROUP BY clause but no aggregate functions.
#
# Note: The query in test case 5-5.5 are not legal SQL. So if the 
# implementation changes in the future and it returns different results,
# this is not such a big deal.
#







|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    SELECT max(x) FROM t1 WHERE x>100
  }
} {{}}
do_test select5-4.5 {
  execsql {
    SELECT sum(x) FROM t1 WHERE x>100
  }
} {0}

# Some tests for queries with a GROUP BY clause but no aggregate functions.
#
# Note: The query in test case 5-5.5 are not legal SQL. So if the 
# implementation changes in the future and it returns different results,
# this is not such a big deal.
#
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.12 2005/08/25 12:45:04 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.13 2005/09/08 10:37:01 drh Exp $
#

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

ifcapable !subquery {
  finish_test
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    SELECT * FROM (SELECT (SELECT a), b FROM t1);
  }
} {1 3 3 13 5 31 7 57}
do_test subquery-1.10.3 {
  execsql {
    SELECT * FROM (SELECT (SELECT sum(a) FROM t1));
  }
} {16.0}
do_test subquery-1.10.4 {
  execsql {
    CREATE TABLE t5 (val int, period text PRIMARY KEY);
    INSERT INTO t5 VALUES(5, '2001-3');
    INSERT INTO t5 VALUES(10, '2001-4');
    INSERT INTO t5 VALUES(15, '2002-1');
    INSERT INTO t5 VALUES(5, '2002-2');







|







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    SELECT * FROM (SELECT (SELECT a), b FROM t1);
  }
} {1 3 3 13 5 31 7 57}
do_test subquery-1.10.3 {
  execsql {
    SELECT * FROM (SELECT (SELECT sum(a) FROM t1));
  }
} {16}
do_test subquery-1.10.4 {
  execsql {
    CREATE TABLE t5 (val int, period text PRIMARY KEY);
    INSERT INTO t5 VALUES(5, '2001-3');
    INSERT INTO t5 VALUES(10, '2001-4');
    INSERT INTO t5 VALUES(15, '2002-1');
    INSERT INTO t5 VALUES(5, '2002-2');
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    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.0 2002-3 25.0 2002-4 15.0}
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.0 2002-3 25.0 2002-4 15.0}
do_test subquery-1.10.6 {
  execsql {
    DROP TABLE t5;
  }
} {}









|








|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    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 {
  execsql {
    DROP TABLE t5;
  }
} {}


Changes to test/subselect.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 implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that are part of
# expressions.
#
# $Id: subselect.test,v 1.12 2005/01/21 03:12:16 danielk1977 Exp $

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

# Omit this whole file if the library is build without subquery support.
ifcapable !subquery {
  finish_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 implements regression tests for SQLite library.  The
# focus of this file is testing SELECT statements that are part of
# expressions.
#
# $Id: subselect.test,v 1.13 2005/09/08 10:37:01 drh Exp $

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

# Omit this whole file if the library is build without subquery support.
ifcapable !subquery {
  finish_test
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
} {1 2 3 4 5 6}
} ;# ifcapable !compound

do_test subselect-3.2 {
  execsql {
    SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x LIMIT 2);
  }
} {3.0}
do_test subselect-3.3 {
  execsql {
    SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x DESC LIMIT 2);
  }
} {11.0}
do_test subselect-3.4 {
  execsql {
    SELECT (SELECT x FROM t3 ORDER BY x);
  }
} {1}
do_test subselect-3.5 {
  execsql {







|




|







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
} {1 2 3 4 5 6}
} ;# ifcapable !compound

do_test subselect-3.2 {
  execsql {
    SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x LIMIT 2);
  }
} {3}
do_test subselect-3.3 {
  execsql {
    SELECT sum(x) FROM (SELECT x FROM t3 ORDER BY x DESC LIMIT 2);
  }
} {11}
do_test subselect-3.4 {
  execsql {
    SELECT (SELECT x FROM t3 ORDER BY x);
  }
} {1}
do_test subselect-3.5 {
  execsql {
Changes to test/trigger2.test.
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
        INSERT INTO other_tbl VALUES(3, 4);
        -- INSERT INTO tbl SELECT * FROM other_tbl;
        INSERT INTO tbl VALUES(5, 6);
        DROP TABLE other_tbl;
  
        SELECT * FROM rlog;
      }
    } [list 1 0 0 0.0 0.0 5 6 \
            2 0 0 5.0 6.0 5 6 ]
  
    integrity_check trigger2-1.$ii.4
  }
  catchsql {
    DROP TABLE rlog;
    DROP TABLE clog;
    DROP TABLE tbl;







|
|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
        INSERT INTO other_tbl VALUES(3, 4);
        -- INSERT INTO tbl SELECT * FROM other_tbl;
        INSERT INTO tbl VALUES(5, 6);
        DROP TABLE other_tbl;
  
        SELECT * FROM rlog;
      }
    } [list 1 0 0 0 0 5 6 \
            2 0 0 5 6 5 6 ]
  
    integrity_check trigger2-1.$ii.4
  }
  catchsql {
    DROP TABLE rlog;
    DROP TABLE clog;
    DROP TABLE tbl;
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.35 2005/09/01 17:47:52 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.36 2005/09/08 10:37:02 drh Exp $

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

# Build some test data
#
do_test where-1.0 {
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    CREATE TABLE t3(a,b,c);
    CREATE INDEX t3a ON t3(a);
    CREATE INDEX t3bc ON t3(b,c);
    CREATE INDEX t3acb ON t3(a,c,b);
    INSERT INTO t3 SELECT w, 101-w, y FROM t1;
    SELECT count(*), sum(a), sum(b), sum(c) FROM t3;
  }
} {100 5050.0 5050.0 348550.0}
do_test where-6.2 {
  cksort {
    SELECT * FROM t3 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}
do_test where-6.3 {
  cksort {







|







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    CREATE TABLE t3(a,b,c);
    CREATE INDEX t3a ON t3(a);
    CREATE INDEX t3bc ON t3(b,c);
    CREATE INDEX t3acb ON t3(a,c,b);
    INSERT INTO t3 SELECT w, 101-w, y FROM t1;
    SELECT count(*), sum(a), sum(b), sum(c) FROM t3;
  }
} {100 5050 5050 348550}
do_test where-6.2 {
  cksort {
    SELECT * FROM t3 ORDER BY a LIMIT 3
  }
} {1 100 4 2 99 9 3 98 16 nosort}
do_test where-6.3 {
  cksort {