]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add support for the TOTAL() aggregate function - works like SUM() except
authordrh <drh@noemail.net>
Thu, 12 Jan 2006 22:17:50 +0000 (22:17 +0000)
committerdrh <drh@noemail.net>
Thu, 12 Jan 2006 22:17:50 +0000 (22:17 +0000)
that it returns 0 instead of NULL when presented with an empty list. (CVS 2930)

FossilOrigin-Name: a7f528ff3446d50b280fb0b85063879e3ac5751a

manifest
manifest.uuid
src/func.c
test/null.test
www/lang.tcl

index f79e868ab65630f7c08986a0c44d768eaa6ab537..af3e0ac7bb2557df7a1f0de94141ba76d78d3717 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Performance\sboost\sin\ssqlite3VdbeRecordCompare.\s(CVS\s2929)
-D 2006-01-12T20:28:35
+C Add\ssupport\sfor\sthe\sTOTAL()\saggregate\sfunction\s-\sworks\slike\sSUM()\sexcept\nthat\sit\sreturns\s0\sinstead\sof\sNULL\swhen\spresented\swith\san\sempty\slist.\s(CVS\s2930)
+D 2006-01-12T22:17:50
 F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -43,7 +43,7 @@ F src/date.c a927bdbb51296ac398d2f667086a7072c099e5ab
 F src/delete.c c7bd5708a629585e073ce34cf3b1fcb52c2fef38
 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
 F src/expr.c 3b6acdb4e254027fe72ce70054ea6b71c7d423a3
-F src/func.c e013c3b6c607c6a1654f5260eab59f5609a5ce4a
+F src/func.c be4c026c1d2401f14c3186611e1131a895a3ca6e
 F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 F src/insert.c a5595cf8d1d8ba087b676a63f1f7277ea44b5ac1
@@ -202,7 +202,7 @@ F test/misc4.test b043a05dea037cca5989f3ae09552fa16119bc80
 F test/misc5.test a27520a0033f2837cda94bfdfb096a25fc4b128d
 F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
-F test/null.test 012fe5455f4fc3102490b4bad373a674e5741fdd
+F test/null.test db52272f9628ae9e77ab451cf0fb3871a98c5f00
 F test/pager.test 1579e8f07291ae8e24db62ffade5c101c3e76597
 F test/pager2.test 49c0f57c7da0b060f0486b85fdd074025caa694e
 F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
@@ -319,7 +319,7 @@ F www/fullscanb.gif f7c94cb227f060511f8909e10f570157263e9a25
 F www/index-ex1-x-b.gif f9b1d85c3fa2435cf38b15970c7e3aa1edae23a3
 F www/index.tcl f84bf390bd272035934639748c89730f3d60dc44
 F www/indirect1b1.gif adfca361d2df59e34f9c5cac52a670c2bfc303a1
-F www/lang.tcl 6f81b2726dc350ba5dc0dd6dcddb9e7a307b9976
+F www/lang.tcl b3561af8d85d2d712d43b3604e4aadce9257e4d9
 F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f
 F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
 F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
@@ -340,7 +340,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 730ddb0b74ed23c916dabd7ce893bd6bc55f3549
-R 36b85235284a365ef7c4f8a7c8bf02e6
+P 14c423075bcebf42a3f4e24838bc865cfb90afda
+R 96aa9577c2fe78f0881f3a139cc6dc0c
 U drh
-Z 308f9bd267f3ff57a7f1fa05f779432c
+Z 680a9cdd5661322ac6544d3998d3b8d1
index 99f52e187d8bfe703cb0ea2ebd4bab49e23fe885..4034ef219e180694b044b7adaf4b10e5c9bfb328 100644 (file)
@@ -1 +1 @@
-14c423075bcebf42a3f4e24838bc865cfb90afda
\ No newline at end of file
+a7f528ff3446d50b280fb0b85063879e3ac5751a
\ No newline at end of file
index 7c16f70bebd3760bc796544d168e9c23a60a0db0..4198d61005f6781c2ed71d755a65f66b17c3b041 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.115 2006/01/09 16:12:05 danielk1977 Exp $
+** $Id: func.c,v 1.116 2006/01/12 22:17:50 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -823,7 +823,13 @@ struct SumCtx {
 };
 
 /*
-** Routines used to compute the sum or average.
+** Routines used to compute the sum, average, and total.
+**
+** The SUM() function follows the (broken) SQL standard which means
+** that it returns NULL if it sums over no inputs.  TOTAL returns
+** 0.0 in that case.  In addition, TOTAL always returns a float where
+** SUM might return an integer if it never encounters a floating point
+** value.
 */
 static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
   SumCtx *p;
@@ -857,6 +863,11 @@ static void avgFinalize(sqlite3_context *context){
     sqlite3_result_double(context, p->sum/(double)p->cnt);
   }
 }
+static void totalFinalize(sqlite3_context *context){
+  SumCtx *p;
+  p = sqlite3_aggregate_context(context, 0);
+  sqlite3_result_double(context, p ? p->sum : 0.0);
+}
 
 /*
 ** An instance of the following structure holds the context of a
@@ -1000,6 +1011,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
     { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
     { "sum",    1, 0, 0, sumStep,      sumFinalize    },
+    { "total",  1, 0, 0, sumStep,      totalFinalize    },
     { "avg",    1, 0, 0, sumStep,      avgFinalize    },
     { "count",  0, 0, 0, countStep,    countFinalize  },
     { "count",  1, 0, 0, countStep,    countFinalize  },
index ba9c6f88e0a2433139a0d8f49297c6d652c65130..8d401f651986e8dc78055788a864febe5aa7da7d 100644 (file)
@@ -102,6 +102,14 @@ do_test null-3.1 {
   }
 } {7 4 6 2 3 0.5 0.5 0 1}
 
+# The sum of zero entries is a NULL, but the total of zero entries is 0.
+#
+do_test null-3.2 {
+  execsql {
+    SELECT sum(b), total(b) FROM t1 WHERE b<0
+  }
+} {{} 0.0}
+
 # 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.
index 0fe77cd5589073f8c012a795d3604e25be9e8e1c..b937cbd27742402692153a2ebab3a5fd4c299ec5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the lang-*.html files.
 #
-set rcsid {$Id: lang.tcl,v 1.104 2006/01/04 15:58:29 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.105 2006/01/12 22:17:50 drh Exp $}
 source common.tcl
 
 if {[llength $argv]>0} {
@@ -1395,15 +1395,15 @@ if all values in the group are NULL.</td>
 </tr>
 
 <tr>
-<td valign="top" align="right">sum(<i>X</i>)</td>
+<td valign="top" align="right">sum(<i>X</i>)<br>total(<i>X</i>)</td>
 <td valign="top">Return the numeric sum of all numeric values in the group.
-   If there are no input rows or all values are NULL, then NULL is returned.
+   If there are no input rows or all values are NULL, then sum() returns
+   NULL but total() returns zero.
    NULL is not a helpful result in that case (the correct answer should be
-   zero) but it is what the SQL standard requires and how 
-   most other SQL database engines operate so SQLite does it that way
-   in order to be compatible. 
-   You will probably want to use
-   "<b>coalesce(sum(</b>X<b>),0)</b>" instead of just "<b>sum(</b>X<b>)</b>"
+   zero) but the SQL standard requires that behavior from sum() and that is how 
+   most other SQL database engines implement sum() so SQLite does it that way
+   in order to be compatible.   The non-standard total() function is provided
+   as a convenient way
    to work around this design problem in the SQL language.</td>
 </tr>
 </table>