-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
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
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
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
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
-14c423075bcebf42a3f4e24838bc865cfb90afda
\ No newline at end of file
+a7f528ff3446d50b280fb0b85063879e3ac5751a
\ No newline at end of file
** 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>
};
/*
-** 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;
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
{ "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 },
}
} {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.
#
# 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} {
</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>