]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with NULL handling in aggregate min/max when returning output-minmax-row
authordrh <drh@noemail.net>
Thu, 2 Feb 2012 18:42:09 +0000 (18:42 +0000)
committerdrh <drh@noemail.net>
Thu, 2 Feb 2012 18:42:09 +0000 (18:42 +0000)
values from the row containing the min or max.

FossilOrigin-Name: f27c7b4fb193126548e6a620ac89664d1efa3856

manifest
manifest.uuid
src/func.c
test/e_select.test
test/minmax4.test [new file with mode: 0644]

index c28861e94cd8cc292651f8a6016711221714b3cc..200cf03d507c28570a632af7b9bfa9e83b474ea6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C For\squeries\sof\sthe\sform\s"SELECT\sp,\smax(q)\sFROM\st1",\sthe\svalue\sof\scolumn\sp\nreturned\sis\sthe\sone\son\sthe\ssame\srow\sthat\sholds\sthe\smaximum\svalue\sof\sq.
-D 2012-02-02T17:35:43.157
+C Fix\sa\sproblem\swith\sNULL\shandling\sin\saggregate\smin/max\swhen\sreturning\nvalues\sfrom\sthe\srow\scontaining\sthe\smin\sor\smax.
+D 2012-02-02T18:42:09.724
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -137,7 +137,7 @@ F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112
 F src/expr.c 00675123e0beec98f999aa4594d2cbe1fec33c1b
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
-F src/func.c f66c87956c9afc098e1b74612d3c2b38760a41dc
+F src/func.c d7925f33a8ce2207f86dea5cfb1a4379413312fe
 F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
@@ -386,7 +386,7 @@ F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
 F test/e_insert.test 234242b71855af8e8a9b1e141c3533f6d43d8645
 F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
 F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
-F test/e_select.test f0aa7a972a336e5e874700915b1f5abd7d63a7e2
+F test/e_select.test 99202f99a9a3273c6fb0d2e7592b98faeb6c206e
 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
 F test/e_update.test dba988a4d079156549a40854074ba4890b0a4577
 F test/e_uri.test 6f35b491f80dac005c8144f38b2dfb4d96483596
@@ -601,6 +601,7 @@ F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
 F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
 F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
+F test/minmax4.test c1fa9505fd135007fdb1fb699334fb3d4ea7952e
 F test/misc1.test 55cb2bfbf4a8cd61f4be1effc30426ad41696bff
 F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
 F test/misc3.test fe55130a43e444ee75e2156ff75dc96e964b5738
@@ -988,10 +989,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P 0bc594e861ae1142e8c6c83f39b095e1432856bf
-R eff167ee91b10474f283fe35279e92e9
-T *branch * output-minmax-row
-T *sym-output-minmax-row *
-T -sym-trunk *
+P adb29232b659c5332b6841776372407fcc350b08
+R 087241beca277f1bd5ef577cbad5e6e6
 U drh
-Z cf65185cbe7093f978d4a185698ec6ea
+Z d29e9619f6216c8dbc76413eb249e3f2
index e33d5dd10693fbc5bc156ce0b4e610483fb0da2a..1b02240b7ba242dba7cd3a2506151eb277e6b1b1 100644 (file)
@@ -1 +1 @@
-adb29232b659c5332b6841776372407fcc350b08
\ No newline at end of file
+f27c7b4fb193126548e6a620ac89664d1efa3856
\ No newline at end of file
index deddd5375b37eee273f42a60b4ad2c0214ab0246..b7d081068682b2588feb7056a16cdf9004d5d89e 100644 (file)
@@ -1342,11 +1342,12 @@ static void minmaxStep(
   Mem *pBest;
   UNUSED_PARAMETER(NotUsed);
 
-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
   pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
   if( !pBest ) return;
 
-  if( pBest->flags ){
+  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+    if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
+  }else if( pBest->flags ){
     int max;
     int cmp;
     CollSeq *pColl = sqlite3GetFuncCollSeq(context);
@@ -1373,7 +1374,7 @@ static void minMaxFinalize(sqlite3_context *context){
   sqlite3_value *pRes;
   pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
   if( pRes ){
-    if( ALWAYS(pRes->flags) ){
+    if( pRes->flags ){
       sqlite3_result_value(context, pRes);
     }
     sqlite3VdbeMemRelease(pRes);
index 656bbd1b5670b9ee3ed200c4bd976fe6215a6134..103472cd92982e4554de0226e77b604ee1ccd0fb 100644 (file)
@@ -800,7 +800,7 @@ do_select_tests e_select-4.1 {
 
   6  "SELECT count(*), * FROM z1"           {6 63 born -26}
   7  "SELECT max(a), * FROM z1"             {63 63 born -26}
-  8  "SELECT *, min(a) FROM z1"             {{} 67 quartets -5}
+  8  "SELECT *, min(a) FROM z1"             {-5 {} 75 -5}
 
   9  "SELECT *,* FROM z1,z2 LIMIT 1" {        
      51.65 -59.58 belfries {} 21 51.65 -59.58 belfries {} 21
diff --git a/test/minmax4.test b/test/minmax4.test
new file mode 100644 (file)
index 0000000..12f56a8
--- /dev/null
@@ -0,0 +1,145 @@
+# 2012 February 02
+#
+# 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.
+#
+#***********************************************************************
+#
+# Test for queries of the form:  
+#
+#    SELECT p, max(q) FROM t1;
+#
+# Demonstration that the value returned for p is on the same row as 
+# the maximum q.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_test minmax4-1.1 {
+  db eval {
+    CREATE TABLE t1(p,q);
+    SELECT p, max(q) FROM t1;
+  }
+} {{} {}}
+do_test minmax4-1.2 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {{} {}}
+do_test minmax4-1.3 {
+  db eval {
+    INSERT INTO t1 VALUES(1,2);
+    SELECT p, max(q) FROM t1;
+  }
+} {1 2}
+do_test minmax4-1.4 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {1 2}
+do_test minmax4-1.5 {
+  db eval {
+    INSERT INTO t1 VALUES(3,4);
+    SELECT p, max(q) FROM t1;
+  }
+} {3 4}
+do_test minmax4-1.6 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {1 2}
+do_test minmax4-1.7 {
+  db eval {
+    INSERT INTO t1 VALUES(5,0);
+    SELECT p, max(q) FROM t1;
+  }
+} {3 4}
+do_test minmax4-1.8 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {5 0}
+do_test minmax4-1.9 {
+  db eval {
+    INSERT INTO t1 VALUES(6,1);
+    SELECT p, max(q) FROM t1;
+  }
+} {3 4}
+do_test minmax4-1.10 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {5 0}
+do_test minmax4-1.11 {
+  db eval {
+    INSERT INTO t1 VALUES(7,NULL);
+    SELECT p, max(q) FROM t1;
+  }
+} {3 4}
+do_test minmax4-1.12 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {5 0}
+do_test minmax4-1.13 {
+  db eval {
+    DELETE FROM t1 WHERE q IS NOT NULL;
+    SELECT p, max(q) FROM t1;
+  }
+} {7 {}}
+do_test minmax4-1.14 {
+  db eval {
+    SELECT p, min(q) FROM t1;
+  }
+} {7 {}}
+
+do_test minmax4-2.1 {
+  db eval {
+    CREATE TABLE t2(a,b,c);
+    INSERT INTO t2 VALUES
+         (1,null,2),
+         (1,2,3),
+         (1,1,4),
+         (2,3,5);
+    SELECT a, max(b), c FROM t2 GROUP BY a ORDER BY a;
+  }
+} {1 2 3 2 3 5}
+do_test minmax4-2.2 {
+  db eval {
+    SELECT a, min(b), c FROM t2 GROUP BY a ORDER BY a;
+  }
+} {1 1 4 2 3 5}
+do_test minmax4-2.3 {
+  db eval {
+    SELECT a, min(b), avg(b), count(b), c FROM t2 GROUP BY a ORDER BY a DESC;
+  }
+} {2 3 3.0 1 5 1 1 1.5 2 4}
+do_test minmax4-2.4 {
+  db eval {
+    SELECT a, min(b), max(b), c FROM t2 GROUP BY a ORDER BY a;
+  }
+} {1 1 2 3 2 3 3 5}
+do_test minmax4-2.5 {
+  db eval {
+    SELECT a, max(b), min(b), c FROM t2 GROUP BY a ORDER BY a;
+  }
+} {1 2 1 4 2 3 3 5}
+do_test minmax4-2.6 {
+  db eval {
+    SELECT a, max(b), b, max(c), c FROM t2 GROUP BY a ORDER BY a;
+  }
+} {1 2 1 4 4 2 3 3 5 5}
+do_test minmax4-2.7 {
+  db eval {
+    SELECT a, min(b), b, min(c), c FROM t2 GROUP BY a ORDER BY a;
+  }
+} {1 1 {} 2 2 2 3 3 5 5}
+
+
+
+finish_test