From: dan Date: Mon, 18 Mar 2019 16:51:24 +0000 (+0000) Subject: Fixes for RANGE windows and NULL values. X-Git-Tag: version-3.28.0~88^2~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bdabe742da30a22aff881fc89773cf0ec1eaec60;p=thirdparty%2Fsqlite.git Fixes for RANGE windows and NULL values. FossilOrigin-Name: 723c84be3ec5ae941b7abd2442cdb76ca3bd76a5ce2d830b0e648c6e1424885a --- diff --git a/manifest b/manifest index baeaa3c8ea..d4bad83f6f 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 7e704679d7..4671c64cc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cebe09e11cc91d9776f259dd9b87e9c760a460f53ba6fa36481dfe58f77ad417 \ No newline at end of file +723c84be3ec5ae941b7abd2442cdb76ca3bd76a5ce2d830b0e648c6e1424885a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 00792b1448..095021eb65 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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, diff --git a/src/window.c b/src/window.c index d3088c0c83..28562c8f72 100644 --- a/src/window.c +++ b/src/window.c @@ -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. */ diff --git a/test/pg_common.tcl b/test/pg_common.tcl index 80287c1161..bbc52ebede 100644 --- a/test/pg_common.tcl +++ b/test/pg_common.tcl @@ -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}" diff --git a/test/window8.tcl b/test/window8.tcl index 3cbeea2e8c..d7f9dfd58f 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -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 diff --git a/test/window8.test b/test/window8.test index b1ccddcbf5..a171d1ce0d 100644 --- a/test/window8.test +++ b/test/window8.test @@ -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