diff --git a/Makefile.in b/Makefile.in index 1d4dd98892..4125f22e4f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -243,12 +243,12 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h # files are automatically generated. This target takes care of # all that automatic generation. # -target_source: $(SRC) parse.c opcodes.c keywordhash.c $(VDBEHDR) +target_source: $(SRC) parse.c opcodes.c keywordhash.h $(VDBEHDR) rm -rf tsrc mkdir -p tsrc cp $(SRC) $(VDBEHDR) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - cp parse.c opcodes.c keywordhash.c tsrc + cp parse.c opcodes.c keywordhash.h tsrc cp $(TOP)/sqlite3.def tsrc # Rules to build the LEMON compiler generator @@ -363,12 +363,12 @@ table.lo: $(TOP)/src/table.c $(HDR) tclsqlite.lo: $(TOP)/src/tclsqlite.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/tclsqlite.c -tokenize.lo: $(TOP)/src/tokenize.c keywordhash.c $(HDR) +tokenize.lo: $(TOP)/src/tokenize.c keywordhash.h $(HDR) $(LTCOMPILE) -c $(TOP)/src/tokenize.c -keywordhash.c: $(TOP)/tool/mkkeywordhash.c +keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash$(BEXE) $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash$(BEXE) >keywordhash.c + ./mkkeywordhash$(BEXE) >keywordhash.h trigger.lo: $(TOP)/src/trigger.c $(HDR) $(LTCOMPILE) -c $(TOP)/src/trigger.c @@ -621,7 +621,7 @@ clean: rm -f sqlite3.h opcodes.* rm -rf .libs .deps rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz - rm -f mkkeywordhash$(BEXE) keywordhash.c + rm -f mkkeywordhash$(BEXE) keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -f testfixture$(TEXE) test.db diff --git a/main.mk b/main.mk index 6aaa959b4b..0d2f4bd579 100644 --- a/main.mk +++ b/main.mk @@ -180,12 +180,12 @@ objects: $(LIBOBJ_ORIG) # files are automatically generated. This target takes care of # all that automatic generation. # -target_source: $(SRC) $(VDBEHDR) opcodes.c keywordhash.c +target_source: $(SRC) $(VDBEHDR) opcodes.c keywordhash.h rm -rf tsrc mkdir tsrc cp $(SRC) $(VDBEHDR) tsrc rm tsrc/sqlite.h.in tsrc/parse.y - cp parse.c opcodes.c keywordhash.c tsrc + cp parse.c opcodes.c keywordhash.h tsrc cp $(TOP)/sqlite3.def tsrc # Rules to build the LEMON compiler generator @@ -301,12 +301,12 @@ table.o: $(TOP)/src/table.c $(HDR) tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR) $(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c -tokenize.o: $(TOP)/src/tokenize.c keywordhash.c $(HDR) +tokenize.o: $(TOP)/src/tokenize.c keywordhash.h $(HDR) $(TCCX) -c $(TOP)/src/tokenize.c -keywordhash.c: $(TOP)/tool/mkkeywordhash.c +keywordhash.h: $(TOP)/tool/mkkeywordhash.c $(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c - ./mkkeywordhash >keywordhash.c + ./mkkeywordhash >keywordhash.h trigger.o: $(TOP)/src/trigger.c $(HDR) $(TCCX) -c $(TOP)/src/trigger.c @@ -542,7 +542,7 @@ install: sqlite3 libsqlite3.a sqlite3.h clean: rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* - rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.c + rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -rf tsrc diff --git a/manifest b/manifest index 59180f7b34..96fce36a74 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Infrastructure\schanges\sto\shandle\sname\sresolution\sdifferently.\s\sThis\sis\sneeded\nto\sfix\svarious\slong-standing\sproblems\swith\scolumn\snames\sin\sjoins.\s\sIt\swill\nalso\smake\sthe\simplementation\sof\scorrelated\ssubqueries\seasier.\s(CVS\s2228) -D 2005-01-17T22:08:19 -F Makefile.in 78d6d0af3725aef32468ac9923444d7645d21a28 +C Refinements\sto\sthe\sname\sresolution\slogic.\s\sChange\sthe\sname\sof\sthe\nkeywordhash.c\sfile\sto\skeywordhash.h.\s(CVS\s2229) +D 2005-01-18T04:00:43 +F Makefile.in ffd81f5e926d40b457071b4de8d7c1fa18f39b5a F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 F VERSION 342b6d5fde93b6d45023e2fee0163dda6464b9d6 @@ -16,7 +16,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826 -F main.mk 839f7bc12221a02bcee10aa0fc72841d893e9b16 +F main.mk 612a0bdbc23797754186ea366ff54512081d17fb F mkdll.sh 468d4f41d3ea98221371df4825cfbffbaac4d7e4 F mkopcodec.awk 141aede6e58634f9cf9e96205a5316680e649987 F mkopcodeh.awk ee454cdee1da38b485c5e8cca84e5727c07158ba @@ -31,15 +31,15 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689 F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea F src/btree.c 97101cce85304edbaedafc5f39ab12e2dc78b076 F src/btree.h 74d19cf40ab49fd69abe9e4e12a6c321ad86c497 -F src/build.c 4638b87f5e797e364ff995f8338b281b61dd8be1 +F src/build.c 4b7a2c308973df3ec26ceda6e3dadc07eecf031b F src/cursor.c f883813759742068890b1f699335872bfa8fdf41 F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f -F src/delete.c 5872f452031f31c6941ef70e9f4e1823e9fecefc -F src/expr.c 2a9485be4ec44eea0f3eada89f415f2172fc5c2e +F src/delete.c 728a02e5b5c62d294f8cdbdb21dbaa3e188983ab +F src/expr.c fa983460a064ee9ba55a0b3be1bd7db6b0545622 F src/func.c dc188d862d7276ea897655b248e2cb17022686e3 F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 -F src/insert.c 0acf8a8cd21d60c60432c0004586d2aee0ad8d8e +F src/insert.c 18d506e14d200378902747d13d7fb2a43fb3d31d F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b F src/main.c cbe5a05baabad9fabb733065d0fb00c0b36f6ef1 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 @@ -57,10 +57,10 @@ F src/parse.y ceba179b9703657180963568f54b0e75f33e36e1 F src/pragma.c ac594f74c90ffec043c43e49358719ffeb491eec F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 -F src/select.c cfd5f30611967ebd7c39d4bd448a1b1e263e9fb8 +F src/select.c 37b9ddb9688a98c521d092dc38c811ec72191b14 F src/shell.c 591364a0e9ca4ce53873e21e0294476c0c2b4770 F src/sqlite.h.in 0d5e48e506845b74a845c9470e01d3f472b59611 -F src/sqliteInt.h f7ed4e6e112df9af7c85600bfb3b0af02e7b7577 +F src/sqliteInt.h a208bf0f51e6d7616c083313fa7cf5313efd346a F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c fd27457b228118be96524dae285146c76efe032b F src/test1.c 2e27b110ba5aa16977bad1cc2388553479d73793 @@ -68,9 +68,9 @@ F src/test2.c bbc2ecc58ceeab12d1e40970f831b1017524e40d F src/test3.c a72f20066cccd5a7b9f20b7b78fa9b05b47b3020 F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5 -F src/tokenize.c c1d124ec41422c9ec14360ea3a1f98ca4acf7cf1 -F src/trigger.c 210fe50d4b3c01d3e5f8ef8a7a820117416a992b -F src/update.c 79a1511104963df3368d9235f9393cfe7f38c027 +F src/tokenize.c 88bef43fe3e3c8865a7447f934296ac13238c4f6 +F src/trigger.c 7b5da6613419da37e5b3e1c6151c7dff95fd4ee0 +F src/update.c 48da25249d33c32fa1e55c66c5a01ec0d182b203 F src/utf.c 9bece2c7b94d9002ab1bb900a7658c6f826b0f74 F src/util.c 63e8d77659df88b292ac2a9dbd4766419b0ea158 F src/vacuum.c 1a9db113a027461daaf44724c71dd1ebbd064203 @@ -269,7 +269,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746 -P 5a9da62ae303800ded99942aed30eadeb3863da3 -R 27952fc035e1cac4b0d3a414cfc9fe27 +P 4a7534396a72ccb300303df28798bb2c50293782 +R f8f7d8c77656eb3939f3657d425a82a6 U drh -Z 916e3799f439fba92eda7a2a24dc2de5 +Z 295a57dfb9d4d3f564ec7f21c6307f77 diff --git a/manifest.uuid b/manifest.uuid index 2c09d63b5d..8174dd4e38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a7534396a72ccb300303df28798bb2c50293782 \ No newline at end of file +0142ae6f0004bf18a1c2d8e49c09d2a9a27d6369 \ No newline at end of file diff --git a/src/build.c b/src/build.c index ee505d2efa..7e304ef644 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.292 2005/01/17 22:08:19 drh Exp $ +** $Id: build.c,v 1.293 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" #include @@ -884,7 +884,7 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){ }else{ sqlite3ExprDelete(pCol->pDflt); pCol->pDflt = sqlite3ExprDup(pExpr); - sqlite3ExprResolveNames(pParse,0,0,pExpr,0,0,0); + sqlite3ExprResolveNames(pParse,0,0,pExpr,0,0); } sqlite3ExprDelete(pExpr); } diff --git a/src/delete.c b/src/delete.c index 0bc24577ba..f81ec3f7ac 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.96 2005/01/17 22:08:19 drh Exp $ +** $Id: delete.c,v 1.97 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" @@ -150,7 +150,7 @@ void sqlite3DeleteFrom( */ assert( pTabList->nSrc==1 ); iCur = pTabList->a[0].iCursor = pParse->nTab++; - if( sqlite3ExprResolveNames(pParse, pTabList, 0, pWhere, 0, 0, 1) ){ + if( sqlite3ExprResolveNames(pParse, pTabList, 0, pWhere, 0, 1) ){ goto delete_from_cleanup; } diff --git a/src/expr.c b/src/expr.c index 7c0fb70cbb..36cfa2821d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.179 2005/01/17 22:08:19 drh Exp $ +** $Id: expr.c,v 1.180 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" #include @@ -562,6 +562,7 @@ void sqlite3ExprListDelete(ExprList *pList){ /* ** Walk an expression tree. Call xFunc for each node visited. +** ** The return value from xFunc determines whether the tree walk continues. ** 0 means continue walking the tree. 1 means do not walk children ** of the current node but continue with siblings. 2 means abandon @@ -594,10 +595,14 @@ static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){ ** This routine is designed as an xFunc for walkExprTree(). ** ** pArg is really a pointer to an integer. If we can tell by looking -** at just pExpr and none of its children that the expression is a -** constant, then set *pArg to 1 and return 0. If we can tell that -** the expression is not a constant, then set *pArg to 0 and return 0. -** If we need to look at child nodes, return 1. +** at pExpr that the expression that contains pExpr is not a constant +** expression, then set *pArg to 0 and return 2 to abandon the tree walk. +** If pExpr does does not disqualify the expression from being a constant +** then do nothing. +** +** After walking the whole tree, if no nodes are found that disqualify +** the expression as constant, then we assume the whole expression +** is constant. See sqlite3ExprIsConstant() for additional information. */ static int exprNodeIsConstant(void *pArg, Expr *pExpr){ switch( pExpr->op ){ @@ -628,7 +633,7 @@ int sqlite3ExprIsConstant(Expr *p){ } /* -** If the given expression codes a constant integer that is small enough +** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. @@ -709,6 +714,7 @@ static int lookupName( sqlite3 *db = pParse->db; /* The database */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); @@ -872,6 +878,7 @@ static int lookupName( } sqlite3ErrorMsg(pParse, zErr, z); sqliteFree(z); + pTopNC->nErr++; } /* If a column from a table in pSrcList is referenced, then record @@ -957,9 +964,13 @@ static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ /* ** This routine is designed as an xFunc for walkExprTree(). ** -** Resolve symbolic names into TK_COLUMN operands for the current +** Resolve symbolic names into TK_COLUMN operators for the current ** node in the expression tree. Return 0 to continue the search down -** the tree or 1 to abort the tree walk. +** the tree or 2 to abort the tree walk. +** +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. */ static int nameResolverStep(void *pArg, Expr *pExpr){ NameContext *pNC = (NameContext*)pArg; @@ -1039,9 +1050,8 @@ static int nameResolverStep(void *pArg, Expr *pExpr){ int i; int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ - FuncDef *pDef; - int enc = pParse->db->enc; - NameContext ncParam; /* Name context for parameters */ + FuncDef *pDef; /* Information about the function */ + int enc = pParse->db->enc; /* The database encoding */ getFunctionName(pExpr, &zId, &nId); pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); @@ -1071,14 +1081,11 @@ static int nameResolverStep(void *pArg, Expr *pExpr){ pExpr->op = TK_AGG_FUNCTION; pNC->hasAgg = 1; } - ncParam = *pNC; - if( is_agg ) ncParam.allowAgg = 0; + if( is_agg ) pNC->allowAgg = 0; for(i=0; pNC->nErr==0 && ia[i].pExpr, nameResolverStep, &ncParam); - pNC->nErr += ncParam.nErr; - if( ncParam.hasAgg ) pNC->hasAgg = 1; + walkExprTree(pList->a[i].pExpr, nameResolverStep, pNC); } - if( pNC->nErr ) return 2; + if( is_agg ) pNC->allowAgg = 1; /* FIX ME: Compute pExpr->affinity based on the expected return ** type of the function */ @@ -1106,8 +1113,8 @@ static int nameResolverStep(void *pArg, Expr *pExpr){ ** have the correct number of arguments. Leave an error message ** in pParse->zErrMsg if anything is amiss. Return the number of errors. ** -** if pIsAgg is not null and this expression is an aggregate function -** (like count(*) or max(value)) then write a 1 into *pIsAgg. +** If the expression contains aggregate functions then set the EP_Agg +** property on the expression. */ int sqlite3ExprResolveNames( Parse *pParse, /* The parser context */ @@ -1115,29 +1122,33 @@ int sqlite3ExprResolveNames( ExprList *pEList, /* List of expressions used to resolve "AS" */ Expr *pExpr, /* The expression to be analyzed. */ int allowAgg, /* True to allow aggregate expressions */ - int *pIsAgg, /* Set to TRUE if aggregates are found */ int codeSubquery /* If true, then generate code for subqueries too */ ){ NameContext sNC; + if( pExpr==0 ) return 0; memset(&sNC, 0, sizeof(sNC)); sNC.pSrcList = pSrcList; sNC.pParse = pParse; sNC.pEList = pEList; sNC.allowAgg = allowAgg; walkExprTree(pExpr, nameResolverStep, &sNC); - if( pIsAgg && sNC.hasAgg ) *pIsAgg = 1; - if( sNC.nErr==0 && codeSubquery ){ - sNC.nErr += sqlite3ExprCodeSubquery(pParse, pExpr); + if( sNC.hasAgg ){ + ExprSetProperty(pExpr, EP_Agg); } - return sNC.nErr + pParse->nErr; + if( sNC.nErr>0 ){ + ExprSetProperty(pExpr, EP_Error); + }else if( codeSubquery && sqlite3ExprCodeSubquery(pParse, pExpr) ){ + return 1; + } + return ExprHasProperty(pExpr, EP_Error); } /* ** Generate code for subqueries and IN operators. ** -** IN comes in two forms: +** IN operators comes in two forms: ** ** expr IN (exprlist) ** and @@ -1150,6 +1161,10 @@ int sqlite3ExprResolveNames( ** This routine also looks for scalar SELECTs that are part of an expression. ** If it finds any, it generates code to write the value of that select ** into a memory cell. +** +** This routine is a callback for wallExprTree() used to implement +** sqlite3ExprCodeSubquery(). See comments on those routines for +** additional information. */ static int codeSubqueryStep(void *pArg, Expr *pExpr){ Parse *pParse = (Parse*)pArg; @@ -1222,7 +1237,7 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){ "right-hand side of IN operator must be constant"); return 2; } - if( sqlite3ExprResolveNames(pParse, 0, 0, pE2, 0, 0, 0) ){ + if( sqlite3ExprResolveNames(pParse, 0, 0, pE2, 0, 0) ){ return 2; } @@ -1251,7 +1266,8 @@ static int codeSubqueryStep(void *pArg, Expr *pExpr){ } /* -** Generate code to evaluate subqueries and IN operators. +** Generate code to evaluate subqueries and IN operators contained +** in expression pExpr. */ int sqlite3ExprCodeSubquery(Parse *pParse, Expr *pExpr){ walkExprTree(pExpr, codeSubqueryStep, pParse); @@ -1869,6 +1885,8 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ /* ** Add a new element to the pParse->aAgg[] array and return its index. +** The new element is initialized to zero. The calling function is +** expected to fill it in. */ static int appendAggInfo(Parse *pParse){ if( (pParse->nAgg & 0x7)==0 ){ diff --git a/src/insert.c b/src/insert.c index 17b5cf8eee..11b27de2cd 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.131 2005/01/17 22:08:19 drh Exp $ +** $Id: insert.c,v 1.132 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" @@ -380,7 +380,7 @@ void sqlite3Insert( nColumn = pList->nExpr; dummy.nSrc = 0; for(i=0; ia[i].pExpr,0,0,1) ){ + if( sqlite3ExprResolveNames(pParse,&dummy,0,pList->a[i].pExpr,0,1) ){ goto insert_cleanup; } } diff --git a/src/select.c b/src/select.c index dce52c4022..c1d2dc9b43 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.223 2005/01/17 22:08:19 drh Exp $ +** $Id: select.c,v 1.224 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" @@ -2186,7 +2186,7 @@ static int processOrderGroupBy( sqlite3ExprDelete(pE); pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); } - if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pE, isAgg, 0, 1) ){ + if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pE, isAgg, 1) ){ return 1; } if( sqlite3ExprIsConstant(pE) ){ @@ -2355,12 +2355,13 @@ int sqlite3Select( ** Resolve the column names and do a semantics check on all the expressions. */ for(i=0; inExpr; i++){ - if( sqlite3ExprResolveNames(pParse, pTabList, 0, pEList->a[i].pExpr, - 1, &isAgg, 1) ){ + Expr *pX = pEList->a[i].pExpr; + if( sqlite3ExprResolveNames(pParse, pTabList, 0, pX, 1, 1) ){ goto select_end; } + if( ExprHasProperty(pX, EP_Agg) ) isAgg = 1; } - if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pWhere, 0, 0, 1) ){ + if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pWhere, 0, 1) ){ goto select_end; } if( pHaving ){ @@ -2368,9 +2369,10 @@ int sqlite3Select( sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); goto select_end; } - if( sqlite3ExprResolveNames(pParse, pTabList, pEList,pHaving,1,&isAgg,1) ){ + if( sqlite3ExprResolveNames(pParse, pTabList, pEList, pHaving, 1, 1) ){ goto select_end; } + if( ExprHasProperty(pHaving, EP_Agg) ) isAgg = 1; } if( pGroupBy && !isAgg ){ sqlite3ErrorMsg(pParse, "GROUP BY may only be used on aggregate queries"); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 39393ea866..b85b28d713 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.354 2005/01/17 22:08:19 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.355 2005/01/18 04:00:44 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -817,6 +817,7 @@ struct Expr { #define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */ #define EP_Agg 0x0002 /* Contains one or more aggregate functions */ #define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */ +#define EP_Error 0x0008 /* Expression contains one or more errors */ /* ** These macros can be used to test, set, or clear bits in the @@ -1423,7 +1424,7 @@ char *sqlite3NameFromToken(Token*); int sqlite3ExprCheck(Parse*, Expr*, int, int*); int sqlite3ExprCompare(Expr*, Expr*); int sqliteFuncId(Token*); -int sqlite3ExprResolveNames(Parse*, SrcList*, ExprList*, Expr*, int, int*, int); +int sqlite3ExprResolveNames(Parse*, SrcList*, ExprList*, Expr*, int, int); int sqlite3ExprCodeSubquery(Parse*, Expr*); int sqlite3ExprAnalyzeAggregates(Parse*, Expr*); Vdbe *sqlite3GetVdbe(Parse*); diff --git a/src/tokenize.c b/src/tokenize.c index 725223cef5..43490cbebd 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.98 2005/01/11 17:59:48 drh Exp $ +** $Id: tokenize.c,v 1.99 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -28,12 +28,12 @@ ** returned. If the input is not a keyword, TK_ID is returned. ** ** The implementation of this routine was generated by a program, -** mkkeywordhash.c, located in the tool subdirectory of the distribution. +** mkkeywordhash.h, located in the tool subdirectory of the distribution. ** The output of the mkkeywordhash.c program is written into a file -** named keywordhash.c and then included into this source file by +** named keywordhash.h and then included into this source file by ** the #include below. */ -#include "keywordhash.c" +#include "keywordhash.h" /* diff --git a/src/trigger.c b/src/trigger.c index 0fe636971d..f63c7c9910 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -766,7 +766,7 @@ int sqlite3CodeRowTrigger( /* code the WHEN clause */ endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); whenExpr = sqlite3ExprDup(pTrigger->pWhen); - if( sqlite3ExprResolveNames(pParse, &dummyTablist, 0, whenExpr, 0, 0, 1)){ + if( sqlite3ExprResolveNames(pParse, &dummyTablist, 0, whenExpr, 0, 1) ){ pParse->trigStack = trigStackEntry.pNext; sqlite3ExprDelete(whenExpr); return 1; diff --git a/src/update.c b/src/update.c index 38223ebae9..27b9c24584 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.101 2005/01/17 22:08:19 drh Exp $ +** $Id: update.c,v 1.102 2005/01/18 04:00:44 drh Exp $ */ #include "sqliteInt.h" @@ -122,7 +122,7 @@ void sqlite3Update( chngRecno = 0; for(i=0; inExpr; i++){ if( sqlite3ExprResolveNames(pParse, pTabList, 0, - pChanges->a[i].pExpr, 0, 0, 1) ){ + pChanges->a[i].pExpr, 0, 1) ){ goto update_cleanup; } for(j=0; jnCol; j++){ @@ -198,7 +198,7 @@ void sqlite3Update( /* Resolve the column names in all the expressions in the ** WHERE clause. */ - if( sqlite3ExprResolveNames(pParse, pTabList, 0, pWhere, 0, 0, 1) ){ + if( sqlite3ExprResolveNames(pParse, pTabList, 0, pWhere, 0, 1) ){ goto update_cleanup; }