Compare commits

...

1 Commits

Author SHA1 Message Date
drh 6ed6f260ba Work toward improving analysis and code generation for DISTINCT and
aggregate queries.

FossilOrigin-Name: 129083bd5e9f8688604a7b7169f15907ec6e332f
2016-04-14 19:29:59 +00:00
6 changed files with 45 additions and 32 deletions
+12 -9
View File
@@ -1,5 +1,5 @@
C Add\sthe\sSF_HasAgg\sconstant\s(currently\sunused).\s\sAlso\senhance\sthe\scomments\son\nmany\sother\sconstant\sdefinitions\sto\sdetail\sconstraints\son\stheir\svalues.
D 2016-04-14T16:40:13.322
C Work\stoward\simproving\sanalysis\sand\scode\sgeneration\sfor\sDISTINCT\sand\naggregate\squeries.
D 2016-04-14T19:29:59.500
F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
@@ -373,9 +373,9 @@ F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
F src/resolve.c d3eaf8c20c9b2292fb1d278293c1e4cfe0a9dc87
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
F src/select.c 30217121bdf6b587462150b8ee9e1467f7a6036b
F src/select.c d3ef06f9247f19fd4797f261b489077bd1fde41c
F src/shell.c ebcdf99f3e7c7409bd463eae443f1bd01e3e2d02
F src/sqlite.h.in 64eb70a3b309751bebf73a5552a51244f68f0ea5
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -462,7 +462,7 @@ F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
F test/aggnested.test 116ab8359b88553a0cf20b44e655df9942e5ed41
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
F test/alter.test 2facdddf08d0d48e75dc6cc312cd2b030f4835dd
@@ -1021,7 +1021,7 @@ F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
F test/select1.test e80459748cf40aecffa7cbd28069a73b791c8a2d
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test d926792a5e4d88fef0ddcddeb45d27ce75f7296c
@@ -1482,7 +1482,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 79147dca87cfd7eb62d57baa3b70fa2a8542232a
R 6419c618333708e1ee248e43219e551e
P 7b7a69d098f7581a43b818c251717c2450b797de
R 13f89f53cffc3ab72b6f782d41fa8915
T *branch * better-distinct-agg
T *sym-better-distinct-agg *
T -sym-trunk *
U drh
Z 76d9f185ebd1be8244746d28959cec5d
Z e9a95e98abf36ab9d11354211f2ff8ae
+1 -1
View File
@@ -1 +1 @@
7b7a69d098f7581a43b818c251717c2450b797de
129083bd5e9f8688604a7b7169f15907ec6e332f
+23 -17
View File
@@ -391,12 +391,12 @@ static int lookupName(
for(j=0; j<pEList->nExpr; j++){
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
if( (pNC->ncFlags&NC_AllowAgg)==0
&& ExprHasProperty(pEList->a[j].pExpr, EP_Agg)
){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
@@ -714,11 +714,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr);
}
}
#if 0
/* This error condition will be caught later, during code
** generation */
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++;
is_agg = 0;
}else if( no_such_func && pParse->db->init.busy==0 ){
}else
#endif
if( no_such_func && pParse->db->init.busy==0 ){
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nErr++;
}else if( wrong_num_args ){
@@ -1208,20 +1213,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Resolve names in the result set. */
if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy;
if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
assert( NC_MinMaxAgg==SF_MinMaxAgg );
p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg);
}else{
sNC.ncFlags &= ~NC_AllowAgg;
}
/* If a HAVING clause is present, then there must be a GROUP BY clause.
*/
pGroupBy = p->pGroupBy;
if( p->pHaving && !pGroupBy ){
sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
return WRC_Abort;
@@ -1236,8 +1230,20 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** re-evaluated for each reference to it.
*/
sNC.pEList = p->pEList;
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
assert( NC_MinMaxAgg==SF_MinMaxAgg );
assert( NC_HasAgg==SF_HasAgg );
p->selFlags |= SF_Aggregate | (sNC.ncFlags&(NC_MinMaxAgg|NC_HasAgg));
}else{
sNC.ncFlags &= ~NC_AllowAgg;
}
/* Resolve names in table-valued-function arguments */
for(i=0; i<p->pSrc->nSrc; i++){
+7 -2
View File
@@ -4899,12 +4899,12 @@ int sqlite3Select(
goto select_end;
}
isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
isAggSub = pSub->selFlags & (SF_Aggregate|SF_HasAgg);
if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
/* This subquery can be absorbed into its parent. */
if( isAggSub ){
isAgg = 1;
p->selFlags |= SF_Aggregate;
p->selFlags |= isAggSub;
}
i = -1;
}
@@ -5062,6 +5062,7 @@ int sqlite3Select(
pGroupBy = p->pGroupBy;
pHaving = p->pHaving;
sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
assert( (p->selFlags & SF_HasAgg)==0 || (p->selFlags & SF_Aggregate)!=0 );
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
@@ -5270,6 +5271,9 @@ int sqlite3Select(
sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
/* Not true if there are errors in the input SQL!:
** assert( (sAggInfo.nFunc>0)==((p->selFlags&SF_HasAgg)!=0) ); */
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
*/
@@ -5656,6 +5660,7 @@ int sqlite3Select(
/* The SELECT has been coded. If there is an error in the Parse structure,
** set the return code to 1. Otherwise 0. */
rc = (pParse->nErr>0);
assert( (sAggInfo.nFunc>0)==((p->selFlags&SF_HasAgg)!=0) || rc!=SQLITE_OK );
/* Control jumps to here if an error is encountered above, or upon
** successful coding of the SELECT.
+1 -2
View File
@@ -218,13 +218,12 @@ do_test aggnested-3.14 {
}
} {12 2 34 4}
do_test aggnested-3.15 {
# FIXME: If case 3.16 works, then this case really ought to work too...
catchsql {
SELECT max(value1), (SELECT sum(value2=max(value1)) FROM t2)
FROM t1
GROUP BY id1;
}
} {1 {misuse of aggregate function max()}}
} {0 {12 2 34 4}}
do_test aggnested-3.16 {
db eval {
SELECT max(value1), (SELECT sum(value2=value1) FROM t2)
+1 -1
View File
@@ -223,7 +223,7 @@ do_test select1-2.19 {
do_test select1-2.20 {
set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg]
lappend v $msg
} {1 {misuse of aggregate function min()}}
} {1 {misuse of aggregate: min()}}
# Ticket #2526
#