1cce7d176Sdrh /* 2b19a2bc6Sdrh ** 2001 September 15 3cce7d176Sdrh ** 4b19a2bc6Sdrh ** The author disclaims copyright to this source code. In place of 5b19a2bc6Sdrh ** a legal notice, here is a blessing: 6cce7d176Sdrh ** 7b19a2bc6Sdrh ** May you do good and not evil. 8b19a2bc6Sdrh ** May you find forgiveness for yourself and forgive others. 9b19a2bc6Sdrh ** May you share freely, never taking more than you give. 10cce7d176Sdrh ** 11cce7d176Sdrh ************************************************************************* 12cce7d176Sdrh ** This file contains C code routines that are called by the parser 13b19a2bc6Sdrh ** to handle SELECT statements in SQLite. 14cce7d176Sdrh ** 15*a76b5dfcSdrh ** $Id: select.c,v 1.65 2002/02/23 02:32:10 drh Exp $ 16cce7d176Sdrh */ 17cce7d176Sdrh #include "sqliteInt.h" 18cce7d176Sdrh 19cce7d176Sdrh /* 209bb61fe7Sdrh ** Allocate a new Select structure and return a pointer to that 219bb61fe7Sdrh ** structure. 22cce7d176Sdrh */ 239bb61fe7Sdrh Select *sqliteSelectNew( 24daffd0e5Sdrh ExprList *pEList, /* which columns to include in the result */ 25daffd0e5Sdrh IdList *pSrc, /* the FROM clause -- which tables to scan */ 26daffd0e5Sdrh Expr *pWhere, /* the WHERE clause */ 27daffd0e5Sdrh ExprList *pGroupBy, /* the GROUP BY clause */ 28daffd0e5Sdrh Expr *pHaving, /* the HAVING clause */ 29daffd0e5Sdrh ExprList *pOrderBy, /* the ORDER BY clause */ 309bbca4c1Sdrh int isDistinct, /* true if the DISTINCT keyword is present */ 319bbca4c1Sdrh int nLimit, /* LIMIT value. -1 means not used */ 329bbca4c1Sdrh int nOffset /* OFFSET value. -1 means not used */ 339bb61fe7Sdrh ){ 349bb61fe7Sdrh Select *pNew; 359bb61fe7Sdrh pNew = sqliteMalloc( sizeof(*pNew) ); 36daffd0e5Sdrh if( pNew==0 ){ 37daffd0e5Sdrh sqliteExprListDelete(pEList); 38daffd0e5Sdrh sqliteIdListDelete(pSrc); 39daffd0e5Sdrh sqliteExprDelete(pWhere); 40daffd0e5Sdrh sqliteExprListDelete(pGroupBy); 41daffd0e5Sdrh sqliteExprDelete(pHaving); 42daffd0e5Sdrh sqliteExprListDelete(pOrderBy); 43daffd0e5Sdrh }else{ 449bb61fe7Sdrh pNew->pEList = pEList; 459bb61fe7Sdrh pNew->pSrc = pSrc; 469bb61fe7Sdrh pNew->pWhere = pWhere; 479bb61fe7Sdrh pNew->pGroupBy = pGroupBy; 489bb61fe7Sdrh pNew->pHaving = pHaving; 499bb61fe7Sdrh pNew->pOrderBy = pOrderBy; 509bb61fe7Sdrh pNew->isDistinct = isDistinct; 5182c3d636Sdrh pNew->op = TK_SELECT; 529bbca4c1Sdrh pNew->nLimit = nLimit; 539bbca4c1Sdrh pNew->nOffset = nOffset; 54daffd0e5Sdrh } 559bb61fe7Sdrh return pNew; 569bb61fe7Sdrh } 579bb61fe7Sdrh 589bb61fe7Sdrh /* 599bb61fe7Sdrh ** Delete the given Select structure and all of its substructures. 609bb61fe7Sdrh */ 619bb61fe7Sdrh void sqliteSelectDelete(Select *p){ 6282c3d636Sdrh if( p==0 ) return; 639bb61fe7Sdrh sqliteExprListDelete(p->pEList); 649bb61fe7Sdrh sqliteIdListDelete(p->pSrc); 659bb61fe7Sdrh sqliteExprDelete(p->pWhere); 669bb61fe7Sdrh sqliteExprListDelete(p->pGroupBy); 679bb61fe7Sdrh sqliteExprDelete(p->pHaving); 689bb61fe7Sdrh sqliteExprListDelete(p->pOrderBy); 6982c3d636Sdrh sqliteSelectDelete(p->pPrior); 70*a76b5dfcSdrh sqliteFree(p->zSelect); 719bb61fe7Sdrh sqliteFree(p); 729bb61fe7Sdrh } 739bb61fe7Sdrh 749bb61fe7Sdrh /* 752282792aSdrh ** Delete the aggregate information from the parse structure. 762282792aSdrh */ 771d83f052Sdrh static void sqliteAggregateInfoReset(Parse *pParse){ 782282792aSdrh sqliteFree(pParse->aAgg); 792282792aSdrh pParse->aAgg = 0; 802282792aSdrh pParse->nAgg = 0; 812282792aSdrh pParse->iAggCount = -1; 822282792aSdrh pParse->useAgg = 0; 832282792aSdrh } 842282792aSdrh 852282792aSdrh /* 862282792aSdrh ** This routine generates the code for the inside of the inner loop 872282792aSdrh ** of a SELECT. 8882c3d636Sdrh ** 8982c3d636Sdrh ** The pEList is used to determine the values for each column in the 90967e8b73Sdrh ** result row. Except if pEList==NULL, then we just read nColumn 9182c3d636Sdrh ** elements from the srcTab table. 922282792aSdrh */ 932282792aSdrh static int selectInnerLoop( 942282792aSdrh Parse *pParse, /* The parser context */ 952282792aSdrh ExprList *pEList, /* List of values being extracted */ 9682c3d636Sdrh int srcTab, /* Pull data from this table */ 97967e8b73Sdrh int nColumn, /* Number of columns in the source table */ 982282792aSdrh ExprList *pOrderBy, /* If not NULL, sort results using this key */ 992282792aSdrh int distinct, /* If >=0, make sure results are distinct */ 1002282792aSdrh int eDest, /* How to dispose of the results */ 1012282792aSdrh int iParm, /* An argument to the disposal method */ 1022282792aSdrh int iContinue, /* Jump here to continue with next row */ 1032282792aSdrh int iBreak /* Jump here to break out of the inner loop */ 1042282792aSdrh ){ 1052282792aSdrh Vdbe *v = pParse->pVdbe; 1062282792aSdrh int i; 107daffd0e5Sdrh if( v==0 ) return 0; 1082282792aSdrh 109967e8b73Sdrh /* Pull the requested columns. 1102282792aSdrh */ 11182c3d636Sdrh if( pEList ){ 1122282792aSdrh for(i=0; i<pEList->nExpr; i++){ 1132282792aSdrh sqliteExprCode(pParse, pEList->a[i].pExpr); 1142282792aSdrh } 115967e8b73Sdrh nColumn = pEList->nExpr; 11682c3d636Sdrh }else{ 117967e8b73Sdrh for(i=0; i<nColumn; i++){ 11899fcd718Sdrh sqliteVdbeAddOp(v, OP_Column, srcTab, i); 11982c3d636Sdrh } 12082c3d636Sdrh } 1212282792aSdrh 122daffd0e5Sdrh /* If the DISTINCT keyword was present on the SELECT statement 123daffd0e5Sdrh ** and this row has been seen before, then do not make this row 124daffd0e5Sdrh ** part of the result. 1252282792aSdrh */ 1262282792aSdrh if( distinct>=0 ){ 1272282792aSdrh int lbl = sqliteVdbeMakeLabel(v); 12899fcd718Sdrh sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1); 12999fcd718Sdrh sqliteVdbeAddOp(v, OP_Distinct, distinct, lbl); 13099fcd718Sdrh sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0); 13199fcd718Sdrh sqliteVdbeAddOp(v, OP_Goto, 0, iContinue); 13299fcd718Sdrh sqliteVdbeResolveLabel(v, lbl); 13399fcd718Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0); 1346b12545fSdrh sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0); 1352282792aSdrh } 13682c3d636Sdrh 1372282792aSdrh /* If there is an ORDER BY clause, then store the results 1382282792aSdrh ** in a sorter. 1392282792aSdrh */ 1402282792aSdrh if( pOrderBy ){ 1412282792aSdrh char *zSortOrder; 14299fcd718Sdrh sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0); 1432282792aSdrh zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 ); 1442282792aSdrh if( zSortOrder==0 ) return 1; 1452282792aSdrh for(i=0; i<pOrderBy->nExpr; i++){ 146d8bc7086Sdrh zSortOrder[i] = pOrderBy->a[i].sortOrder ? '-' : '+'; 1472282792aSdrh sqliteExprCode(pParse, pOrderBy->a[i].pExpr); 1482282792aSdrh } 1492282792aSdrh zSortOrder[pOrderBy->nExpr] = 0; 15099fcd718Sdrh sqliteVdbeAddOp(v, OP_SortMakeKey, pOrderBy->nExpr, 0); 15199fcd718Sdrh sqliteVdbeChangeP3(v, -1, zSortOrder, strlen(zSortOrder)); 1526e142f54Sdrh sqliteFree(zSortOrder); 15399fcd718Sdrh sqliteVdbeAddOp(v, OP_SortPut, 0, 0); 1542282792aSdrh }else 1552282792aSdrh 15682c3d636Sdrh /* In this mode, write each query result to the key of the temporary 15782c3d636Sdrh ** table iParm. 1582282792aSdrh */ 15982c3d636Sdrh if( eDest==SRT_Union ){ 16099fcd718Sdrh sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0); 16199fcd718Sdrh sqliteVdbeAddOp(v, OP_String, iParm, 0); 1626b12545fSdrh sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0); 16382c3d636Sdrh }else 16482c3d636Sdrh 1655974a30fSdrh /* Store the result as data using a unique key. 1665974a30fSdrh */ 1675974a30fSdrh if( eDest==SRT_Table ){ 16899fcd718Sdrh sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0); 16999fcd718Sdrh sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0); 17099fcd718Sdrh sqliteVdbeAddOp(v, OP_Pull, 1, 0); 1716b12545fSdrh sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0); 1725974a30fSdrh }else 1735974a30fSdrh 17482c3d636Sdrh /* Construct a record from the query result, but instead of 17582c3d636Sdrh ** saving that record, use it as a key to delete elements from 17682c3d636Sdrh ** the temporary table iParm. 17782c3d636Sdrh */ 17882c3d636Sdrh if( eDest==SRT_Except ){ 17999fcd718Sdrh int addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0); 18099fcd718Sdrh sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3); 18199fcd718Sdrh sqliteVdbeAddOp(v, OP_Delete, iParm, 0); 1822282792aSdrh }else 1832282792aSdrh 1842282792aSdrh /* If we are creating a set for an "expr IN (SELECT ...)" construct, 1852282792aSdrh ** then there should be a single item on the stack. Write this 1862282792aSdrh ** item into the set table with bogus data. 1872282792aSdrh */ 1882282792aSdrh if( eDest==SRT_Set ){ 189967e8b73Sdrh assert( nColumn==1 ); 19099fcd718Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0); 1916b12545fSdrh sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0); 1922282792aSdrh }else 1932282792aSdrh 19482c3d636Sdrh 1952282792aSdrh /* If this is a scalar select that is part of an expression, then 1962282792aSdrh ** store the results in the appropriate memory cell and break out 1972282792aSdrh ** of the scan loop. 1982282792aSdrh */ 1992282792aSdrh if( eDest==SRT_Mem ){ 200967e8b73Sdrh assert( nColumn==1 ); 2018721ce4aSdrh sqliteVdbeAddOp(v, OP_MemStore, iParm, 1); 20299fcd718Sdrh sqliteVdbeAddOp(v, OP_Goto, 0, iBreak); 2032282792aSdrh }else 2042282792aSdrh 2052282792aSdrh /* If none of the above, send the data to the callback function. 2062282792aSdrh */ 2072282792aSdrh { 2089bbca4c1Sdrh sqliteVdbeAddOp(v, OP_Callback, nColumn, iBreak); 20982c3d636Sdrh } 21082c3d636Sdrh return 0; 21182c3d636Sdrh } 21282c3d636Sdrh 21382c3d636Sdrh /* 214d8bc7086Sdrh ** If the inner loop was generated using a non-null pOrderBy argument, 215d8bc7086Sdrh ** then the results were placed in a sorter. After the loop is terminated 216d8bc7086Sdrh ** we need to run the sorter and output the results. The following 217d8bc7086Sdrh ** routine generates the code needed to do that. 218d8bc7086Sdrh */ 219967e8b73Sdrh static void generateSortTail(Vdbe *v, int nColumn){ 220d8bc7086Sdrh int end = sqliteVdbeMakeLabel(v); 221d8bc7086Sdrh int addr; 22299fcd718Sdrh sqliteVdbeAddOp(v, OP_Sort, 0, 0); 22399fcd718Sdrh addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end); 2249bbca4c1Sdrh sqliteVdbeAddOp(v, OP_SortCallback, nColumn, end); 22599fcd718Sdrh sqliteVdbeAddOp(v, OP_Goto, 0, addr); 22699fcd718Sdrh sqliteVdbeResolveLabel(v, end); 227a8b38d28Sdrh sqliteVdbeAddOp(v, OP_SortReset, 0, 0); 228d8bc7086Sdrh } 229d8bc7086Sdrh 230d8bc7086Sdrh /* 23182c3d636Sdrh ** Generate code that will tell the VDBE how many columns there 23282c3d636Sdrh ** are in the result and the name for each column. This information 23382c3d636Sdrh ** is used to provide "argc" and "azCol[]" values in the callback. 23482c3d636Sdrh */ 235d8bc7086Sdrh static 236d8bc7086Sdrh void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){ 237d8bc7086Sdrh Vdbe *v = pParse->pVdbe; 23882c3d636Sdrh int i; 239daffd0e5Sdrh if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return; 240d8bc7086Sdrh pParse->colNamesSet = 1; 24199fcd718Sdrh sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0); 24282c3d636Sdrh for(i=0; i<pEList->nExpr; i++){ 24382c3d636Sdrh Expr *p; 2441bee3d7bSdrh int showFullNames; 24582c3d636Sdrh if( pEList->a[i].zName ){ 24682c3d636Sdrh char *zName = pEList->a[i].zName; 24799fcd718Sdrh sqliteVdbeAddOp(v, OP_ColumnName, i, 0); 24899fcd718Sdrh sqliteVdbeChangeP3(v, -1, zName, strlen(zName)); 24982c3d636Sdrh continue; 25082c3d636Sdrh } 25182c3d636Sdrh p = pEList->a[i].pExpr; 252daffd0e5Sdrh if( p==0 ) continue; 2531bee3d7bSdrh showFullNames = (pParse->db->flags & SQLITE_FullColNames)!=0; 2541bee3d7bSdrh if( p->span.z && p->span.z[0] && !showFullNames ){ 25599fcd718Sdrh int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0); 25699fcd718Sdrh sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n); 257e1b6a5b8Sdrh sqliteVdbeCompressSpace(v, addr); 2581bee3d7bSdrh }else if( p->op==TK_COLUMN && pTabList ){ 2598aff1015Sdrh Table *pTab = pTabList->a[p->iTable - pParse->nTab].pTab; 26097665873Sdrh char *zCol; 2618aff1015Sdrh int iCol = p->iColumn; 2628aff1015Sdrh if( iCol<0 ) iCol = pTab->iPKey; 26397665873Sdrh assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) ); 26497665873Sdrh zCol = iCol<0 ? "_ROWID_" : pTab->aCol[iCol].zName; 2651bee3d7bSdrh if( pTabList->nId>1 || showFullNames ){ 26682c3d636Sdrh char *zName = 0; 26782c3d636Sdrh char *zTab; 26882c3d636Sdrh 26998808babSdrh zTab = pTabList->a[p->iTable - pParse->nTab].zAlias; 27001a34661Sdrh if( showFullNames || zTab==0 ) zTab = pTab->zName; 27197665873Sdrh sqliteSetString(&zName, zTab, ".", zCol, 0); 27299fcd718Sdrh sqliteVdbeAddOp(v, OP_ColumnName, i, 0); 27399fcd718Sdrh sqliteVdbeChangeP3(v, -1, zName, strlen(zName)); 27482c3d636Sdrh sqliteFree(zName); 27582c3d636Sdrh }else{ 27699fcd718Sdrh sqliteVdbeAddOp(v, OP_ColumnName, i, 0); 27722f70c32Sdrh sqliteVdbeChangeP3(v, -1, zCol, 0); 27882c3d636Sdrh } 2791bee3d7bSdrh }else if( p->span.z && p->span.z[0] ){ 2801bee3d7bSdrh int addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0); 2811bee3d7bSdrh sqliteVdbeChangeP3(v, -1, p->span.z, p->span.n); 2821bee3d7bSdrh sqliteVdbeCompressSpace(v, addr); 2831bee3d7bSdrh }else{ 2841bee3d7bSdrh char zName[30]; 2851bee3d7bSdrh assert( p->op!=TK_COLUMN || pTabList==0 ); 2861bee3d7bSdrh sprintf(zName, "column%d", i+1); 2871bee3d7bSdrh sqliteVdbeAddOp(v, OP_ColumnName, i, 0); 2881bee3d7bSdrh sqliteVdbeChangeP3(v, -1, zName, strlen(zName)); 28982c3d636Sdrh } 29082c3d636Sdrh } 29182c3d636Sdrh } 29282c3d636Sdrh 29382c3d636Sdrh /* 294d8bc7086Sdrh ** Name of the connection operator, used for error messages. 295d8bc7086Sdrh */ 296d8bc7086Sdrh static const char *selectOpName(int id){ 297d8bc7086Sdrh char *z; 298d8bc7086Sdrh switch( id ){ 299d8bc7086Sdrh case TK_ALL: z = "UNION ALL"; break; 300d8bc7086Sdrh case TK_INTERSECT: z = "INTERSECT"; break; 301d8bc7086Sdrh case TK_EXCEPT: z = "EXCEPT"; break; 302d8bc7086Sdrh default: z = "UNION"; break; 303d8bc7086Sdrh } 304d8bc7086Sdrh return z; 305d8bc7086Sdrh } 306d8bc7086Sdrh 307d8bc7086Sdrh /* 30822f70c32Sdrh ** Given a SELECT statement, generate a Table structure that describes 30922f70c32Sdrh ** the result set of that SELECT. 31022f70c32Sdrh */ 31122f70c32Sdrh Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ 31222f70c32Sdrh Table *pTab; 31322f70c32Sdrh int i; 31422f70c32Sdrh ExprList *pEList; 31522f70c32Sdrh static int fillInColumnList(Parse*, Select*); 31622f70c32Sdrh 31722f70c32Sdrh if( fillInColumnList(pParse, pSelect) ){ 31822f70c32Sdrh return 0; 31922f70c32Sdrh } 32022f70c32Sdrh pTab = sqliteMalloc( sizeof(Table) ); 32122f70c32Sdrh if( pTab==0 ){ 32222f70c32Sdrh return 0; 32322f70c32Sdrh } 32422f70c32Sdrh pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0; 32522f70c32Sdrh pEList = pSelect->pEList; 32622f70c32Sdrh pTab->nCol = pEList->nExpr; 32722f70c32Sdrh pTab->aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); 32822f70c32Sdrh for(i=0; i<pTab->nCol; i++){ 32922f70c32Sdrh Expr *p; 33022f70c32Sdrh if( pEList->a[i].zName ){ 33122f70c32Sdrh pTab->aCol[i].zName = sqliteStrDup(pEList->a[i].zName); 33222f70c32Sdrh }else if( (p=pEList->a[i].pExpr)->span.z && p->span.z[0] ){ 33322f70c32Sdrh sqliteSetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0); 334d820cb1bSdrh }else if( p->op==TK_DOT && p->pRight && p->pRight->token.z && 335d820cb1bSdrh p->pRight->token.z[0] ){ 336d820cb1bSdrh sqliteSetNString(&pTab->aCol[i].zName, 337d820cb1bSdrh p->pRight->token.z, p->pRight->token.n, 0); 33822f70c32Sdrh }else{ 33922f70c32Sdrh char zBuf[30]; 34022f70c32Sdrh sprintf(zBuf, "column%d", i+1); 34122f70c32Sdrh pTab->aCol[i].zName = sqliteStrDup(zBuf); 34222f70c32Sdrh } 34322f70c32Sdrh } 34422f70c32Sdrh pTab->iPKey = -1; 34522f70c32Sdrh return pTab; 34622f70c32Sdrh } 34722f70c32Sdrh 34822f70c32Sdrh /* 349d8bc7086Sdrh ** For the given SELECT statement, do two things. 350d8bc7086Sdrh ** 351967e8b73Sdrh ** (1) Fill in the pTabList->a[].pTab fields in the IdList that 352967e8b73Sdrh ** defines the set of tables that should be scanned. 353d8bc7086Sdrh ** 354d8bc7086Sdrh ** (2) If the columns to be extracted variable (pEList) is NULL 355d8bc7086Sdrh ** (meaning that a "*" was used in the SQL statement) then 356d8bc7086Sdrh ** create a fake pEList containing the names of all columns 357d8bc7086Sdrh ** of all tables. 358d8bc7086Sdrh ** 359d8bc7086Sdrh ** Return 0 on success. If there are problems, leave an error message 360d8bc7086Sdrh ** in pParse and return non-zero. 361d8bc7086Sdrh */ 362d8bc7086Sdrh static int fillInColumnList(Parse *pParse, Select *p){ 3637c917d19Sdrh int i, j, k; 364daffd0e5Sdrh IdList *pTabList; 365daffd0e5Sdrh ExprList *pEList; 366*a76b5dfcSdrh Table *pTab; 367daffd0e5Sdrh 368daffd0e5Sdrh if( p==0 || p->pSrc==0 ) return 1; 369daffd0e5Sdrh pTabList = p->pSrc; 370daffd0e5Sdrh pEList = p->pEList; 371d8bc7086Sdrh 372d8bc7086Sdrh /* Look up every table in the table list. 373d8bc7086Sdrh */ 374d8bc7086Sdrh for(i=0; i<pTabList->nId; i++){ 375d8bc7086Sdrh if( pTabList->a[i].pTab ){ 376d8bc7086Sdrh /* This routine has run before! No need to continue */ 377d8bc7086Sdrh return 0; 378d8bc7086Sdrh } 379daffd0e5Sdrh if( pTabList->a[i].zName==0 ){ 38022f70c32Sdrh /* A sub-query in the FROM clause of a SELECT */ 38122f70c32Sdrh assert( pTabList->a[i].pSelect!=0 ); 38222f70c32Sdrh pTabList->a[i].pTab = pTab = 38322f70c32Sdrh sqliteResultSetOfSelect(pParse, pTabList->a[i].zAlias, 38422f70c32Sdrh pTabList->a[i].pSelect); 38522f70c32Sdrh if( pTab==0 ){ 386daffd0e5Sdrh return 1; 387daffd0e5Sdrh } 38822f70c32Sdrh pTab->isTransient = 1; 38922f70c32Sdrh }else{ 390*a76b5dfcSdrh /* An ordinary table or view name in the FROM clause */ 391*a76b5dfcSdrh pTabList->a[i].pTab = pTab = 392*a76b5dfcSdrh sqliteFindTable(pParse->db, pTabList->a[i].zName); 393*a76b5dfcSdrh if( pTab==0 ){ 394d8bc7086Sdrh sqliteSetString(&pParse->zErrMsg, "no such table: ", 395d8bc7086Sdrh pTabList->a[i].zName, 0); 396d8bc7086Sdrh pParse->nErr++; 397d8bc7086Sdrh return 1; 398d8bc7086Sdrh } 399*a76b5dfcSdrh if( pTab->pSelect ){ 400*a76b5dfcSdrh pTabList->a[i].pSelect = pTab->pSelect; 401*a76b5dfcSdrh } 402d8bc7086Sdrh } 40322f70c32Sdrh } 404d8bc7086Sdrh 4057c917d19Sdrh /* For every "*" that occurs in the column list, insert the names of 4067c917d19Sdrh ** all columns in all tables. The parser inserted a special expression 4077c917d19Sdrh ** with the TK_ALL operator for each "*" that it found in the column list. 4087c917d19Sdrh ** The following code just has to locate the TK_ALL expressions and expand 4097c917d19Sdrh ** each one to the list of all columns in all tables. 410d8bc7086Sdrh */ 4117c917d19Sdrh for(k=0; k<pEList->nExpr; k++){ 4127c917d19Sdrh if( pEList->a[k].pExpr->op==TK_ALL ) break; 4137c917d19Sdrh } 4147c917d19Sdrh if( k<pEList->nExpr ){ 4157c917d19Sdrh struct ExprList_item *a = pEList->a; 4167c917d19Sdrh ExprList *pNew = 0; 4177c917d19Sdrh for(k=0; k<pEList->nExpr; k++){ 4187c917d19Sdrh if( a[k].pExpr->op!=TK_ALL ){ 4197c917d19Sdrh pNew = sqliteExprListAppend(pNew, a[k].pExpr, 0); 4207c917d19Sdrh pNew->a[pNew->nExpr-1].zName = a[k].zName; 4217c917d19Sdrh a[k].pExpr = 0; 4227c917d19Sdrh a[k].zName = 0; 4237c917d19Sdrh }else{ 424d8bc7086Sdrh for(i=0; i<pTabList->nId; i++){ 425d8bc7086Sdrh Table *pTab = pTabList->a[i].pTab; 426d8bc7086Sdrh for(j=0; j<pTab->nCol; j++){ 42722f70c32Sdrh Expr *pExpr, *pLeft, *pRight; 42822f70c32Sdrh pRight = sqliteExpr(TK_ID, 0, 0, 0); 42922f70c32Sdrh if( pRight==0 ) break; 43022f70c32Sdrh pRight->token.z = pTab->aCol[j].zName; 43122f70c32Sdrh pRight->token.n = strlen(pTab->aCol[j].zName); 43222f70c32Sdrh if( pTab->zName ){ 43322f70c32Sdrh pLeft = sqliteExpr(TK_ID, 0, 0, 0); 43422f70c32Sdrh if( pLeft==0 ) break; 43517e24df6Sdrh if( pTabList->a[i].zAlias && pTabList->a[i].zAlias[0] ){ 43622f70c32Sdrh pLeft->token.z = pTabList->a[i].zAlias; 43722f70c32Sdrh pLeft->token.n = strlen(pTabList->a[i].zAlias); 43817e24df6Sdrh }else{ 43922f70c32Sdrh pLeft->token.z = pTab->zName; 44022f70c32Sdrh pLeft->token.n = strlen(pTab->zName); 44117e24df6Sdrh } 44222f70c32Sdrh pExpr = sqliteExpr(TK_DOT, pLeft, pRight, 0); 44322f70c32Sdrh if( pExpr==0 ) break; 44422f70c32Sdrh }else{ 44522f70c32Sdrh pExpr = pRight; 44622f70c32Sdrh pExpr->span = pExpr->token; 44722f70c32Sdrh } 4487c917d19Sdrh pNew = sqliteExprListAppend(pNew, pExpr, 0); 449d8bc7086Sdrh } 450d8bc7086Sdrh } 4517c917d19Sdrh } 4527c917d19Sdrh } 4537c917d19Sdrh sqliteExprListDelete(pEList); 4547c917d19Sdrh p->pEList = pNew; 455d8bc7086Sdrh } 456d8bc7086Sdrh return 0; 457d8bc7086Sdrh } 458d8bc7086Sdrh 459d8bc7086Sdrh /* 460d8bc7086Sdrh ** This routine associates entries in an ORDER BY expression list with 461d8bc7086Sdrh ** columns in a result. For each ORDER BY expression, the opcode of 462967e8b73Sdrh ** the top-level node is changed to TK_COLUMN and the iColumn value of 463d8bc7086Sdrh ** the top-level node is filled in with column number and the iTable 464d8bc7086Sdrh ** value of the top-level node is filled with iTable parameter. 465d8bc7086Sdrh ** 466d8bc7086Sdrh ** If there are prior SELECT clauses, they are processed first. A match 467d8bc7086Sdrh ** in an earlier SELECT takes precedence over a later SELECT. 468d8bc7086Sdrh ** 469d8bc7086Sdrh ** Any entry that does not match is flagged as an error. The number 470d8bc7086Sdrh ** of errors is returned. 471d8bc7086Sdrh */ 472d8bc7086Sdrh static int matchOrderbyToColumn( 473d8bc7086Sdrh Parse *pParse, /* A place to leave error messages */ 474d8bc7086Sdrh Select *pSelect, /* Match to result columns of this SELECT */ 475d8bc7086Sdrh ExprList *pOrderBy, /* The ORDER BY values to match against columns */ 476d8bc7086Sdrh int iTable, /* Insert this this value in iTable */ 477d8bc7086Sdrh int mustComplete /* If TRUE all ORDER BYs must match */ 478d8bc7086Sdrh ){ 479d8bc7086Sdrh int nErr = 0; 480d8bc7086Sdrh int i, j; 481d8bc7086Sdrh ExprList *pEList; 482d8bc7086Sdrh 483daffd0e5Sdrh if( pSelect==0 || pOrderBy==0 ) return 1; 484d8bc7086Sdrh if( mustComplete ){ 485d8bc7086Sdrh for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; } 486d8bc7086Sdrh } 487d8bc7086Sdrh if( fillInColumnList(pParse, pSelect) ){ 488d8bc7086Sdrh return 1; 489d8bc7086Sdrh } 490d8bc7086Sdrh if( pSelect->pPrior ){ 49192cd52f5Sdrh if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){ 49292cd52f5Sdrh return 1; 49392cd52f5Sdrh } 494d8bc7086Sdrh } 495d8bc7086Sdrh pEList = pSelect->pEList; 496d8bc7086Sdrh for(i=0; i<pOrderBy->nExpr; i++){ 497d8bc7086Sdrh Expr *pE = pOrderBy->a[i].pExpr; 49892cd52f5Sdrh int match = 0; 499d8bc7086Sdrh if( pOrderBy->a[i].done ) continue; 500d8bc7086Sdrh for(j=0; j<pEList->nExpr; j++){ 5014cfa7934Sdrh if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){ 502*a76b5dfcSdrh char *zName, *zLabel; 503*a76b5dfcSdrh zName = pEList->a[j].zName; 504*a76b5dfcSdrh assert( pE->token.z ); 505*a76b5dfcSdrh zLabel = sqliteStrNDup(pE->token.z, pE->token.n); 506d8bc7086Sdrh sqliteDequote(zLabel); 507d8bc7086Sdrh if( sqliteStrICmp(zName, zLabel)==0 ){ 508d8bc7086Sdrh match = 1; 509d8bc7086Sdrh } 5106e142f54Sdrh sqliteFree(zLabel); 511d8bc7086Sdrh } 5124cfa7934Sdrh if( match==0 && sqliteExprCompare(pE, pEList->a[j].pExpr) ){ 513d8bc7086Sdrh match = 1; 514d8bc7086Sdrh } 515d8bc7086Sdrh if( match ){ 516967e8b73Sdrh pE->op = TK_COLUMN; 517967e8b73Sdrh pE->iColumn = j; 518d8bc7086Sdrh pE->iTable = iTable; 519d8bc7086Sdrh pOrderBy->a[i].done = 1; 520d8bc7086Sdrh break; 521d8bc7086Sdrh } 522d8bc7086Sdrh } 52392cd52f5Sdrh if( !match && mustComplete ){ 524d8bc7086Sdrh char zBuf[30]; 525d8bc7086Sdrh sprintf(zBuf,"%d",i+1); 526d8bc7086Sdrh sqliteSetString(&pParse->zErrMsg, "ORDER BY term number ", zBuf, 527d8bc7086Sdrh " does not match any result column", 0); 528d8bc7086Sdrh pParse->nErr++; 529d8bc7086Sdrh nErr++; 530d8bc7086Sdrh break; 531d8bc7086Sdrh } 532d8bc7086Sdrh } 533d8bc7086Sdrh return nErr; 534d8bc7086Sdrh } 535d8bc7086Sdrh 536d8bc7086Sdrh /* 537d8bc7086Sdrh ** Get a VDBE for the given parser context. Create a new one if necessary. 538d8bc7086Sdrh ** If an error occurs, return NULL and leave a message in pParse. 539d8bc7086Sdrh */ 540d8bc7086Sdrh Vdbe *sqliteGetVdbe(Parse *pParse){ 541d8bc7086Sdrh Vdbe *v = pParse->pVdbe; 542d8bc7086Sdrh if( v==0 ){ 5434c504391Sdrh v = pParse->pVdbe = sqliteVdbeCreate(pParse->db); 544d8bc7086Sdrh } 545d8bc7086Sdrh return v; 546d8bc7086Sdrh } 547d8bc7086Sdrh 548d8bc7086Sdrh 549d8bc7086Sdrh /* 55082c3d636Sdrh ** This routine is called to process a query that is really the union 55182c3d636Sdrh ** or intersection of two or more separate queries. 55282c3d636Sdrh */ 55382c3d636Sdrh static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){ 55410e5e3cfSdrh int rc; /* Success code from a subroutine */ 55510e5e3cfSdrh Select *pPrior; /* Another SELECT immediately to our left */ 55610e5e3cfSdrh Vdbe *v; /* Generate code to this VDBE */ 55710e5e3cfSdrh int base; /* Baseline value for pParse->nTab */ 55882c3d636Sdrh 559d8bc7086Sdrh /* Make sure there is no ORDER BY clause on prior SELECTs. Only the 560d8bc7086Sdrh ** last SELECT in the series may have an ORDER BY. 56182c3d636Sdrh */ 562daffd0e5Sdrh if( p==0 || p->pPrior==0 ) return 1; 563d8bc7086Sdrh pPrior = p->pPrior; 564d8bc7086Sdrh if( pPrior->pOrderBy ){ 565d8bc7086Sdrh sqliteSetString(&pParse->zErrMsg,"ORDER BY clause should come after ", 566d8bc7086Sdrh selectOpName(p->op), " not before", 0); 56782c3d636Sdrh pParse->nErr++; 56882c3d636Sdrh return 1; 56982c3d636Sdrh } 57082c3d636Sdrh 571d8bc7086Sdrh /* Make sure we have a valid query engine. If not, create a new one. 572d8bc7086Sdrh */ 573d8bc7086Sdrh v = sqliteGetVdbe(pParse); 574d8bc7086Sdrh if( v==0 ) return 1; 575d8bc7086Sdrh 576d8bc7086Sdrh /* Process the UNION or INTERSECTION 577d8bc7086Sdrh */ 57810e5e3cfSdrh base = pParse->nTab; 57982c3d636Sdrh switch( p->op ){ 580d8bc7086Sdrh case TK_ALL: 58182c3d636Sdrh case TK_EXCEPT: 58282c3d636Sdrh case TK_UNION: { 583d8bc7086Sdrh int unionTab; /* Cursor number of the temporary table holding result */ 584d8bc7086Sdrh int op; /* One of the SRT_ operations to apply to self */ 585d8bc7086Sdrh int priorOp; /* The SRT_ operation to apply to prior selects */ 58682c3d636Sdrh 587d8bc7086Sdrh priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union; 588d8bc7086Sdrh if( eDest==priorOp ){ 589d8bc7086Sdrh /* We can reuse a temporary table generated by a SELECT to our 590d8bc7086Sdrh ** right. This also means we are not the right-most select and so 591d8bc7086Sdrh ** we cannot have an ORDER BY clause 592d8bc7086Sdrh */ 59382c3d636Sdrh unionTab = iParm; 594d8bc7086Sdrh assert( p->pOrderBy==0 ); 59582c3d636Sdrh }else{ 596d8bc7086Sdrh /* We will need to create our own temporary table to hold the 597d8bc7086Sdrh ** intermediate results. 598d8bc7086Sdrh */ 59982c3d636Sdrh unionTab = pParse->nTab++; 600d8bc7086Sdrh if( p->pOrderBy 601d8bc7086Sdrh && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){ 602d8bc7086Sdrh return 1; 603d8bc7086Sdrh } 604d8bc7086Sdrh if( p->op!=TK_ALL ){ 605c6b52df3Sdrh sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 1); 60699fcd718Sdrh sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1); 607345fda3eSdrh }else{ 60899fcd718Sdrh sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0); 60982c3d636Sdrh } 610d8bc7086Sdrh } 611d8bc7086Sdrh 612d8bc7086Sdrh /* Code the SELECT statements to our left 613d8bc7086Sdrh */ 614d8bc7086Sdrh rc = sqliteSelect(pParse, pPrior, priorOp, unionTab); 61582c3d636Sdrh if( rc ) return rc; 616d8bc7086Sdrh 617d8bc7086Sdrh /* Code the current SELECT statement 618d8bc7086Sdrh */ 619d8bc7086Sdrh switch( p->op ){ 620d8bc7086Sdrh case TK_EXCEPT: op = SRT_Except; break; 621d8bc7086Sdrh case TK_UNION: op = SRT_Union; break; 622d8bc7086Sdrh case TK_ALL: op = SRT_Table; break; 623d8bc7086Sdrh } 62482c3d636Sdrh p->pPrior = 0; 62582c3d636Sdrh rc = sqliteSelect(pParse, p, op, unionTab); 62682c3d636Sdrh p->pPrior = pPrior; 62782c3d636Sdrh if( rc ) return rc; 628d8bc7086Sdrh 629d8bc7086Sdrh /* Convert the data in the temporary table into whatever form 630d8bc7086Sdrh ** it is that we currently need. 631d8bc7086Sdrh */ 632d8bc7086Sdrh if( eDest!=priorOp ){ 6336b56344dSdrh int iCont, iBreak, iStart; 63482c3d636Sdrh assert( p->pEList ); 635d8bc7086Sdrh generateColumnNames(pParse, 0, p->pEList); 63682c3d636Sdrh iBreak = sqliteVdbeMakeLabel(v); 6376b56344dSdrh iCont = sqliteVdbeMakeLabel(v); 6386b56344dSdrh sqliteVdbeAddOp(v, OP_Rewind, unionTab, iBreak); 6396b56344dSdrh iStart = sqliteVdbeCurrentAddr(v); 64082c3d636Sdrh rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr, 641d8bc7086Sdrh p->pOrderBy, -1, eDest, iParm, 64282c3d636Sdrh iCont, iBreak); 64382c3d636Sdrh if( rc ) return 1; 6446b56344dSdrh sqliteVdbeResolveLabel(v, iCont); 6456b56344dSdrh sqliteVdbeAddOp(v, OP_Next, unionTab, iStart); 64699fcd718Sdrh sqliteVdbeResolveLabel(v, iBreak); 64799fcd718Sdrh sqliteVdbeAddOp(v, OP_Close, unionTab, 0); 648d8bc7086Sdrh if( p->pOrderBy ){ 649d8bc7086Sdrh generateSortTail(v, p->pEList->nExpr); 650d8bc7086Sdrh } 65182c3d636Sdrh } 65282c3d636Sdrh break; 65382c3d636Sdrh } 65482c3d636Sdrh case TK_INTERSECT: { 65582c3d636Sdrh int tab1, tab2; 6566b56344dSdrh int iCont, iBreak, iStart; 65782c3d636Sdrh 658d8bc7086Sdrh /* INTERSECT is different from the others since it requires 6596206d50aSdrh ** two temporary tables. Hence it has its own case. Begin 660d8bc7086Sdrh ** by allocating the tables we will need. 661d8bc7086Sdrh */ 66282c3d636Sdrh tab1 = pParse->nTab++; 66382c3d636Sdrh tab2 = pParse->nTab++; 664d8bc7086Sdrh if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){ 665d8bc7086Sdrh return 1; 666d8bc7086Sdrh } 667c6b52df3Sdrh sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 1); 66899fcd718Sdrh sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1); 669d8bc7086Sdrh 670d8bc7086Sdrh /* Code the SELECTs to our left into temporary table "tab1". 671d8bc7086Sdrh */ 67282c3d636Sdrh rc = sqliteSelect(pParse, pPrior, SRT_Union, tab1); 67382c3d636Sdrh if( rc ) return rc; 674d8bc7086Sdrh 675d8bc7086Sdrh /* Code the current SELECT into temporary table "tab2" 676d8bc7086Sdrh */ 677c6b52df3Sdrh sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 1); 67899fcd718Sdrh sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1); 67982c3d636Sdrh p->pPrior = 0; 68082c3d636Sdrh rc = sqliteSelect(pParse, p, SRT_Union, tab2); 68182c3d636Sdrh p->pPrior = pPrior; 68282c3d636Sdrh if( rc ) return rc; 683d8bc7086Sdrh 684d8bc7086Sdrh /* Generate code to take the intersection of the two temporary 685d8bc7086Sdrh ** tables. 686d8bc7086Sdrh */ 68782c3d636Sdrh assert( p->pEList ); 688d8bc7086Sdrh generateColumnNames(pParse, 0, p->pEList); 68982c3d636Sdrh iBreak = sqliteVdbeMakeLabel(v); 6906b56344dSdrh iCont = sqliteVdbeMakeLabel(v); 6916b56344dSdrh sqliteVdbeAddOp(v, OP_Rewind, tab1, iBreak); 6926b56344dSdrh iStart = sqliteVdbeAddOp(v, OP_FullKey, tab1, 0); 69399fcd718Sdrh sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont); 69482c3d636Sdrh rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr, 695d8bc7086Sdrh p->pOrderBy, -1, eDest, iParm, 69682c3d636Sdrh iCont, iBreak); 69782c3d636Sdrh if( rc ) return 1; 6986b56344dSdrh sqliteVdbeResolveLabel(v, iCont); 6996b56344dSdrh sqliteVdbeAddOp(v, OP_Next, tab1, iStart); 70099fcd718Sdrh sqliteVdbeResolveLabel(v, iBreak); 70199fcd718Sdrh sqliteVdbeAddOp(v, OP_Close, tab2, 0); 70299fcd718Sdrh sqliteVdbeAddOp(v, OP_Close, tab1, 0); 703d8bc7086Sdrh if( p->pOrderBy ){ 704d8bc7086Sdrh generateSortTail(v, p->pEList->nExpr); 705d8bc7086Sdrh } 70682c3d636Sdrh break; 70782c3d636Sdrh } 70882c3d636Sdrh } 70982c3d636Sdrh assert( p->pEList && pPrior->pEList ); 71082c3d636Sdrh if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ 711d8bc7086Sdrh sqliteSetString(&pParse->zErrMsg, "SELECTs to the left and right of ", 712d8bc7086Sdrh selectOpName(p->op), " do not have the same number of result columns", 0); 71382c3d636Sdrh pParse->nErr++; 71482c3d636Sdrh return 1; 7152282792aSdrh } 71610e5e3cfSdrh pParse->nTab = base; 7172282792aSdrh return 0; 7182282792aSdrh } 7192282792aSdrh 7202282792aSdrh /* 7219562b551Sdrh ** Analyze the SELECT statement passed in as an argument to see if it 7229562b551Sdrh ** is a simple min() or max() query. If it is and this query can be 7239562b551Sdrh ** satisfied using a single seek to the beginning or end of an index, 7249562b551Sdrh ** then generate the code for this SELECT return 1. If this is not a 7259562b551Sdrh ** simple min() or max() query, then return 0; 7269562b551Sdrh ** 7279562b551Sdrh ** A simply min() or max() query looks like this: 7289562b551Sdrh ** 7299562b551Sdrh ** SELECT min(a) FROM table; 7309562b551Sdrh ** SELECT max(a) FROM table; 7319562b551Sdrh ** 7329562b551Sdrh ** The query may have only a single table in its FROM argument. There 7339562b551Sdrh ** can be no GROUP BY or HAVING or WHERE clauses. The result set must 7349562b551Sdrh ** be the min() or max() of a single column of the table. The column 7359562b551Sdrh ** in the min() or max() function must be indexed. 7369562b551Sdrh ** 7379562b551Sdrh ** The parameters to this routine are the same as for sqliteSelect(). 7389562b551Sdrh ** See the header comment on that routine for additional information. 7399562b551Sdrh */ 7409562b551Sdrh static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ 7419562b551Sdrh Expr *pExpr; 7429562b551Sdrh int iCol; 7439562b551Sdrh Table *pTab; 7449562b551Sdrh Index *pIdx; 7459562b551Sdrh int base; 7469562b551Sdrh Vdbe *v; 7479562b551Sdrh int openOp; 7489562b551Sdrh int seekOp; 7499562b551Sdrh int cont; 7509562b551Sdrh ExprList eList; 7519562b551Sdrh struct ExprList_item eListItem; 7529562b551Sdrh 7539562b551Sdrh /* Check to see if this query is a simple min() or max() query. Return 7549562b551Sdrh ** zero if it is not. 7559562b551Sdrh */ 7569562b551Sdrh if( p->pGroupBy || p->pHaving || p->pWhere ) return 0; 7579562b551Sdrh if( p->pSrc->nId!=1 ) return 0; 7589562b551Sdrh if( p->pEList->nExpr!=1 ) return 0; 7599562b551Sdrh pExpr = p->pEList->a[0].pExpr; 7609562b551Sdrh if( pExpr->op!=TK_AGG_FUNCTION ) return 0; 7619562b551Sdrh if( pExpr->pList==0 || pExpr->pList->nExpr!=1 ) return 0; 7629562b551Sdrh if( pExpr->iColumn!=FN_Min && pExpr->iColumn!=FN_Max ) return 0; 7639562b551Sdrh seekOp = pExpr->iColumn==FN_Min ? OP_Rewind : OP_Last; 7649562b551Sdrh pExpr = pExpr->pList->a[0].pExpr; 7659562b551Sdrh if( pExpr->op!=TK_COLUMN ) return 0; 7669562b551Sdrh iCol = pExpr->iColumn; 7679562b551Sdrh pTab = p->pSrc->a[0].pTab; 7689562b551Sdrh 7699562b551Sdrh /* If we get to here, it means the query is of the correct form. 77017f71934Sdrh ** Check to make sure we have an index and make pIdx point to the 77117f71934Sdrh ** appropriate index. If the min() or max() is on an INTEGER PRIMARY 77217f71934Sdrh ** key column, no index is necessary so set pIdx to NULL. If no 77317f71934Sdrh ** usable index is found, return 0. 7749562b551Sdrh */ 7759562b551Sdrh if( iCol<0 ){ 7769562b551Sdrh pIdx = 0; 7779562b551Sdrh }else{ 7789562b551Sdrh for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ 7799562b551Sdrh assert( pIdx->nColumn>=1 ); 7809562b551Sdrh if( pIdx->aiColumn[0]==iCol ) break; 7819562b551Sdrh } 7829562b551Sdrh if( pIdx==0 ) return 0; 7839562b551Sdrh } 7849562b551Sdrh 78517f71934Sdrh /* Identify column names if we will be using the callback. This 7869562b551Sdrh ** step is skipped if the output is going to a table or a memory cell. 7879562b551Sdrh */ 7889562b551Sdrh v = sqliteGetVdbe(pParse); 7899562b551Sdrh if( v==0 ) return 0; 7909562b551Sdrh if( eDest==SRT_Callback ){ 7919562b551Sdrh generateColumnNames(pParse, p->pSrc, p->pEList); 7929562b551Sdrh } 7939562b551Sdrh 79417f71934Sdrh /* Generating code to find the min or the max. Basically all we have 79517f71934Sdrh ** to do is find the first or the last entry in the chosen index. If 79617f71934Sdrh ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first 79717f71934Sdrh ** or last entry in the main table. 7989562b551Sdrh */ 7995cf8e8c7Sdrh if( !pParse->schemaVerified && (pParse->db->flags & SQLITE_InTrans)==0 ){ 8005cf8e8c7Sdrh sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0); 8015cf8e8c7Sdrh pParse->schemaVerified = 1; 8025cf8e8c7Sdrh } 8039562b551Sdrh openOp = pTab->isTemp ? OP_OpenAux : OP_Open; 8045cf8e8c7Sdrh base = pParse->nTab; 8059562b551Sdrh sqliteVdbeAddOp(v, openOp, base, pTab->tnum); 8065cf8e8c7Sdrh sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); 8079562b551Sdrh if( pIdx==0 ){ 8089562b551Sdrh sqliteVdbeAddOp(v, seekOp, base, 0); 8099562b551Sdrh }else{ 8109562b551Sdrh sqliteVdbeAddOp(v, openOp, base+1, pIdx->tnum); 8115cf8e8c7Sdrh sqliteVdbeChangeP3(v, -1, pIdx->zName, P3_STATIC); 8129562b551Sdrh sqliteVdbeAddOp(v, seekOp, base+1, 0); 8139562b551Sdrh sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0); 8149562b551Sdrh sqliteVdbeAddOp(v, OP_Close, base+1, 0); 8159562b551Sdrh sqliteVdbeAddOp(v, OP_MoveTo, base, 0); 8169562b551Sdrh } 8175cf8e8c7Sdrh eList.nExpr = 1; 8185cf8e8c7Sdrh memset(&eListItem, 0, sizeof(eListItem)); 8195cf8e8c7Sdrh eList.a = &eListItem; 8205cf8e8c7Sdrh eList.a[0].pExpr = pExpr; 8219562b551Sdrh cont = sqliteVdbeMakeLabel(v); 8229562b551Sdrh selectInnerLoop(pParse, &eList, base, 1, 0, -1, eDest, iParm, cont, cont); 8239562b551Sdrh sqliteVdbeResolveLabel(v, cont); 8249562b551Sdrh sqliteVdbeAddOp(v, OP_Close, base, 0); 8259562b551Sdrh return 1; 8269562b551Sdrh } 8279562b551Sdrh 8289562b551Sdrh /* 8299bb61fe7Sdrh ** Generate code for the given SELECT statement. 8309bb61fe7Sdrh ** 831fef5208cSdrh ** The results are distributed in various ways depending on the 832fef5208cSdrh ** value of eDest and iParm. 833fef5208cSdrh ** 834fef5208cSdrh ** eDest Value Result 835fef5208cSdrh ** ------------ ------------------------------------------- 836fef5208cSdrh ** SRT_Callback Invoke the callback for each row of the result. 837fef5208cSdrh ** 838fef5208cSdrh ** SRT_Mem Store first result in memory cell iParm 839fef5208cSdrh ** 840fef5208cSdrh ** SRT_Set Store results as keys of a table with cursor iParm 841fef5208cSdrh ** 84282c3d636Sdrh ** SRT_Union Store results as a key in a temporary table iParm 84382c3d636Sdrh ** 844c4a3c779Sdrh ** SRT_Except Remove results form the temporary table iParm. 845c4a3c779Sdrh ** 846c4a3c779Sdrh ** SRT_Table Store results in temporary table iParm 8479bb61fe7Sdrh ** 8489bb61fe7Sdrh ** This routine returns the number of errors. If any errors are 8499bb61fe7Sdrh ** encountered, then an appropriate error message is left in 8509bb61fe7Sdrh ** pParse->zErrMsg. 8519bb61fe7Sdrh ** 8529bb61fe7Sdrh ** This routine does NOT free the Select structure passed in. The 8539bb61fe7Sdrh ** calling function needs to do that. 8549bb61fe7Sdrh */ 8559bb61fe7Sdrh int sqliteSelect( 856cce7d176Sdrh Parse *pParse, /* The parser context */ 8579bb61fe7Sdrh Select *p, /* The SELECT statement being coded. */ 85882c3d636Sdrh int eDest, /* One of: SRT_Callback Mem Set Union Except */ 859fef5208cSdrh int iParm /* Save result in this memory location, if >=0 */ 860cce7d176Sdrh ){ 861d8bc7086Sdrh int i; 862cce7d176Sdrh WhereInfo *pWInfo; 863cce7d176Sdrh Vdbe *v; 864cce7d176Sdrh int isAgg = 0; /* True for select lists like "count(*)" */ 865a2e00042Sdrh ExprList *pEList; /* List of columns to extract. */ 8669bb61fe7Sdrh IdList *pTabList; /* List of tables to select from */ 8679bb61fe7Sdrh Expr *pWhere; /* The WHERE clause. May be NULL */ 8689bb61fe7Sdrh ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ 8692282792aSdrh ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ 8702282792aSdrh Expr *pHaving; /* The HAVING clause. May be NULL */ 87119a775c2Sdrh int isDistinct; /* True if the DISTINCT keyword is present */ 87219a775c2Sdrh int distinct; /* Table to use for the distinct set */ 87310e5e3cfSdrh int base; /* First cursor available for use */ 8741d83f052Sdrh int rc = 1; /* Value to return from this function */ 8759bb61fe7Sdrh 876daffd0e5Sdrh if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1; 877daffd0e5Sdrh 87882c3d636Sdrh /* If there is are a sequence of queries, do the earlier ones first. 87982c3d636Sdrh */ 88082c3d636Sdrh if( p->pPrior ){ 88182c3d636Sdrh return multiSelect(pParse, p, eDest, iParm); 88282c3d636Sdrh } 88382c3d636Sdrh 88482c3d636Sdrh /* Make local copies of the parameters for this query. 88582c3d636Sdrh */ 8869bb61fe7Sdrh pTabList = p->pSrc; 8879bb61fe7Sdrh pWhere = p->pWhere; 8889bb61fe7Sdrh pOrderBy = p->pOrderBy; 8892282792aSdrh pGroupBy = p->pGroupBy; 8902282792aSdrh pHaving = p->pHaving; 89119a775c2Sdrh isDistinct = p->isDistinct; 8929bb61fe7Sdrh 89310e5e3cfSdrh /* Save the current value of pParse->nTab. Restore this value before 89410e5e3cfSdrh ** we exit. 89510e5e3cfSdrh */ 89610e5e3cfSdrh base = pParse->nTab; 89710e5e3cfSdrh 8989bb61fe7Sdrh /* 8999bb61fe7Sdrh ** Do not even attempt to generate any code if we have already seen 9009bb61fe7Sdrh ** errors before this routine starts. 9019bb61fe7Sdrh */ 9021d83f052Sdrh if( pParse->nErr>0 ) goto select_end; 903cce7d176Sdrh 904d8bc7086Sdrh /* Look up every table in the table list and create an appropriate 905d8bc7086Sdrh ** columnlist in pEList if there isn't one already. (The parser leaves 906967e8b73Sdrh ** a NULL in the p->pEList if the SQL said "SELECT * FROM ...") 907cce7d176Sdrh */ 908d8bc7086Sdrh if( fillInColumnList(pParse, p) ){ 9091d83f052Sdrh goto select_end; 910cce7d176Sdrh } 911d8bc7086Sdrh pEList = p->pEList; 9121d83f052Sdrh if( pEList==0 ) goto select_end; 913cce7d176Sdrh 91419a775c2Sdrh /* Allocate a temporary table to use for the DISTINCT set, if 9152282792aSdrh ** necessary. This must be done early to allocate the cursor before 9162282792aSdrh ** any calls to sqliteExprResolveIds(). 91719a775c2Sdrh */ 91819a775c2Sdrh if( isDistinct ){ 91919a775c2Sdrh distinct = pParse->nTab++; 9202282792aSdrh }else{ 9212282792aSdrh distinct = -1; 92219a775c2Sdrh } 92319a775c2Sdrh 9242282792aSdrh /* If writing to memory or generating a set 9252282792aSdrh ** only a single column may be output. 92619a775c2Sdrh */ 927fef5208cSdrh if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){ 92819a775c2Sdrh sqliteSetString(&pParse->zErrMsg, "only a single result allowed for " 92919a775c2Sdrh "a SELECT that is part of an expression", 0); 93019a775c2Sdrh pParse->nErr++; 9311d83f052Sdrh goto select_end; 93219a775c2Sdrh } 93319a775c2Sdrh 9342282792aSdrh /* ORDER BY is ignored if we are not sending the result to a callback. 9352282792aSdrh */ 9362282792aSdrh if( eDest!=SRT_Callback ){ 9372282792aSdrh pOrderBy = 0; 9382282792aSdrh } 9392282792aSdrh 9402282792aSdrh /* Allocate cursors for "expr IN (SELECT ...)" constructs. 941cce7d176Sdrh */ 942cce7d176Sdrh for(i=0; i<pEList->nExpr; i++){ 9434794b980Sdrh sqliteExprResolveInSelect(pParse, pEList->a[i].pExpr); 9444794b980Sdrh } 9454794b980Sdrh if( pWhere ) sqliteExprResolveInSelect(pParse, pWhere); 9464794b980Sdrh if( pOrderBy ){ 9474794b980Sdrh for(i=0; i<pOrderBy->nExpr; i++){ 9484794b980Sdrh sqliteExprResolveInSelect(pParse, pOrderBy->a[i].pExpr); 9494794b980Sdrh } 9504794b980Sdrh } 9512282792aSdrh if( pGroupBy ){ 9522282792aSdrh for(i=0; i<pGroupBy->nExpr; i++){ 9532282792aSdrh sqliteExprResolveInSelect(pParse, pGroupBy->a[i].pExpr); 9542282792aSdrh } 9552282792aSdrh } 9562282792aSdrh if( pHaving ) sqliteExprResolveInSelect(pParse, pHaving); 9572282792aSdrh 95810e5e3cfSdrh /* At this point, we should have allocated all the cursors that we 95910e5e3cfSdrh ** need to handle subquerys and temporary tables. From here on we 96010e5e3cfSdrh ** are committed to keeping the same value for pParse->nTab. 96110e5e3cfSdrh ** 962967e8b73Sdrh ** Resolve the column names and do a semantics check on all the expressions. 9632282792aSdrh */ 9644794b980Sdrh for(i=0; i<pEList->nExpr; i++){ 965a2e00042Sdrh if( sqliteExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){ 9661d83f052Sdrh goto select_end; 967cce7d176Sdrh } 9682282792aSdrh if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){ 9691d83f052Sdrh goto select_end; 970cce7d176Sdrh } 971cce7d176Sdrh } 972cce7d176Sdrh if( pWhere ){ 973a2e00042Sdrh if( sqliteExprResolveIds(pParse, pTabList, pEList, pWhere) ){ 9741d83f052Sdrh goto select_end; 975cce7d176Sdrh } 976cce7d176Sdrh if( sqliteExprCheck(pParse, pWhere, 0, 0) ){ 9771d83f052Sdrh goto select_end; 978cce7d176Sdrh } 979cce7d176Sdrh } 980cce7d176Sdrh if( pOrderBy ){ 981cce7d176Sdrh for(i=0; i<pOrderBy->nExpr; i++){ 9822282792aSdrh Expr *pE = pOrderBy->a[i].pExpr; 9839208643dSdrh if( sqliteExprIsConstant(pE) ){ 9849208643dSdrh sqliteSetString(&pParse->zErrMsg, 9859208643dSdrh "ORDER BY expressions should not be constant", 0); 9869208643dSdrh pParse->nErr++; 9871d83f052Sdrh goto select_end; 9889208643dSdrh } 989a2e00042Sdrh if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){ 9901d83f052Sdrh goto select_end; 991cce7d176Sdrh } 9922282792aSdrh if( sqliteExprCheck(pParse, pE, isAgg, 0) ){ 9931d83f052Sdrh goto select_end; 994cce7d176Sdrh } 995cce7d176Sdrh } 996cce7d176Sdrh } 9972282792aSdrh if( pGroupBy ){ 9982282792aSdrh for(i=0; i<pGroupBy->nExpr; i++){ 9992282792aSdrh Expr *pE = pGroupBy->a[i].pExpr; 10009208643dSdrh if( sqliteExprIsConstant(pE) ){ 10019208643dSdrh sqliteSetString(&pParse->zErrMsg, 10029208643dSdrh "GROUP BY expressions should not be constant", 0); 10039208643dSdrh pParse->nErr++; 10041d83f052Sdrh goto select_end; 10059208643dSdrh } 1006a2e00042Sdrh if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){ 10071d83f052Sdrh goto select_end; 10082282792aSdrh } 10092282792aSdrh if( sqliteExprCheck(pParse, pE, isAgg, 0) ){ 10101d83f052Sdrh goto select_end; 10112282792aSdrh } 10122282792aSdrh } 10132282792aSdrh } 10142282792aSdrh if( pHaving ){ 10152282792aSdrh if( pGroupBy==0 ){ 1016da93281eSdrh sqliteSetString(&pParse->zErrMsg, "a GROUP BY clause is required " 1017da93281eSdrh "before HAVING", 0); 10182282792aSdrh pParse->nErr++; 10191d83f052Sdrh goto select_end; 10202282792aSdrh } 1021a2e00042Sdrh if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){ 10221d83f052Sdrh goto select_end; 10232282792aSdrh } 1024da93281eSdrh if( sqliteExprCheck(pParse, pHaving, isAgg, 0) ){ 10251d83f052Sdrh goto select_end; 10262282792aSdrh } 1027cce7d176Sdrh } 1028cce7d176Sdrh 10299562b551Sdrh /* Check for the special case of a min() or max() function by itself 10309562b551Sdrh ** in the result set. 10319562b551Sdrh */ 10329562b551Sdrh if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){ 10335cf8e8c7Sdrh rc = 0; 10349562b551Sdrh goto select_end; 10359562b551Sdrh } 10369562b551Sdrh 1037d820cb1bSdrh /* Begin generating code. 1038d820cb1bSdrh */ 1039d820cb1bSdrh v = sqliteGetVdbe(pParse); 1040d820cb1bSdrh if( v==0 ) goto select_end; 1041d820cb1bSdrh 1042d820cb1bSdrh /* Generate code for all sub-queries in the FROM clause 1043d820cb1bSdrh */ 1044d820cb1bSdrh for(i=0; i<pTabList->nId; i++){ 1045d820cb1bSdrh int oldNTab; 1046*a76b5dfcSdrh if( pTabList->a[i].pSelect==0 ) continue; 1047d820cb1bSdrh oldNTab = pParse->nTab; 1048d820cb1bSdrh pParse->nTab += i+1; 1049d820cb1bSdrh sqliteVdbeAddOp(v, OP_OpenTemp, oldNTab+i, 0); 1050d820cb1bSdrh sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_Table, oldNTab+i); 1051d820cb1bSdrh pParse->nTab = oldNTab; 1052d820cb1bSdrh } 1053d820cb1bSdrh 10542282792aSdrh /* Do an analysis of aggregate expressions. 1055efb7251dSdrh */ 1056d820cb1bSdrh sqliteAggregateInfoReset(pParse); 10572282792aSdrh if( isAgg ){ 1058aaf88729Sdrh assert( pParse->nAgg==0 && pParse->iAggCount<0 ); 10592282792aSdrh for(i=0; i<pEList->nExpr; i++){ 10602282792aSdrh if( sqliteExprAnalyzeAggregates(pParse, pEList->a[i].pExpr) ){ 10611d83f052Sdrh goto select_end; 10622282792aSdrh } 10632282792aSdrh } 10642282792aSdrh if( pGroupBy ){ 10652282792aSdrh for(i=0; i<pGroupBy->nExpr; i++){ 10662282792aSdrh if( sqliteExprAnalyzeAggregates(pParse, pGroupBy->a[i].pExpr) ){ 10671d83f052Sdrh goto select_end; 10682282792aSdrh } 10692282792aSdrh } 10702282792aSdrh } 10712282792aSdrh if( pHaving && sqliteExprAnalyzeAggregates(pParse, pHaving) ){ 10721d83f052Sdrh goto select_end; 10732282792aSdrh } 1074191b690eSdrh if( pOrderBy ){ 1075191b690eSdrh for(i=0; i<pOrderBy->nExpr; i++){ 1076191b690eSdrh if( sqliteExprAnalyzeAggregates(pParse, pOrderBy->a[i].pExpr) ){ 10771d83f052Sdrh goto select_end; 1078191b690eSdrh } 1079191b690eSdrh } 1080191b690eSdrh } 1081efb7251dSdrh } 1082efb7251dSdrh 10839bbca4c1Sdrh /* Set the limiter 10849bbca4c1Sdrh */ 10859bbca4c1Sdrh if( p->nLimit<=0 ){ 10869bbca4c1Sdrh p->nOffset = 0; 10879bbca4c1Sdrh }else{ 10889bbca4c1Sdrh if( p->nOffset<0 ) p->nOffset = 0; 10899bbca4c1Sdrh sqliteVdbeAddOp(v, OP_Limit, p->nLimit, p->nOffset); 10909bbca4c1Sdrh } 10919bbca4c1Sdrh 10929bbca4c1Sdrh 10932282792aSdrh /* Identify column names if we will be using in the callback. This 109419a775c2Sdrh ** step is skipped if the output is going to a table or a memory cell. 1095cce7d176Sdrh */ 1096fef5208cSdrh if( eDest==SRT_Callback ){ 1097d8bc7086Sdrh generateColumnNames(pParse, pTabList, pEList); 1098cce7d176Sdrh } 1099cce7d176Sdrh 11002282792aSdrh /* Reset the aggregator 1101cce7d176Sdrh */ 1102cce7d176Sdrh if( isAgg ){ 110399fcd718Sdrh sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg); 11041bee3d7bSdrh if( pGroupBy==0 ){ 11051bee3d7bSdrh sqliteVdbeAddOp(v, OP_String, 0, 0); 11061bee3d7bSdrh sqliteVdbeAddOp(v, OP_AggFocus, 0, 0); 11071bee3d7bSdrh for(i=0; i<pParse->nAgg; i++){ 11081bee3d7bSdrh Expr *pE; 11091bee3d7bSdrh if( !pParse->aAgg[i].isAgg ) continue; 11101bee3d7bSdrh pE = pParse->aAgg[i].pExpr; 11111bee3d7bSdrh assert( pE==0 || pE->op==TK_AGG_FUNCTION ); 11121bee3d7bSdrh assert( pE==0 || (pE->pList!=0 && pE->pList->nExpr==1) ); 11131bee3d7bSdrh if( pE==0 || pE->iColumn==FN_Sum ){ 11141bee3d7bSdrh sqliteVdbeAddOp(v, OP_Integer, 0, 0); 11151bee3d7bSdrh sqliteVdbeAddOp(v, OP_AggSet, 0, i); 11161bee3d7bSdrh continue; 11171bee3d7bSdrh } 11181bee3d7bSdrh } 11191bee3d7bSdrh } 1120cce7d176Sdrh } 1121cce7d176Sdrh 112219a775c2Sdrh /* Initialize the memory cell to NULL 112319a775c2Sdrh */ 1124fef5208cSdrh if( eDest==SRT_Mem ){ 112599fcd718Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0); 11268721ce4aSdrh sqliteVdbeAddOp(v, OP_MemStore, iParm, 1); 112719a775c2Sdrh } 112819a775c2Sdrh 1129cce7d176Sdrh /* Begin the database scan 1130cce7d176Sdrh */ 113119a775c2Sdrh if( isDistinct ){ 1132c6b52df3Sdrh sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 1); 1133efb7251dSdrh } 1134cce7d176Sdrh pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0); 11351d83f052Sdrh if( pWInfo==0 ) goto select_end; 1136cce7d176Sdrh 11372282792aSdrh /* Use the standard inner loop if we are not dealing with 11382282792aSdrh ** aggregates 1139cce7d176Sdrh */ 1140da9d6c45Sdrh if( !isAgg ){ 114182c3d636Sdrh if( selectInnerLoop(pParse, pEList, 0, 0, pOrderBy, distinct, eDest, iParm, 11422282792aSdrh pWInfo->iContinue, pWInfo->iBreak) ){ 11431d83f052Sdrh goto select_end; 1144cce7d176Sdrh } 1145da9d6c45Sdrh } 1146cce7d176Sdrh 11472282792aSdrh /* If we are dealing with aggregates, then to the special aggregate 11482282792aSdrh ** processing. 1149efb7251dSdrh */ 11502282792aSdrh else{ 11512282792aSdrh if( pGroupBy ){ 11521bee3d7bSdrh int lbl1; 11532282792aSdrh for(i=0; i<pGroupBy->nExpr; i++){ 11542282792aSdrh sqliteExprCode(pParse, pGroupBy->a[i].pExpr); 1155efb7251dSdrh } 115699fcd718Sdrh sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0); 11571bee3d7bSdrh lbl1 = sqliteVdbeMakeLabel(v); 115899fcd718Sdrh sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1); 11592282792aSdrh for(i=0; i<pParse->nAgg; i++){ 11602282792aSdrh if( pParse->aAgg[i].isAgg ) continue; 11612282792aSdrh sqliteExprCode(pParse, pParse->aAgg[i].pExpr); 116299fcd718Sdrh sqliteVdbeAddOp(v, OP_AggSet, 0, i); 11632282792aSdrh } 11642282792aSdrh sqliteVdbeResolveLabel(v, lbl1); 11652282792aSdrh } 11662282792aSdrh for(i=0; i<pParse->nAgg; i++){ 11672282792aSdrh Expr *pE; 11682282792aSdrh int op; 11692282792aSdrh if( !pParse->aAgg[i].isAgg ) continue; 11702282792aSdrh pE = pParse->aAgg[i].pExpr; 11712282792aSdrh if( pE==0 ){ 117299fcd718Sdrh sqliteVdbeAddOp(v, OP_AggIncr, 1, i); 11732282792aSdrh continue; 11742282792aSdrh } 11752282792aSdrh assert( pE->op==TK_AGG_FUNCTION ); 11762282792aSdrh assert( pE->pList!=0 && pE->pList->nExpr==1 ); 11772282792aSdrh sqliteExprCode(pParse, pE->pList->a[0].pExpr); 117899fcd718Sdrh sqliteVdbeAddOp(v, OP_AggGet, 0, i); 1179967e8b73Sdrh switch( pE->iColumn ){ 11802282792aSdrh case FN_Min: op = OP_Min; break; 11812282792aSdrh case FN_Max: op = OP_Max; break; 11822282792aSdrh case FN_Avg: op = OP_Add; break; 11832282792aSdrh case FN_Sum: op = OP_Add; break; 11842282792aSdrh } 118599fcd718Sdrh sqliteVdbeAddOp(v, op, 0, 0); 118699fcd718Sdrh sqliteVdbeAddOp(v, OP_AggSet, 0, i); 11872282792aSdrh } 11882282792aSdrh } 11892282792aSdrh 1190cce7d176Sdrh 1191cce7d176Sdrh /* End the database scan loop. 1192cce7d176Sdrh */ 1193cce7d176Sdrh sqliteWhereEnd(pWInfo); 1194cce7d176Sdrh 11952282792aSdrh /* If we are processing aggregates, we need to set up a second loop 11962282792aSdrh ** over all of the aggregate values and process them. 11972282792aSdrh */ 11982282792aSdrh if( isAgg ){ 11992282792aSdrh int endagg = sqliteVdbeMakeLabel(v); 12002282792aSdrh int startagg; 120199fcd718Sdrh startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg); 12022282792aSdrh pParse->useAgg = 1; 12032282792aSdrh if( pHaving ){ 12042282792aSdrh sqliteExprIfFalse(pParse, pHaving, startagg); 12052282792aSdrh } 120682c3d636Sdrh if( selectInnerLoop(pParse, pEList, 0, 0, pOrderBy, distinct, eDest, iParm, 12072282792aSdrh startagg, endagg) ){ 12081d83f052Sdrh goto select_end; 12092282792aSdrh } 121099fcd718Sdrh sqliteVdbeAddOp(v, OP_Goto, 0, startagg); 121199fcd718Sdrh sqliteVdbeResolveLabel(v, endagg); 121299fcd718Sdrh sqliteVdbeAddOp(v, OP_Noop, 0, 0); 12132282792aSdrh pParse->useAgg = 0; 12142282792aSdrh } 12152282792aSdrh 1216cce7d176Sdrh /* If there is an ORDER BY clause, then we need to sort the results 1217cce7d176Sdrh ** and send them to the callback one by one. 1218cce7d176Sdrh */ 1219cce7d176Sdrh if( pOrderBy ){ 1220d8bc7086Sdrh generateSortTail(v, pEList->nExpr); 1221cce7d176Sdrh } 122210e5e3cfSdrh pParse->nTab = base; 12236a535340Sdrh 12246a535340Sdrh 12256a535340Sdrh /* Issue a null callback if that is what the user wants. 12266a535340Sdrh */ 12276a535340Sdrh if( (pParse->db->flags & SQLITE_NullCallback)!=0 && eDest==SRT_Callback ){ 12286a535340Sdrh sqliteVdbeAddOp(v, OP_NullCallback, pEList->nExpr, 0); 12296a535340Sdrh } 12306a535340Sdrh 12311d83f052Sdrh /* The SELECT was successfully coded. Set the return code to 0 12321d83f052Sdrh ** to indicate no errors. 12331d83f052Sdrh */ 12341d83f052Sdrh rc = 0; 12351d83f052Sdrh 12361d83f052Sdrh /* Control jumps to here if an error is encountered above, or upon 12371d83f052Sdrh ** successful coding of the SELECT. 12381d83f052Sdrh */ 12391d83f052Sdrh select_end: 12401d83f052Sdrh sqliteAggregateInfoReset(pParse); 12411d83f052Sdrh return rc; 1242cce7d176Sdrh } 1243