]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When omitting result columns for the vector-IN optimization, make sure that group-by-consistency
authordrh <>
Fri, 24 May 2024 20:18:16 +0000 (20:18 +0000)
committerdrh <>
Fri, 24 May 2024 20:18:16 +0000 (20:18 +0000)
any result-set column references in both the ORDER BY clause and the
GROUP BY clause are updated appropriately.

FossilOrigin-Name: f890812df0a57fcd201647640d8b9ee26047cd93cd7171bc6fd050f574649345

manifest
manifest.uuid
src/wherecode.c

index 3a1a676133186cc7e2124a26433e5074c50a62ec..c89949eb99ca6b9f83438650477d0dc2910238b9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sthat\squeries\slike\s"SELECT\sindeterministic(a)\sFROM\stbl\sGROUP\sBY\s1"\sinvoke\sthe\sindeterministic\sfunction\sonly\sonce\sfor\seach\srow\sof\stbl.
-D 2024-05-24T18:31:39.505
+C When\somitting\sresult\scolumns\sfor\sthe\svector-IN\soptimization,\smake\ssure\sthat\nany\sresult-set\scolumn\sreferences\sin\sboth\sthe\sORDER\sBY\sclause\sand\sthe\nGROUP\sBY\sclause\sare\supdated\sappropriately.
+D 2024-05-24T20:18:16.599
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -842,7 +842,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
 F src/where.c 9b2ab23fcc2198ebcee1e6e840a9ff22350668bd3a99195a5dc7299d5908370a
 F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8
-F src/wherecode.c f5255f49d1f42b6e7e6b0362ff3522fa88cbcaa7213e52f9374744027ecdebca
+F src/wherecode.c d5184620bcb5265d59072cb66e1386bfe0331a9ce7614286f9ab79a4fcd00fb8
 F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd
 F src/window.c 5d95122dd330bfaebd732358c8ef067c5a9394a53ac249470d611d0ce2c52be2
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@@ -2193,11 +2193,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 5c97a5b9d163b1c427e002f3734687ca0384bc0da6a90fc4bfd358c654d3a7b3
-R 5fdf8e25d08374c3b6caf60dac9645e5
-T *branch * group-by-consistency
-T *sym-group-by-consistency *
-T -sym-trunk *
-U dan
-Z 5149149f75ab1db4d2d6bfcada9a5ce2
+P 4555d66547e28cb110e1012b145bcf3aafb5d4bde05e9d27bcb4ca33837b28f5
+R 956873244f968f95be3366298765be9b
+U drh
+Z ab0b66dde2c2b53f84c20902891068f4
 # Remove this line to create a well-formed Fossil manifest.
index 2a7f5c0822ede74842dce8d9971a30382ccfafe0..eeb28cef2311b94951d786bfe6f2d0029f56a63c 100644 (file)
@@ -1 +1 @@
-4555d66547e28cb110e1012b145bcf3aafb5d4bde05e9d27bcb4ca33837b28f5
\ No newline at end of file
+f890812df0a57fcd201647640d8b9ee26047cd93cd7171bc6fd050f574649345
\ No newline at end of file
index a620a5ac0653024cd2fa8b7713a10d7d8bd62747..30624be8a28a89aa10f0042201d732df167de0dd 100644 (file)
@@ -460,6 +460,39 @@ static void updateRangeAffinityStr(
   }
 }
 
+/*
+** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because
+** columns might have been rearranged in the result set.  This routine
+** fixes them up.
+**
+** pEList is the new result set.  The pEList->a[].u.x.iOrderByCol values
+** contain the *old* locations of each expression.  This is a temporary
+** use of u.x.iOrderByCol, not its intended use.  The caller must reset
+** u.x.iOrderByCol back to zero for all entries in pEList before the
+** caller returns.
+**
+** This routine changes pOrderBy->a[].u.x.iOrderByCol values from
+** pEList->a[N].u.x.iOrderByCol into N+1.  (The "+1" is because of the 1-based
+** indexing used by iOrderByCol.)  Or if no match, iOrderByCol is set to zero.
+*/
+static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){
+  int i, j;
+  if( pOrderBy==0 ) return;
+  for(i=0; i<pOrderBy->nExpr; i++){
+    int t = pOrderBy->a[i].u.x.iOrderByCol;
+    if( t==0 ) continue;
+    for(j=0; j<pEList->nExpr; j++){
+      if( pEList->a[j].u.x.iOrderByCol==t ){
+        pOrderBy->a[i].u.x.iOrderByCol = j+1;
+        break;
+      }
+    }
+    if( j>=pEList->nExpr ){
+      pOrderBy->a[i].u.x.iOrderByCol = 0;
+    }
+  }
+}
+
 
 /*
 ** pX is an expression of the form:  (vector) IN (SELECT ...)
@@ -522,7 +555,8 @@ static Expr *removeUnindexableInClauseTerms(
           iField = pLoop->aLTerm[i]->u.x.iField - 1;
           if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
           pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
-          pOrigRhs->a[iField].pExpr = 0;
+          pOrigRhs->a[iField].pExpr = 0;       
+          if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1;
           if( pOrigLhs ){
             assert( pOrigLhs->a[iField].pExpr!=0 );
             pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr);
@@ -545,18 +579,16 @@ static Expr *removeUnindexableInClauseTerms(
         sqlite3ExprDelete(db, pNew->pLeft);
         pNew->pLeft = p;
       }
-      if( pSelect->pOrderBy ){
-        /* If the SELECT statement has an ORDER BY clause, zero the
-        ** iOrderByCol variables. These are set to non-zero when an
-        ** ORDER BY term exactly matches one of the terms of the
-        ** result-set. Since the result-set of the SELECT statement may
-        ** have been modified or reordered, these variables are no longer
-        ** set correctly.  Since setting them is just an optimization,
-        ** it's easiest just to zero them here.  */
-        ExprList *pOrderBy = pSelect->pOrderBy;
-        for(i=0; i<pOrderBy->nExpr; i++){
-          pOrderBy->a[i].u.x.iOrderByCol = 0;
-        }
+
+      /* If either the ORDER BY clause or the GROUP BY clause contains
+      ** references to result-set columns, those references might now be
+      ** obsolete.  So fix them up.
+      */
+      assert( pRhs!=0 || db->mallocFailed );
+      if( pRhs ){
+        adjustOrderByCol(pSelect->pOrderBy, pRhs);
+        adjustOrderByCol(pSelect->pGroupBy, pRhs);
+        for(i=0; i<pRhs->nExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0;
       }
 
 #if 0