mirror of
https://github.com/sqlite/sqlite.git
synced 2025-12-09 10:21:35 +03:00
Do not flatten aggregate subqueries that contain min() or max() functions
so that if the min()/max() are discarded by the outer query, they still function and cause non-aggregate expression to be evaluated on the minimal or maximal row. FossilOrigin-Name: 0bdf1a086b3946722f4d4b328e25917f61c14713
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Adjust\scomments\sto\sshow\sthat\ssubquery\sflattening\srestriction\s(10)\swas\nremoved\sfrom\sthe\scode\sback\sin\s2005.\s\sThis\sis\sa\scomment\schange\sonly.
|
C Do\snot\sflatten\saggregate\ssubqueries\sthat\scontain\smin()\sor\smax()\sfunctions\nso\sthat\sif\sthe\smin()/max()\sare\sdiscarded\sby\sthe\souter\squery,\sthey\sstill\nfunction\sand\scause\snon-aggregate\sexpression\sto\sbe\sevaluated\son\sthe\sminimal\nor\smaximal\srow.
|
||||||
D 2014-09-15T11:14:50.871
|
D 2014-09-15T14:46:02.082
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -183,7 +183,7 @@ F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f
|
|||||||
F src/expr.c 19392d98e089640c3336e65b4254cc337efef7d1
|
F src/expr.c 19392d98e089640c3336e65b4254cc337efef7d1
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
|
F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7
|
||||||
F src/func.c d4d218704b13bc1814b7d76874e405743c903773
|
F src/func.c 5d498933f6168dff80941c873805fe04dc2b766d
|
||||||
F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937
|
F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937
|
||||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||||
@@ -224,14 +224,14 @@ F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f
|
|||||||
F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196
|
F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196
|
||||||
F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2
|
F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2
|
||||||
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
|
||||||
F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb
|
F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89
|
||||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||||
F src/select.c 70312b18bf56f741556ed494c398afa0ca3c0e1a
|
F src/select.c 0cd6706fd52ae5db229e9041094db6ec27195335
|
||||||
F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d
|
F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d
|
||||||
F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6
|
F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||||
F src/sqliteInt.h e9030816d5ee6fe2063553b40359096f994664ee
|
F src/sqliteInt.h 0803e900eb1882f7dd88e86ddcddd2d1b27c8d86
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 218ae2ba022881846741dfc8351aefdf129e0377
|
F src/table.c 218ae2ba022881846741dfc8351aefdf129e0377
|
||||||
@@ -305,7 +305,7 @@ F src/where.c 839b5e1db2507e221ad1c308f148a8519ed750be
|
|||||||
F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c
|
F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
|
||||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||||
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
|
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
|
||||||
F test/alter.test 547dc2d292644301ac9a7dda22b319b74f9c08d2
|
F test/alter.test 547dc2d292644301ac9a7dda22b319b74f9c08d2
|
||||||
@@ -712,7 +712,7 @@ F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
|
|||||||
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
|
||||||
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
|
||||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||||
F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef
|
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
|
||||||
F test/misc1.test 1201a037c24f982cc0e956cdaa34fcaf6439c417
|
F test/misc1.test 1201a037c24f982cc0e956cdaa34fcaf6439c417
|
||||||
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
|
||||||
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
|
||||||
@@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P b332a84d5154f70f3197537df4af243eaebbb011
|
P 4ff0eb96bc364baed2d8005c69291ca9240b99dd
|
||||||
R 4fde0e674c64eada90bf3beabe45d5b4
|
R d83c0c27bf862a8b9f30cb2ccec5fde3
|
||||||
U drh
|
U drh
|
||||||
Z 7e796116236157f7f97effb3ae76fb8a
|
Z 5049f8c8dea35bd8f91ea699f6fd9960
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
4ff0eb96bc364baed2d8005c69291ca9240b99dd
|
0bdf1a086b3946722f4d4b328e25917f61c14713
|
||||||
10
src/func.c
10
src/func.c
@@ -1663,10 +1663,12 @@ void sqlite3RegisterGlobalFunctions(void){
|
|||||||
FUNCTION(trim, 2, 3, 0, trimFunc ),
|
FUNCTION(trim, 2, 3, 0, trimFunc ),
|
||||||
FUNCTION(min, -1, 0, 1, minmaxFunc ),
|
FUNCTION(min, -1, 0, 1, minmaxFunc ),
|
||||||
FUNCTION(min, 0, 0, 1, 0 ),
|
FUNCTION(min, 0, 0, 1, 0 ),
|
||||||
AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ),
|
AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize,
|
||||||
|
SQLITE_FUNC_MINMAX ),
|
||||||
FUNCTION(max, -1, 1, 1, minmaxFunc ),
|
FUNCTION(max, -1, 1, 1, minmaxFunc ),
|
||||||
FUNCTION(max, 0, 1, 1, 0 ),
|
FUNCTION(max, 0, 1, 1, 0 ),
|
||||||
AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
|
AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize,
|
||||||
|
SQLITE_FUNC_MINMAX ),
|
||||||
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
|
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
|
||||||
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
|
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
|
||||||
FUNCTION(instr, 2, 0, 0, instrFunc ),
|
FUNCTION(instr, 2, 0, 0, instrFunc ),
|
||||||
@@ -1719,8 +1721,8 @@ void sqlite3RegisterGlobalFunctions(void){
|
|||||||
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
|
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
|
||||||
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
|
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
|
||||||
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
|
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
|
||||||
/* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
|
AGGREGATE2(count, 0, 0, 0, countStep, countFinalize,
|
||||||
{0,SQLITE_UTF8|SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
|
SQLITE_FUNC_COUNT ),
|
||||||
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
|
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
|
||||||
AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
|
AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
|
||||||
AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
|
AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
|
||||||
|
|||||||
@@ -719,9 +719,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|||||||
pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
|
pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
if( pDef ){
|
|
||||||
auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
|
auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
|
||||||
if( auth!=SQLITE_OK ){
|
if( auth!=SQLITE_OK ){
|
||||||
if( auth==SQLITE_DENY ){
|
if( auth==SQLITE_DENY ){
|
||||||
@@ -732,9 +730,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|||||||
pExpr->op = TK_NULL;
|
pExpr->op = TK_NULL;
|
||||||
return WRC_Prune;
|
return WRC_Prune;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
|
if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
|
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
|
||||||
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
|
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
|
||||||
pNC->nErr++;
|
pNC->nErr++;
|
||||||
@@ -757,7 +755,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
|||||||
pExpr->op2++;
|
pExpr->op2++;
|
||||||
pNC2 = pNC2->pNext;
|
pNC2 = pNC2->pNext;
|
||||||
}
|
}
|
||||||
if( pNC2 ) pNC2->ncFlags |= NC_HasAgg;
|
assert( pDef!=0 );
|
||||||
|
if( pNC2 ){
|
||||||
|
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||||||
|
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||||||
|
pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
|
||||||
|
|
||||||
|
}
|
||||||
pNC->ncFlags |= NC_AllowAgg;
|
pNC->ncFlags |= NC_AllowAgg;
|
||||||
}
|
}
|
||||||
/* FIX ME: Compute pExpr->affinity based on the expected return
|
/* FIX ME: Compute pExpr->affinity based on the expected return
|
||||||
@@ -1222,7 +1226,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
|||||||
assert( (p->selFlags & SF_Aggregate)==0 );
|
assert( (p->selFlags & SF_Aggregate)==0 );
|
||||||
pGroupBy = p->pGroupBy;
|
pGroupBy = p->pGroupBy;
|
||||||
if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
|
if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
|
||||||
p->selFlags |= SF_Aggregate;
|
assert( NC_MinMaxAgg==SF_MinMaxAgg );
|
||||||
|
p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg);
|
||||||
}else{
|
}else{
|
||||||
sNC.ncFlags &= ~NC_AllowAgg;
|
sNC.ncFlags &= ~NC_AllowAgg;
|
||||||
}
|
}
|
||||||
@@ -1350,7 +1355,7 @@ int sqlite3ResolveExprNames(
|
|||||||
NameContext *pNC, /* Namespace to resolve expressions in. */
|
NameContext *pNC, /* Namespace to resolve expressions in. */
|
||||||
Expr *pExpr /* The expression to be analyzed. */
|
Expr *pExpr /* The expression to be analyzed. */
|
||||||
){
|
){
|
||||||
u8 savedHasAgg;
|
u16 savedHasAgg;
|
||||||
Walker w;
|
Walker w;
|
||||||
|
|
||||||
if( pExpr==0 ) return 0;
|
if( pExpr==0 ) return 0;
|
||||||
@@ -1363,8 +1368,8 @@ int sqlite3ResolveExprNames(
|
|||||||
pParse->nHeight += pExpr->nHeight;
|
pParse->nHeight += pExpr->nHeight;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
savedHasAgg = pNC->ncFlags & NC_HasAgg;
|
savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
|
||||||
pNC->ncFlags &= ~NC_HasAgg;
|
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
|
||||||
memset(&w, 0, sizeof(w));
|
memset(&w, 0, sizeof(w));
|
||||||
w.xExprCallback = resolveExprStep;
|
w.xExprCallback = resolveExprStep;
|
||||||
w.xSelectCallback = resolveSelectStep;
|
w.xSelectCallback = resolveSelectStep;
|
||||||
@@ -1379,9 +1384,8 @@ int sqlite3ResolveExprNames(
|
|||||||
}
|
}
|
||||||
if( pNC->ncFlags & NC_HasAgg ){
|
if( pNC->ncFlags & NC_HasAgg ){
|
||||||
ExprSetProperty(pExpr, EP_Agg);
|
ExprSetProperty(pExpr, EP_Agg);
|
||||||
}else if( savedHasAgg ){
|
|
||||||
pNC->ncFlags |= NC_HasAgg;
|
|
||||||
}
|
}
|
||||||
|
pNC->ncFlags |= savedHasAgg;
|
||||||
return ExprHasProperty(pExpr, EP_Error);
|
return ExprHasProperty(pExpr, EP_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
src/select.c
15
src/select.c
@@ -3197,6 +3197,11 @@ static void substSelect(
|
|||||||
** parent to a compound query confuses the code that handles
|
** parent to a compound query confuses the code that handles
|
||||||
** recursive queries in multiSelect().
|
** recursive queries in multiSelect().
|
||||||
**
|
**
|
||||||
|
** (24) The subquery is not an aggregate that uses the built-in min() or
|
||||||
|
** or max() functions. (Without this restriction, a query like:
|
||||||
|
** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
|
||||||
|
** return the value X for which Y was maximal.)
|
||||||
|
**
|
||||||
**
|
**
|
||||||
** In this routine, the "p" parameter is a pointer to the outer query.
|
** In this routine, the "p" parameter is a pointer to the outer query.
|
||||||
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
|
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
|
||||||
@@ -3269,8 +3274,14 @@ static int flattenSubquery(
|
|||||||
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
|
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
|
||||||
return 0; /* Restriction (21) */
|
return 0; /* Restriction (21) */
|
||||||
}
|
}
|
||||||
if( pSub->selFlags & SF_Recursive ) return 0; /* Restriction (22) */
|
testcase( pSub->selFlags & SF_Recursive );
|
||||||
if( (p->selFlags & SF_Recursive) && pSub->pPrior ) return 0; /* (23) */
|
testcase( pSub->selFlags & SF_MinMaxAgg );
|
||||||
|
if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){
|
||||||
|
return 0; /* Restrictions (22) and (24) */
|
||||||
|
}
|
||||||
|
if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
|
||||||
|
return 0; /* Restriction (23) */
|
||||||
|
}
|
||||||
|
|
||||||
/* OBSOLETE COMMENT 1:
|
/* OBSOLETE COMMENT 1:
|
||||||
** Restriction 3: If the subquery is a join, make sure the subquery is
|
** Restriction 3: If the subquery is a join, make sure the subquery is
|
||||||
|
|||||||
@@ -1285,6 +1285,7 @@ struct FuncDestructor {
|
|||||||
#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */
|
#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */
|
||||||
#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */
|
#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */
|
||||||
#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */
|
#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */
|
||||||
|
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
|
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
|
||||||
@@ -1332,6 +1333,9 @@ struct FuncDestructor {
|
|||||||
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
|
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
|
||||||
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
|
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
|
||||||
SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
|
SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
|
||||||
|
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
|
||||||
|
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
|
||||||
|
SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** All current savepoints are stored in a linked list starting at
|
** All current savepoints are stored in a linked list starting at
|
||||||
@@ -2254,17 +2258,22 @@ struct NameContext {
|
|||||||
NameContext *pNext; /* Next outer name context. NULL for outermost */
|
NameContext *pNext; /* Next outer name context. NULL for outermost */
|
||||||
int nRef; /* Number of names resolved by this context */
|
int nRef; /* Number of names resolved by this context */
|
||||||
int nErr; /* Number of errors encountered while resolving names */
|
int nErr; /* Number of errors encountered while resolving names */
|
||||||
u8 ncFlags; /* Zero or more NC_* flags defined below */
|
u16 ncFlags; /* Zero or more NC_* flags defined below */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Allowed values for the NameContext, ncFlags field.
|
** Allowed values for the NameContext, ncFlags field.
|
||||||
|
**
|
||||||
|
** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
|
||||||
|
** SQLITE_FUNC_MINMAX.
|
||||||
|
**
|
||||||
*/
|
*/
|
||||||
#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
|
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
|
||||||
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
|
#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
|
||||||
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
|
#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
|
||||||
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
|
#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */
|
||||||
#define NC_PartIdx 0x10 /* True if resolving a partial index WHERE */
|
#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */
|
||||||
|
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An instance of the following structure contains all information
|
** An instance of the following structure contains all information
|
||||||
@@ -2315,13 +2324,13 @@ struct Select {
|
|||||||
#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
|
#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
|
||||||
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
|
#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
|
||||||
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
|
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
|
||||||
/* 0x0040 NOT USED */
|
#define SF_Compound 0x0040 /* Part of a compound query */
|
||||||
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
|
||||||
/* 0x0100 NOT USED */
|
/* 0x0100 NOT USED */
|
||||||
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
|
||||||
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
|
||||||
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
|
#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
|
||||||
#define SF_Compound 0x1000 /* Part of a compound query */
|
#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -156,8 +156,14 @@ do_test aggnested-3.2 {
|
|||||||
(SELECT value1 as xyz, max(x1) AS pqr
|
(SELECT value1 as xyz, max(x1) AS pqr
|
||||||
FROM t1
|
FROM t1
|
||||||
GROUP BY id1);
|
GROUP BY id1);
|
||||||
|
SELECT
|
||||||
|
(SELECT sum(value2<>xyz) FROM t2)
|
||||||
|
FROM
|
||||||
|
(SELECT value1 as xyz, max(x1) AS pqr
|
||||||
|
FROM t1
|
||||||
|
GROUP BY id1);
|
||||||
}
|
}
|
||||||
} {0}
|
} {1 0}
|
||||||
do_test aggnested-3.3 {
|
do_test aggnested-3.3 {
|
||||||
db eval {
|
db eval {
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1;
|
||||||
|
|||||||
@@ -56,14 +56,16 @@ do_test minmax4-1.5 {
|
|||||||
do_test minmax4-1.6 {
|
do_test minmax4-1.6 {
|
||||||
db eval {
|
db eval {
|
||||||
SELECT p, min(q) FROM t1;
|
SELECT p, min(q) FROM t1;
|
||||||
|
SELECT p FROM (SELECT p, min(q) FROM t1);
|
||||||
}
|
}
|
||||||
} {1 2}
|
} {1 2 1}
|
||||||
do_test minmax4-1.7 {
|
do_test minmax4-1.7 {
|
||||||
db eval {
|
db eval {
|
||||||
INSERT INTO t1 VALUES(5,0);
|
INSERT INTO t1 VALUES(5,0);
|
||||||
SELECT p, max(q) FROM t1;
|
SELECT p, max(q) FROM t1;
|
||||||
|
SELECT p FROM (SELECT max(q), p FROM t1);
|
||||||
}
|
}
|
||||||
} {3 4}
|
} {3 4 3}
|
||||||
do_test minmax4-1.8 {
|
do_test minmax4-1.8 {
|
||||||
db eval {
|
db eval {
|
||||||
SELECT p, min(q) FROM t1;
|
SELECT p, min(q) FROM t1;
|
||||||
@@ -73,8 +75,9 @@ do_test minmax4-1.9 {
|
|||||||
db eval {
|
db eval {
|
||||||
INSERT INTO t1 VALUES(6,1);
|
INSERT INTO t1 VALUES(6,1);
|
||||||
SELECT p, max(q) FROM t1;
|
SELECT p, max(q) FROM t1;
|
||||||
|
SELECT p FROM (SELECT max(q), p FROM t1);
|
||||||
}
|
}
|
||||||
} {3 4}
|
} {3 4 3}
|
||||||
do_test minmax4-1.10 {
|
do_test minmax4-1.10 {
|
||||||
db eval {
|
db eval {
|
||||||
SELECT p, min(q) FROM t1;
|
SELECT p, min(q) FROM t1;
|
||||||
|
|||||||
Reference in New Issue
Block a user