]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Ensure collation sequences and affinities work in window function queries. Fix for...
authordan <dan@noemail.net>
Mon, 8 Jul 2019 12:01:39 +0000 (12:01 +0000)
committerdan <dan@noemail.net>
Mon, 8 Jul 2019 12:01:39 +0000 (12:01 +0000)
FossilOrigin-Name: 28196d894ac9fad9d8f877c7bf17ec9d299d12acdcc942f9ea0783777b14fdc5

manifest
manifest.uuid
src/select.c
src/window.c
test/window9.test [new file with mode: 0644]

index 667bc8f27648204c59d269c939295281d691f401..605151f8595743c073f5fa8571f1892a9dab6ea7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\svalgrind\sproblem\sin\sfts3corrupt4.test.
-D 2019-07-05T15:16:22.173
+C Ensure\scollation\ssequences\sand\saffinities\swork\sin\swindow\sfunction\squeries.\sFix\sfor\s[9ece23d2].
+D 2019-07-08T12:01:39.675
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -522,7 +522,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 93b7bc7c45efa6322d92293361c51a873690daed50cf77eeff88a448246b0d5a
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c 9187f2c65744e975b191ccee49946732ee922f8bf40da998b322aca1633405ea
+F src/select.c 62f21307b280791c50554c9fa3766758dd695ed66a05d2408d213355c7b0aa89
 F src/shell.c.in 82f8a473c01662f52233c6c75b9bf88d0d2cab276086d5d4ca6f2ff57a3e48eb
 F src/sqlite.h.in 83ebc8ab1a2e82d92214006ea2c15bf8a0604f3fac2c31dd9ce9021f568c71f2
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -612,7 +612,7 @@ F src/where.c 2f11eeb14335b7640f886b2fb441f54a94c35ab5cde8b53461a1074bfd587081
 F src/whereInt.h 1b728f71654ebf8421a1715497a587f02d6f538e819af58dc826908f8577e810
 F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a
 F src/whereexpr.c 5e559bdd24b06e3bc2e68f258bf751302954dc1e432daf71fdd8098a71462326
-F src/window.c 5be2cf7d8763cc97137fc44d015aed8a1a4a56fe9700d7933ed560172617c756
+F src/window.c 3408c0f606574d41033d461506bad68790239844b23e70610738a71152873d05
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1708,6 +1708,7 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761
 F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f
 F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518
 F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f
+F test/window9.test 06495ac733843849b1fca8a79d13ba330d04aba02099703198af2ba7e231f90c
 F test/windowerr.tcl abf4d6d0c6d360213af98ed7d538295d905689e83692106f3ece0e3afb9d7f36
 F test/windowerr.test 675b5e6debfc9370bfacb0b91e2a93a8923512f92600b16f4ea70a1cd9b8e6e4
 F test/windowfault.test 16e906a2c4110c88372ff4bd5de59ac7397ec2f025912eff8e5677eedd126898
@@ -1830,7 +1831,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 acd2df36c2876ff3cc477889fc99f493cdf53a656bdb84bde6121676c9eeed1f
-R 89c994fa71bff5aaeabc661835b668a5
+P cb3dec427e399064eeec31c15565346f045bd7c46d2f7860b1cd346bbcccb124
+R 8abf67c9f7cb3324d11bb2f1aeec506d
 U dan
-Z 2b04774a5a233cfa78160cfe1ff740cc
+Z 9ad0a93a7b03f31ce9406ff65c3f0b05
index 592344de2fa615ce0445f22f15095d85a4d03a5c..418d75eed9af04081a2f97e227ea7516e5c4b5cf 100644 (file)
@@ -1 +1 @@
-cb3dec427e399064eeec31c15565346f045bd7c46d2f7860b1cd346bbcccb124
\ No newline at end of file
+28196d894ac9fad9d8f877c7bf17ec9d299d12acdcc942f9ea0783777b14fdc5
\ No newline at end of file
index bd16acb0279347b1e25a529e976ea19e976981c4..53d33a7ef424b9ec6d4b8798de04b0ec93a48280 100644 (file)
@@ -2096,9 +2096,6 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
   if( pTab==0 ){
     return 0;
   }
-  /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
-  ** is disabled */
-  assert( db->lookaside.bDisable );
   pTab->nTabRef = 1;
   pTab->zName = 0;
   pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
index 737261e85c653405f7627719214900e673d725e2..dcd7107a42bbb39ea3a6c007f9b9bf5555b04042 100644 (file)
@@ -736,6 +736,7 @@ struct WindowRewrite {
   Window *pWin;
   SrcList *pSrc;
   ExprList *pSub;
+  Table *pTab;
   Select *pSubSelect;             /* Current sub-select, if any */
 };
 
@@ -796,6 +797,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
         pExpr->op = TK_COLUMN;
         pExpr->iColumn = p->pSub->nExpr-1;
         pExpr->iTable = p->pWin->iEphCsr;
+        pExpr->y.pTab = p->pTab;
       }
 
       break;
@@ -839,6 +841,7 @@ static void selectWindowRewriteEList(
   Window *pWin,
   SrcList *pSrc,
   ExprList *pEList,               /* Rewrite expressions in this list */
+  Table *pTab,
   ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
 ){
   Walker sWalker;
@@ -850,6 +853,7 @@ static void selectWindowRewriteEList(
   sRewrite.pSub = *ppSub;
   sRewrite.pWin = pWin;
   sRewrite.pSrc = pSrc;
+  sRewrite.pTab = pTab;
 
   sWalker.pParse = pParse;
   sWalker.xExprCallback = selectWindowRewriteExprCb;
@@ -909,11 +913,18 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
     ExprList *pSublist = 0;       /* Expression list for sub-query */
     Window *pMWin = p->pWin;      /* Master window object */
     Window *pWin;                 /* Window object iterator */
+    Table *pTab;
+
+    pTab = sqlite3DbMallocZero(db, sizeof(Table));
+    if( pTab==0 ){
+      return SQLITE_NOMEM;
+    }
 
     p->pSrc = 0;
     p->pWhere = 0;
     p->pGroupBy = 0;
     p->pHaving = 0;
+    p->selFlags &= ~SF_Aggregate;
 
     /* Create the ORDER BY clause for the sub-select. This is the concatenation
     ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
@@ -933,8 +944,8 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
     pMWin->iEphCsr = pParse->nTab++;
     pParse->nTab += 3;
 
-    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
-    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
+    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
+    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
     pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
 
     /* Append the PARTITION BY and ORDER BY expressions to the to the 
@@ -976,16 +987,19 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
     );
     p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
     if( p->pSrc ){
+      Table *pTab2;
       p->pSrc->a[0].pSelect = pSub;
       sqlite3SrcListAssignCursors(pParse, p->pSrc);
-      if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
+      pSub->selFlags |= SF_Expanded;
+      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
+      if( pTab2==0 ){
         rc = SQLITE_NOMEM;
       }else{
-        pSub->selFlags |= SF_Expanded;
-        p->selFlags &= ~SF_Aggregate;
-        sqlite3SelectPrep(pParse, pSub, 0);
+        memcpy(pTab, pTab2, sizeof(Table));
+        pTab->tabFlags |= TF_Ephemeral;
+        p->pSrc->a[0].pTab = pTab;
+        pTab = pTab2;
       }
-
       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
       sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
       sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
@@ -994,6 +1008,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
       sqlite3SelectDelete(db, pSub);
     }
     if( db->mallocFailed ) rc = SQLITE_NOMEM;
+    sqlite3DbFree(db, pTab);
   }
 
   return rc;
diff --git a/test/window9.test b/test/window9.test
new file mode 100644 (file)
index 0000000..5a32a75
--- /dev/null
@@ -0,0 +1,102 @@
+# 2019 June 8
+#
+# 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.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix window9
+
+ifcapable !windowfunc {
+  finish_test
+  return
+}
+
+do_execsql_test 1.0 {
+  CREATE TABLE fruits(
+     name TEXT COLLATE NOCASE,
+     color TEXT COLLATE NOCASE
+  );
+}
+
+do_execsql_test 1.1 {
+  INSERT INTO fruits (name, color) VALUES ('apple', 'RED');
+  INSERT INTO fruits (name, color) VALUES ('APPLE', 'yellow');
+  INSERT INTO fruits (name, color) VALUES ('pear', 'YELLOW');
+  INSERT INTO fruits (name, color) VALUES ('PEAR', 'green');
+}
+
+do_execsql_test 1.2 {
+  SELECT name, color, dense_rank() OVER (ORDER BY name) FROM fruits;
+} {
+  apple RED    1
+  APPLE yellow 1
+  pear  YELLOW 2
+  PEAR  green  2
+}
+
+do_execsql_test 1.3 {
+  SELECT name, color,
+    dense_rank() OVER (PARTITION BY name ORDER BY color)
+  FROM fruits;
+} {
+  apple RED    1 
+  APPLE yellow 2 
+  PEAR green   1 
+  pear YELLOW  2
+}
+
+do_execsql_test 1.4 {
+  SELECT name, color,
+    dense_rank() OVER (ORDER BY name),
+    dense_rank() OVER (PARTITION BY name ORDER BY color)
+  FROM fruits;
+} {
+  apple RED    1 1 
+  APPLE yellow 1 2 
+  PEAR  green  2 1 
+  pear  YELLOW 2 2
+}
+
+do_execsql_test 1.5 {
+  SELECT name, color,
+    dense_rank() OVER (ORDER BY name),
+    dense_rank() OVER (PARTITION BY name ORDER BY color)
+  FROM fruits ORDER BY color;
+} {
+  PEAR  green  2 1 
+  apple RED    1 1 
+  APPLE yellow 1 2 
+  pear  YELLOW 2 2
+}
+
+do_execsql_test 2.0 {
+  CREATE TABLE t1(a BLOB, b INTEGER, c COLLATE nocase);
+  INSERT INTO t1 VALUES(1, 2, 'abc');
+  INSERT INTO t1 VALUES(3, 4, 'ABC');
+}
+
+do_execsql_test 2.1.1 {
+  SELECT c=='Abc' FROM t1
+} {1     1}
+do_execsql_test 2.1.2 {
+  SELECT c=='Abc', rank() OVER (ORDER BY b) FROM t1
+} {1 1   1 2}
+
+do_execsql_test 2.2.1 {
+  SELECT b=='2' FROM t1
+} {1     0}
+do_execsql_test 2.2.2 {
+  SELECT b=='2', rank() OVER (ORDER BY a) FROM t1
+} {1 1   0 2}
+
+finish_test
+