]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Allow subqueries on the right-hand side of a LEFT JOIN to be flattened even
authordrh <>
Mon, 25 Jul 2022 15:54:23 +0000 (15:54 +0000)
committerdrh <>
Mon, 25 Jul 2022 15:54:23 +0000 (15:54 +0000)
if they contain a GROUP BY clause.

FossilOrigin-Name: 816da9a893ae97a21463562479edb419a8b511ae731d86eccee3fa6e3e7dc96e

manifest
manifest.uuid
src/expr.c
src/select.c

index d040b26a4788ea49c1fdccf794c7c61c3b6cea52..a5d100a7291c1eaaa2519feeb1a628ae68eb153a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C TK_IF_NULL_ROW\sexpressions\smust\sbe\saccumulated\sin\sthe\ssame\sway\sas\sTK_COLUMN\nexpressions\sin\san\saggregate\squery.\s\sProposed\sfix\sfor\sthe\sproblem\sidentifyed\sby\ndbsqlfuzz\s8e17857db2c5a9294c975123ac807156a6559f13.
-D 2022-07-25T14:05:11.599
+C Allow\ssubqueries\son\sthe\sright-hand\sside\sof\sa\sLEFT\sJOIN\sto\sbe\sflattened\seven\nif\sthey\scontain\sa\sGROUP\sBY\sclause.
+D 2022-07-25T15:54:23.818
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -521,7 +521,7 @@ F src/date.c 272162554168e7af4976213850e1c4c5f33b964d299ceb0983f3d5cceba01d05
 F src/dbpage.c 5808e91bc27fa3981b028000f8fadfdc10ce9e59a34ce7dc4e035a69be3906ec
 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
 F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce
-F src/expr.c 72f312252a5791988242dc812df89778f53939e3f60f4e0b432e90f4a3081c1d
+F src/expr.c 61681ff95f4017181b975cdf2790dcbcda6ec962786041286bf5a8b6e051e2ca
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e
 F src/func.c 8f72e88cccdee22185133c10f96ccd61dc34c5ea4b1fa9a73c237ef59b2e64f1
@@ -570,7 +570,7 @@ F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
 F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 45b93eee3c349f46240ddc14344365bbf34579ec332bd4c7bc061945e38172e2
+F src/select.c a9516e1453241986f1eb73c00a0e7cf23d23081fd2eb50e67fcbb96fe7bf6f00
 F src/shell.c.in 29749b34bbd19d0004fdb6f61f62659096e1c0b4dfb1ad2314e7fafbe9dd8d37
 F src/sqlite.h.in be265991edca9aea69986758b58ba81cbf5ae403fe0c4ea1d0c9df0cdc8f25ed
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -1981,11 +1981,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 836fa097060dadeb2dc5d4ee2e40621c4af606b1ef7241e2264823e23e4ceb1f
-R ef7a712abb1795061ef7b33ca931bdb8
-T *branch * flatten-left-join
-T *sym-flatten-left-join *
-T -sym-trunk *
+P 40d08807209638aad728be2cedbc904e342e76c8e486c364bd571b55dd2e1e87
+R 9e57786ca604cfa312cb51673a055fc9
 U drh
-Z 4c1e333b8e885220474e580d77e5a634
+Z fc9a3eeded753547b019835285a3d918
 # Remove this line to create a well-formed Fossil manifest.
index 383392c4343a9c8a0c1665fc7e643a99cfdf0502..790aa223e46a073d520961d3dfb509bf9b33aff6 100644 (file)
@@ -1 +1 @@
-40d08807209638aad728be2cedbc904e342e76c8e486c364bd571b55dd2e1e87
\ No newline at end of file
+816da9a893ae97a21463562479edb419a8b511ae731d86eccee3fa6e3e7dc96e
\ No newline at end of file
index 876b453f1603c835e6d744fc34fcc456a2f5b7c5..c9c7c2e7609a1cfb28026dccc0e7bc79fe18c35e 100644 (file)
@@ -4670,12 +4670,20 @@ expr_code_doover:
     case TK_IF_NULL_ROW: {
       int addrINR;
       u8 okConstFactor = pParse->okConstFactor;
-      if( pExpr->pAggInfo && !pExpr->pAggInfo->directMode ){
-        struct AggInfo_col *pCol;
-        assert( pExpr->iAgg>=0 && pExpr->iAgg<pExpr->pAggInfo->nColumn );
-        pCol = &pExpr->pAggInfo->aCol[pExpr->iAgg];
-        inReg = pCol->iMem;
-        break;
+      AggInfo *pAggInfo = pExpr->pAggInfo;
+      if( pAggInfo ){
+        assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
+        if( !pAggInfo->directMode ){
+          inReg = pAggInfo->aCol[pExpr->iAgg].iMem;
+          break;
+        }
+        if( pExpr->pAggInfo->useSortingIdx ){
+          sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
+                            pAggInfo->aCol[pExpr->iAgg].iSorterColumn,
+                            target);
+          inReg = target;
+          break;
+        }
       }
       addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
       /* Temporarily disable factoring of constant expressions, since
@@ -6187,6 +6195,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
     case TK_COLUMN: {
       testcase( pExpr->op==TK_AGG_COLUMN );
       testcase( pExpr->op==TK_COLUMN );
+      testcase( pExpr->op==TK_IF_NULL_ROW );
       /* Check to see if the column is in one of the tables in the FROM
       ** clause of the aggregate query */
       if( ALWAYS(pSrcList!=0) ){
@@ -6245,7 +6254,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
             */
             ExprSetVVAProperty(pExpr, EP_NoReduce);
             pExpr->pAggInfo = pAggInfo;
-            if( pExpr->op==TK_COLUMN ) pExpr->op = TK_AGG_COLUMN;
+            if( pExpr->op==TK_COLUMN ){
+              pExpr->op = TK_AGG_COLUMN;
+            }
             pExpr->iAgg = (i16)k;
             break;
           } /* endif pExpr->iTable==pItem->iCursor */
index 90ba47fa8ae408f4b89a9fc948a3bec453d58069..672461d4471a78e963495af2a533aa1d755f1de9 100644 (file)
@@ -4065,8 +4065,8 @@ static void renumberCursors(
 **        (3a) the subquery may not be a join and
 **        (3b) the FROM clause of the subquery may not contain a virtual
 **             table and
-**        (3c) The outer query may not have a GROUP BY.  (This limitation is
-**             due to how TK_IF_NULL_ROW works.  FIX ME!)
+**        (**) Was: "The outer query may not have a GROUP BY." This case
+**             is now managed correctly
 **        (3d) the outer query may not be DISTINCT.
 **        See also (26) for restrictions on RIGHT JOIN.
 **
@@ -4284,7 +4284,6 @@ static int flattenSubquery(
     if( pSubSrc->nSrc>1                        /* (3a) */
      || IsVirtual(pSubSrc->a[0].pTab)          /* (3b) */
      || (p->selFlags & SF_Distinct)!=0         /* (3d) */
-     || (p->pGroupBy!=0)                       /* (3c) */
      || (pSubitem->fg.jointype & JT_RIGHT)!=0  /* (26) */
     ){
       return 0;
@@ -7541,15 +7540,15 @@ int sqlite3Select(
         regBase = sqlite3GetTempRange(pParse, nCol);
         sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
         j = nGroupBy;
+        pAggInfo->directMode = 1;
         for(i=0; i<pAggInfo->nColumn; i++){
           struct AggInfo_col *pCol = &pAggInfo->aCol[i];
           if( pCol->iSorterColumn>=j ){
-            int r1 = j + regBase;
-            sqlite3ExprCodeGetColumnOfTable(v,
-                               pCol->pTab, pCol->iTable, pCol->iColumn, r1);
+            sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase);
             j++;
           }
         }
+        pAggInfo->directMode = 0;
         regRecord = sqlite3GetTempReg(pParse);
         sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
         sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);