]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fixes for RANGE windows and NULL values.
authordan <dan@noemail.net>
Mon, 18 Mar 2019 16:51:24 +0000 (16:51 +0000)
committerdan <dan@noemail.net>
Mon, 18 Mar 2019 16:51:24 +0000 (16:51 +0000)
FossilOrigin-Name: 723c84be3ec5ae941b7abd2442cdb76ca3bd76a5ce2d830b0e648c6e1424885a

manifest
manifest.uuid
src/vdbe.c
src/window.c
test/pg_common.tcl
test/window8.tcl
test/window8.test

index baeaa3c8ea06a07b5947f5adffbf78ef4f8cd232..d4bad83f6f6082a85303a682eff2be390ca79bf3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sproblems\swith\sRANGE\swindows\sand\sstring,\sblob\sand\sNULL\svalues.
-D 2019-03-16T20:29:54.997
+C Fixes\sfor\sRANGE\swindows\sand\sNULL\svalues.
+D 2019-03-18T16:51:24.785
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 236d2739dc3e823c3c909bca2d6cef93009bafbefd7018a8f3281074ecb92954
@@ -586,7 +586,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c 82a2e3f691a3b654be872e305dab1f455e565dedf5e6a90c818c1ab307c00432
 F src/vacuum.c a9f389f41556c0ec310bc9169dc9476603c30a0a913ad92bfbc75c86886967ca
-F src/vdbe.c ec26b53c0c0a1de89c97410ac0bc22da789d45dc694e4dd49cd7cae12d8c0111
+F src/vdbe.c 1bad4337cb9931338f77b2375a894e8d61e8482c9843af9c8d2e988c34786203
 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237
 F src/vdbeInt.h a76d5eed62c76bcd8de7afd3147fac1bc40c5a870582664bcd7d071ef437c37f
 F src/vdbeapi.c 7a052df80d7e2e55382076174633e888f21fe200feb5d49b1b441b4c38ab851a
@@ -604,7 +604,7 @@ F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799
 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88
 F src/wherecode.c ce7b21e1be2b981d62683fc59c4ca73a04a7ff2f1ebec23d41baf2da2349afd6
 F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c
-F src/window.c 3c13b17c47f85ccc2051c123345c7056c168a5ab1e6d237e8d1c59fb4f085470
+F src/window.c aa50be1fc05d03c89b64954529c8041f47cfb09e3f56f7e3f636f2f3a405e002
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1197,7 +1197,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
 F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
 F test/permutations.test 52d2c37fe8cc07ec7362024c214b04bb69432995b3a984a3fbabc60fa6ada3ee
-F test/pg_common.tcl 85fac868078d6d71357642910663aaf95f2cf90b78c9817bcee311fe107f0608
+F test/pg_common.tcl 4740dc35190d6acdab14c097783331361301ab504a94d948f6afbb56ce0a51e8
 F test/pragma.test c267bf02742c823a191960895b3d52933cebd7beee26757d1ed694f213fcd867
 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
 F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
@@ -1687,8 +1687,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652
 F test/window6.test 604890f2b0f976339e6a1774cd90d48840e57a54b4f21a8b4b3047aa2c9787d1
 F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
 F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f
-F test/window8.tcl 3f973e4007cade9e1700434220505bf1ada7f0f13edb1803322cb78069bda7d7
-F test/window8.test 118243072b074d76400b4f528322a2d79a36e02e114da95ebba6610785cd10f2
+F test/window8.tcl 9755f960fb3197e741b393e00841bb9374a5d5058f12b2d056213bfb53877b07
+F test/window8.test daacb65e98c21a614bed6cf55f0bb73146e0abac99916b3ed25041aa84911767
 F test/windowerr.tcl 4f0b111cdbb8de401a8135cd116604fb8add13042bb47a1f1496dd47a690e864
 F test/windowerr.test 461bc504d4af0ae16a081e0c3bdb3724356cdcfb07bdc4b1b2dc4ad91b69bb7e
 F test/windowfault.test 12ceb6bbb355d13e8fcd88c5731a57256dfdf77b9a7ae20842a76fcd4623df5b
@@ -1812,7 +1812,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P f2d5f7a24c7aa483c579706c5bd7268a74da6d53025d78fa8642908c2aed1707
-R 1f818016fedca9daa5b8ba9c8e0b3de6
+P cebe09e11cc91d9776f259dd9b87e9c760a460f53ba6fa36481dfe58f77ad417
+R 8d2c171861aade8c47279f8542c6aefc
 U dan
-Z 3e69c8f976def5bbb22a7214f3463083
+Z b15d3ba2de246cd1586a8b207d7ccea2
index 7e704679d7879c7421b6d31250b1f5a41256eef5..4671c64cc68f4d889822d2ea01008e45e98715ee 100644 (file)
@@ -1 +1 @@
-cebe09e11cc91d9776f259dd9b87e9c760a460f53ba6fa36481dfe58f77ad417
\ No newline at end of file
+723c84be3ec5ae941b7abd2442cdb76ca3bd76a5ce2d830b0e648c6e1424885a
\ No newline at end of file
index 00792b144848f10762131371e55fe6071582d8a6..095021eb65dc7a7f7eb25b67a3e2782b5c5fc5ff 100644 (file)
@@ -1924,7 +1924,6 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
       ** OP_Eq or OP_Ne) then take the jump or not depending on whether
       ** or not both operands are null.
       */
-      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
       assert( (flags1 & MEM_Cleared)==0 );
       assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
       testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
@@ -1933,7 +1932,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
       ){
         res = 0;  /* Operands are equal */
       }else{
-        res = 1;  /* Operands are not equal */
+        res = ((flags3 & MEM_Null) ? -1 : +1);  /* Operands are not equal */
       }
     }else{
       /* SQLITE_NULLEQ is clear and at least one operand is NULL,
index d3088c0c83890f295055ae33b6e5d871010958ac..28562c8f72b1ac49111f9fde9b733db11bfd1df7 100644 (file)
@@ -1783,21 +1783,14 @@ static void windowCodeRangeTest(
   windowReadPeerValues(p, csr2, reg2);
 
   /* Check if the peer value for csr1 value is a text or blob by comparing
-  ** it to the smallest possible string - ''. */
+  ** it to the smallest possible string - ''. If it is, jump over the
+  ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
   sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
   addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
-
-  if( op==OP_Le ){
-    sqlite3VdbeAddOp2(v, OP_IsNull, reg1, lbl);
-  }
-  if( op==OP_Ge ){
-    sqlite3VdbeAddOp2(v, OP_NotNull, reg1, sqlite3VdbeCurrentAddr(v)+2);
-    sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl);
-  }
-
   sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
   sqlite3VdbeJumpHere(v, addrGe);
   sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1);
+  sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
 
   sqlite3ReleaseTempReg(pParse, reg1);
   sqlite3ReleaseTempReg(pParse, reg2);
@@ -2367,13 +2360,15 @@ void sqlite3WindowCodeStep(
   ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
   switch( pMWin->eStart ){
     case TK_FOLLOWING: {
-      sqlite3 *db = pParse->db;
-      sqlite3_value *pVal = 0;
-      sqlite3ValueFromExpr(db, pMWin->pStart, db->enc,SQLITE_AFF_NUMERIC,&pVal);
-      if( pVal && sqlite3_value_int(pVal)>0 ){
-        s.eDelete = WINDOW_RETURN_ROW;
+      if( pMWin->eType!=TK_RANGE ){
+        sqlite3 *db = pParse->db;
+        sqlite3_value *pVal = 0;
+        sqlite3ValueFromExpr(db,pMWin->pStart,db->enc,SQLITE_AFF_NUMERIC,&pVal);
+        if( pVal && sqlite3_value_int(pVal)>0 ){
+          s.eDelete = WINDOW_RETURN_ROW;
+        }
+        sqlite3ValueFree(pVal);
       }
-      sqlite3ValueFree(pVal);
       break;
     }
     case TK_UNBOUNDED:
@@ -2390,6 +2385,8 @@ void sqlite3WindowCodeStep(
       break;
   }
 
+  s.eDelete = 0;
+
   /* Allocate registers for the array of values from the sub-query, the
   ** samve values in record form, and the rowid used to insert said record
   ** into the ephemeral table.  */
index 80287c1161eaa708ecbd47b806dc41555ba38e91..bbc52ebede5a5b090ea94e9069b65166bd3f134a 100644 (file)
@@ -70,6 +70,8 @@ proc execsql {sql} {
 proc execsql_test {tn sql} {
   set res [execsql $sql]
   set sql [string map {string_agg group_concat} $sql]
+  set sql [string map [list {NULLS FIRST} {}] $sql]
+  set sql [string map [list {NULLS LAST} {}] $sql]
   puts $::fd "do_execsql_test $tn {"
   puts $::fd "  [string trim $sql]"
   puts $::fd "} {$res}"
index 3cbeea2e8c69955593506b36400031d6b3f10f0a..d7f9dfd58fda2a4ba73479f32a3cca6deaa0fec7 100644 (file)
@@ -171,12 +171,46 @@ execsql_test 4.0 {
     (NULL, 1), (NULL, 2), (NULL, 3), (10, 4), (10, 5);
 }
 
-execsql_test 4.1 {
+execsql_test 4.1.1 {
   SELECT sum(b) OVER (
     ORDER BY a RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
   ) FROM t1 ORDER BY 1;
 }
+execsql_test 4.1.2 {
+  SELECT sum(b) OVER (
+    ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1;
+}
+
+execsql_test 4.2.1 {
+  SELECT sum(b) OVER (
+    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.2.2 {
+  SELECT sum(b) OVER (
+    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
 
+execsql_test 4.3.1 {
+  SELECT sum(b) OVER (
+    ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.4.1 {
+  SELECT sum(b) OVER (
+    ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+  ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.4.2 {
+  SELECT sum(b) OVER (
+    ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+  ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
 finish_test
 
 
index b1ccddcbf5234e04453decd2653f5d3c89ecbbc8..a171d1ce0d78768ba3867256221f627ee79c97a6 100644 (file)
@@ -2622,10 +2622,46 @@ do_execsql_test 4.0 {
     (NULL, 1), (NULL, 2), (NULL, 3), (10, 4), (10, 5);
 } {}
 
-do_execsql_test 4.1 {
+do_execsql_test 4.1.1 {
   SELECT sum(b) OVER (
     ORDER BY a RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
   ) FROM t1 ORDER BY 1;
 } {6   6   6   9   9}
 
+do_execsql_test 4.1.2 {
+  SELECT sum(b) OVER (
+    ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1;
+} {6   6   6   9   9}
+
+do_execsql_test 4.2.1 {
+  SELECT sum(b) OVER (
+    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1 ;
+} {{}   {}   6   6   6}
+
+do_execsql_test 4.2.2 {
+  SELECT sum(b) OVER (
+    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1 ;
+} {{}   {}   6   6   6}
+
+do_execsql_test 4.3.1 {
+  SELECT sum(b) OVER (
+    ORDER BY a  RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
+  ) FROM t1 ORDER BY 1 ;
+} {6   6   6   15   15}
+
+do_execsql_test 4.4.1 {
+  SELECT sum(b) OVER (
+    ORDER BY a  ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+  ) FROM t1 ORDER BY 1 ;
+} {3   6   9   9   12}
+
+do_execsql_test 4.4.2 {
+  SELECT sum(b) OVER (
+    ORDER BY a DESC  ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+  ) FROM t1 ORDER BY 1 ;
+} {5   6   8   9   10}
+
 finish_test