aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-07-25 15:54:23 +0000
committerdrh <>2022-07-25 15:54:23 +0000
commitee37302095f95b8692d835dc3dec4cbb398d9c3b (patch)
treeda7f2322c7732c92cb670bc49b4e3262fb1fdb1b /src
parent6b6d6c6bd2ca6b1dc19f61216ffe88e5cf734581 (diff)
downloadsqlite-ee37302095f95b8692d835dc3dec4cbb398d9c3b.tar.gz
sqlite-ee37302095f95b8692d835dc3dec4cbb398d9c3b.zip
Allow subqueries on the right-hand side of a LEFT JOIN to be flattened even
if they contain a GROUP BY clause. FossilOrigin-Name: 816da9a893ae97a21463562479edb419a8b511ae731d86eccee3fa6e3e7dc96e
Diffstat (limited to 'src')
-rw-r--r--src/expr.c25
-rw-r--r--src/select.c11
2 files changed, 23 insertions, 13 deletions
diff --git a/src/expr.c b/src/expr.c
index 876b453f1..c9c7c2e76 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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 */
diff --git a/src/select.c b/src/select.c
index 90ba47fa8..672461d44 100644
--- a/src/select.c
+++ b/src/select.c
@@ -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);