/ Check-in [c72b9461]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Integer overflow in SUM causes an exception. Ticket #1669. (CVS 3064)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c72b946198128cbceb12dffbdf4706d9fda0fd72
User & Date: drh 2006-02-09 17:47:42
Context
2006-02-09
18:35
Deprecate the sqlite3_aggregate_count() API. Make sure all aggregate counters are 64 bits. Remove unused StdDev structure from func.c. Ticket #1669. (CVS 3065) check-in: 44bd7ba4 user: drh tags: trunk
17:47
Integer overflow in SUM causes an exception. Ticket #1669. (CVS 3064) check-in: c72b9461 user: drh tags: trunk
16:52
Back out check-in (3058) - it breaks too much application code. (CVS 3063) check-in: 731f1e32 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
845
846
847
848
849
850
851

852
853


854
855

856
857
858
859
860
861
862
** 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.118 2006/02/09 13:38:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
    }
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){

    if( p->seenFloat ){
      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 ){







|







 







>


>
>

<
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
845
846
847
848
849
850
851
852
853
854
855
856
857

858
859
860
861
862
863
864
865
** 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.119 2006/02/09 17:47:42 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
    }
  }
}
static void sumFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    i64 iVal = (i64)p->sum;
    if( p->seenFloat ){
      sqlite3_result_double(context, p->sum);
    }else if( p->sum==(LONGDOUBLE_TYPE)iVal ){
      sqlite3_result_int64(context, iVal);
    }else{

      sqlite3_result_error(context, "integer overflow", -1);
    }
  }
}
static void avgFinalize(sqlite3_context *context){
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
547
548
549
550
551
























552
#    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.45 2006/02/09 13:38:21 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
    INSERT INTO t5 VALUES(0.0);
    SELECT sum(x) FROM t5;
  }
} {9902.0}

# The sum of nothing is NULL.  But the sum of all NULLs is NULL.
#


do_test func-18.3 {
  execsql {
    DELETE FROM t5;
    SELECT sum(x) FROM t5;
  }
} {{}}
do_test func-18.4 {
  execsql {
    INSERT INTO t5 VALUES(NULL);
    SELECT sum(x) FROM t5
  }
} {{}}
do_test func-18.5 {
  execsql {
    INSERT INTO t5 VALUES(NULL);
    SELECT sum(x) FROM t5
  }
} {{}}
do_test func-18.6 {
  execsql {
    INSERT INTO t5 VALUES(123);
    SELECT sum(x) FROM t5
  }
} {123}

# Ticket #1664: 64-bit overflow in sum()
#
do_test func-18.10 {
  execsql {
    CREATE TABLE t6(x INTEGER);
    INSERT INTO t6 VALUES(1);
    INSERT INTO t6 VALUES(1<<62);
    SELECT sum(x) - ((1<<62)+1) from t6;
  }
} 0

























finish_test







|







 







>
>



|

|



|

|



|

|



|

|












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

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
#    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.46 2006/02/09 17:47:42 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
    INSERT INTO t5 VALUES(0.0);
    SELECT sum(x) FROM t5;
  }
} {9902.0}

# The sum of nothing is NULL.  But the sum of all NULLs is NULL.
#
# The TOTAL of nothing is 0.0.
#
do_test func-18.3 {
  execsql {
    DELETE FROM t5;
    SELECT sum(x), total(x) FROM t5;
  }
} {{} 0.0}
do_test func-18.4 {
  execsql {
    INSERT INTO t5 VALUES(NULL);
    SELECT sum(x), total(x) FROM t5
  }
} {{} 0.0}
do_test func-18.5 {
  execsql {
    INSERT INTO t5 VALUES(NULL);
    SELECT sum(x), total(x) FROM t5
  }
} {{} 0.0}
do_test func-18.6 {
  execsql {
    INSERT INTO t5 VALUES(123);
    SELECT sum(x), total(x) FROM t5
  }
} {123 123.0}

# Ticket #1664: 64-bit overflow in sum()
#
do_test func-18.10 {
  execsql {
    CREATE TABLE t6(x INTEGER);
    INSERT INTO t6 VALUES(1);
    INSERT INTO t6 VALUES(1<<62);
    SELECT sum(x) - ((1<<62)+1) from t6;
  }
} 0

# Ticket #1669: If an integer SUM overflows, throw an error, thus
# making the SQL-standard version SUM() even more useless than it
# was before.  
#
# The non-standard TOTAL() function continues to give a helpful result.
#
do_test func-18.11 {
  execsql {
    SELECT typeof(sum(x)) FROM t6
  }
} integer
do_test func-18.12 {
  catchsql {
    INSERT INTO t6 VALUES(1<<62);
    SELECT sum(x) - ((1<<62)*2.0+1) from t6;
  }
} {1 {integer overflow}}
do_test func-18.13 {
  execsql {
    SELECT total(x) - ((1<<62)*2.0+1) FROM t6
  }
} 0.0


finish_test