-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
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
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
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
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
-7b7a69d098f7581a43b818c251717c2450b797de
\ No newline at end of file
+129083bd5e9f8688604a7b7169f15907ec6e332f
\ No newline at end of file
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;
}
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 ){
/* 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;
** 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++){
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;
}
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 ){
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.
*/
/* 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.
}
} {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)
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
#