]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When the sqlite3WindowRewrite() routine detects and error, have it convert
authordrh <drh@noemail.net>
Wed, 25 Dec 2019 23:54:21 +0000 (23:54 +0000)
committerdrh <drh@noemail.net>
Wed, 25 Dec 2019 23:54:21 +0000 (23:54 +0000)
the SELECT statement into just "SELECT null" so that it does not leave the
parse tree in a goofy state that can cause problems with subsequent code
before the stack has a chance to unwind and report the error.
Ticket [d87336c81c7d0873]

FossilOrigin-Name: fa58aad48a788802b13a819e49f9b8787f713bbe395c46c7295e821c52c81738

manifest
manifest.uuid
src/expr.c
src/select.c
src/sqliteInt.h
src/window.c
test/window1.test

index 405691aeec120b261519fe4d2dee206ff848a65f..c938290f74835b9ba382ace828520a6bfcf7b502 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sminor\sperformance\sregression\sfrom\scheck-in\s[401c9d30e06191d9]
-D 2019-12-24T21:42:22.593
+C When\sthe\ssqlite3WindowRewrite()\sroutine\sdetects\sand\serror,\shave\sit\sconvert\nthe\sSELECT\sstatement\sinto\sjust\s"SELECT\snull"\sso\sthat\sit\sdoes\snot\sleave\sthe\nparse\stree\sin\sa\sgoofy\sstate\sthat\scan\scause\sproblems\swith\ssubsequent\scode\nbefore\sthe\sstack\shas\sa\schance\sto\sunwind\sand\sreport\sthe\serror.\nTicket\s[d87336c81c7d0873]
+D 2019-12-25T23:54:21.640
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -479,7 +479,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
 F src/dbstat.c 6c407e549406c10fde9ac3987f6d734459205239ad370369bc5fcd683084a4fa
 F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4
-F src/expr.c 518e46716bcf072b41e3e88209965e2495f4c7888f2f698ff00b3e415738912d
+F src/expr.c 3a27de3630d2dec266423505f1ad38484096df4b6d80cf5c90076340d6b2b810
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847
 F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
@@ -527,12 +527,12 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 86a7773d2892227ba9ad1721c41bb03c501830f1bf6de5f78dd0062b82e10c9d
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c b895d809b93596c828c4cd79f4da96d48bf1969414877bb4313770000ea736cc
+F src/select.c 338c1e7e2d88f1ecc47b3f0b1af73522baffe5b6461d86510bec80b70d9eb63f
 F src/shell.c.in 4a3a9e1c11847b1904f2b01d087af1c052f660902755abab457cab1756817ded
 F src/sqlite.h.in 2a23e8161775253d9cf383c2c6aa559005dc787d350dcb0be67a6c4cc3bd1d19
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2
-F src/sqliteInt.h eada1e78b6b950670eb4cc093ce6eb96a7df8bc548cabd7bc6127fa4fbce8ba5
+F src/sqliteInt.h 3e235c7a406630bff9fe7183d9af5d4ce21a9b7acb77bf1b82a0caa130a5f687
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -617,7 +617,7 @@ F src/where.c 58653781a4b31fa16b95b953591fdc1f1ed5ff77574e59b90a27da3819b60a46
 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217
 F src/wherecode.c bb58d5e6e7f583db5b74e0fd35f1d65fdee67d20553b55cd6098fc3f8148053a
 F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396
-F src/window.c da010455914c81037dcb5b0c6f4273f8a32c94567865c46a60060b937b018a96
+F src/window.c a5b69ea3cd22555d390582771173a68c1b798a0847aef3bd9eb51792bc6fcacb
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1713,7 +1713,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
 F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
-F test/window1.test 790c9f12bc4c6f789216fb2c38bd1fbf5e191bed8b9a3712326e4af1a50222c0
+F test/window1.test 7968f1baa13e4f4399a65a21ae9c324a073c28c684adcda2ddf1ea25741d1faa
 F test/window2.tcl 114b217d4ffff891142023cc5f3131b0dae3ad149ac4b45a6ed9e2ad943f8ce2
 F test/window2.test dea2ffecb7182a385143ea0eb368b6241ee43c5f971f4ad1c4337029cb1fc10a
 F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@@ -1852,7 +1852,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 ddb10f0374e66886d0681937b14cf0b4f100f03d3955b45b6c508dc6d9e36976
-R 5b1079c8a384ce37450b3fecba55c04d
+P 76f54ee86777cbf530654323c953388ef64d0608516722d2522be6c859fa1382
+R c46405001dbbf37c4a4da195980c58c5
 U drh
-Z b050346f80259aa216b8caa58ba47eb4
+Z 7b421b0b8aa6e2e1e8fb7d8227a85505
index 7fc9e7916d3eac116531da44d6a6d4518b510e93..0ca15f04c15b108ca290d993aefe59c6d1d3de2a 100644 (file)
@@ -1 +1 @@
-76f54ee86777cbf530654323c953388ef64d0608516722d2522be6c859fa1382
\ No newline at end of file
+fa58aad48a788802b13a819e49f9b8787f713bbe395c46c7295e821c52c81738
\ No newline at end of file
index 601574e68e86776919fecea63ac66ef27396b878..7901608d2d942efe8a11ec9347154965998f4491 100644 (file)
@@ -594,6 +594,7 @@ static void codeVectorCompare(
   int addrDone = sqlite3VdbeMakeLabel(pParse);
   int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
 
+  if( pParse->nErr ) return;
   if( nLeft!=sqlite3ExprVectorSize(pRight) ){
     sqlite3ErrorMsg(pParse, "row value misused");
     return;
@@ -2686,8 +2687,10 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
 **   "sub-select returns N columns - expected M"
 */   
 void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
-  const char *zFmt = "sub-select returns %d columns - expected %d";
-  sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
+  if( pParse->nErr==0 ){
+    const char *zFmt = "sub-select returns %d columns - expected %d";
+    sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
+  }
 }
 #endif
 
index 6fff2883ec04d149a57758f1b8fab7200b041ae4..60744e825a7ff384ae927bb612b56a1f5a025b78 100644 (file)
@@ -84,7 +84,10 @@ struct SortCtx {
 
 /*
 ** Delete all the content of a Select structure.  Deallocate the structure
-** itself only if bFree is true.
+** itself depending on the value of bFree
+**
+** If bFree==1, call sqlite3DbFree() on the p object.
+** If bFree==0, Leave the first Select object unfreed
 */
 static void clearSelect(sqlite3 *db, Select *p, int bFree){
   while( p ){
@@ -188,6 +191,20 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){
   if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
 }
 
+/*
+** Delete all the substructure for p, but keep p allocated.  Redefine
+** p to be a single SELECT where every column of the result set has a
+** value of NULL.
+*/
+void sqlite3SelectReset(Parse *pParse, Select *p){
+  if( ALWAYS(p) ){
+    clearSelect(pParse->db, p, 0);
+    memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit));
+    p->pEList = sqlite3ExprListAppend(pParse, 0,
+                     sqlite3ExprAlloc(pParse->db,TK_NULL,0,0));
+  }
+}
+
 /*
 ** Return a pointer to the right-most SELECT statement in a compound.
 */
@@ -2711,9 +2728,9 @@ static int multiSelect(
         ** it is that we currently need.
         */
         assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
-        if( dest.eDest!=priorOp ){
+        assert( p->pEList || db->mallocFailed );
+        if( dest.eDest!=priorOp && db->mallocFailed==0 ){
           int iCont, iBreak, iStart;
-          assert( p->pEList );
           iBreak = sqlite3VdbeMakeLabel(pParse);
           iCont = sqlite3VdbeMakeLabel(pParse);
           computeLimitRegisters(pParse, p, iBreak);
@@ -5738,7 +5755,9 @@ int sqlite3Select(
   }
 
 #ifndef SQLITE_OMIT_WINDOWFUNC
-  if( sqlite3WindowRewrite(pParse, p) ){
+  rc = sqlite3WindowRewrite(pParse, p);
+  if( rc ){
+    assert( pParse->nErr>0 );
     goto select_end;
   }
 #if SELECTTRACE_ENABLED
index a8cdb9f6adffa67d95916cdd23cad0f632810703..c1ed684ffcbc391b933f6a590d1c5a0f9e4b387c 100644 (file)
@@ -2918,13 +2918,13 @@ struct Upsert {
 ** sequences for the ORDER BY clause.
 */
 struct Select {
-  ExprList *pEList;      /* The fields of the result */
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
   LogEst nSelectRow;     /* Estimated number of result rows */
   u32 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
   u32 selId;             /* Unique identifier number for this SELECT */
   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
+  ExprList *pEList;      /* The fields of the result */
   SrcList *pSrc;         /* The FROM clause */
   Expr *pWhere;          /* The WHERE clause */
   ExprList *pGroupBy;    /* The GROUP BY clause */
@@ -4092,6 +4092,7 @@ int sqlite3Select(Parse*, Select*, SelectDest*);
 Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                          Expr*,ExprList*,u32,Expr*);
 void sqlite3SelectDelete(sqlite3*, Select*);
+void sqlite3SelectReset(Parse*, Select*);
 Table *sqlite3SrcListLookup(Parse*, SrcList*);
 int sqlite3IsReadOnly(Parse*, Table*, int);
 void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
index f4e12f5fdbc9b3ed952a7c9d6ae2e928120aca03..ab8f2c867a25e3aa60545f951ab6ec297c1da191 100644 (file)
@@ -1021,6 +1021,9 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
       pSub->selFlags |= SF_Expanded;
       pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
       if( pTab2==0 ){
+        /* Might actually be some other kind of error, but in that case
+        ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
+        ** the correct error message regardless. */
         rc = SQLITE_NOMEM;
       }else{
         memcpy(pTab, pTab2, sizeof(Table));
@@ -1039,9 +1042,12 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
     sqlite3DbFree(db, pTab);
   }
 
-  if( rc && pParse->nErr==0 ){
-    assert( pParse->db->mallocFailed );
-    return sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
+  if( rc ){
+    if( pParse->nErr==0 ){
+      assert( pParse->db->mallocFailed );
+      sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM);
+    }
+    sqlite3SelectReset(pParse, p);
   }
   return rc;
 }
index fc729354bd39c2ab0d74afc6f3feac059aa752d9..4249a58e83d102490c7fd61722232b4511686634 100644 (file)
@@ -1329,7 +1329,7 @@ do_execsql_test 37.20 {
   SELECT c FROM v0 WHERE c BETWEEN -10 AND 20;
 } {}
 
-# 2019-20-20 mrigger reported problem with a FILTER clause on an aggregate
+# 2019-12-20 mrigger reported problem with a FILTER clause on an aggregate
 # in a join.
 #
 reset_db
@@ -1361,5 +1361,14 @@ do_execsql_test 39.4 {
   SELECT * FROM t0 WHERE (t0.c0, 1) IN(SELECT NTILE(1) OVER(), 0 FROM t0);
 }
 
+# 2019-12-25 ticket d87336c81c7d0873
+#
+reset_db
+do_catchsql_test 40.1 {
+  CREATE VIRTUAL TABLE t0 USING rtree(c0, c1, c2);
+  SELECT * FROM t0
+   WHERE ((0,0) IN (SELECT COUNT(*),LAG(5)OVER(PARTITION BY 0) FROM t0),0)<=(c1,0);
+} {1 {1st ORDER BY term out of range - should be between 1 and 3}}
+
 
 finish_test