aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2020-06-09 17:45:48 +0000
committerdan <dan@noemail.net>2020-06-09 17:45:48 +0000
commited41a96bc1e3a6eb011330b0a109ae4fc703a14c (patch)
tree42785e67f3f092e33289b83b2eb768c1af9784b0 /src/expr.c
parentcfb8bf6a501ccc5f67b9ae84ad1b6aa40bc1a374 (diff)
downloadsqlite-ed41a96bc1e3a6eb011330b0a109ae4fc703a14c.tar.gz
sqlite-ed41a96bc1e3a6eb011330b0a109ae4fc703a14c.zip
Ensure that aggregate functions that (a) are part of SELECT statements with no FROM clause and (b) have one or more scalar sub-selects as arguments are assigned to the correct aggregate context.
FossilOrigin-Name: 16a41fa8c4c74bba4e908a9c19e6cf5a927cac140e2070c9abf303158be7257b
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/expr.c b/src/expr.c
index 555b2a8d8..87dbe617a 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -5654,11 +5654,26 @@ int sqlite3ExprCoveredByIndex(
*/
struct SrcCount {
SrcList *pSrc; /* One particular FROM clause in a nested query */
+ int iSrcInner; /* Smallest cursor number in this context */
int nThis; /* Number of references to columns in pSrcList */
int nOther; /* Number of references to columns in other FROM clauses */
};
/*
+** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
+** SELECT with a FROM clause encountered during this iteration, set
+** SrcCount.iSrcInner to the cursor number of the leftmost object in
+** the FROM cause.
+*/
+static int selectSrcCount(Walker *pWalker, Select *pSel){
+ struct SrcCount *p = pWalker->u.pSrcCount;
+ if( p->iSrcInner==0x7FFFFFFF && pSel->pSrc && pSel->pSrc->nSrc ){
+ pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
+ }
+ return WRC_Continue;
+}
+
+/*
** Count the number of references to columns.
*/
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
@@ -5678,7 +5693,7 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
}
if( i<nSrc ){
p->nThis++;
- }else if( nSrc==0 || pExpr->iTable<pSrc->a[0].iCursor ){
+ }else if( pExpr->iTable<p->iSrcInner ){
/* In a well-formed parse tree (no name resolution errors),
** TK_COLUMN nodes with smaller Expr.iTable values are in an
** outer context. Those are the only ones to count as "other" */
@@ -5700,9 +5715,10 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
assert( pExpr->op==TK_AGG_FUNCTION );
memset(&w, 0, sizeof(w));
w.xExprCallback = exprSrcCount;
- w.xSelectCallback = sqlite3SelectWalkNoop;
+ w.xSelectCallback = selectSrcCount;
w.u.pSrcCount = &cnt;
cnt.pSrc = pSrcList;
+ cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
cnt.nThis = 0;
cnt.nOther = 0;
sqlite3WalkExprList(&w, pExpr->x.pList);