xref: /illumos-gate/usr/src/lib/libsqlite/src/select.c (revision 55fea89d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate ** 2001 September 15
37c478bd9Sstevel@tonic-gate **
47c478bd9Sstevel@tonic-gate ** The author disclaims copyright to this source code.  In place of
57c478bd9Sstevel@tonic-gate ** a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate **
77c478bd9Sstevel@tonic-gate **    May you do good and not evil.
87c478bd9Sstevel@tonic-gate **    May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate **    May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate **
117c478bd9Sstevel@tonic-gate *************************************************************************
127c478bd9Sstevel@tonic-gate ** This file contains C code routines that are called by the parser
137c478bd9Sstevel@tonic-gate ** to handle SELECT statements in SQLite.
147c478bd9Sstevel@tonic-gate **
157c478bd9Sstevel@tonic-gate ** $Id: select.c,v 1.161.2.4 2004/07/20 01:45:49 drh Exp $
167c478bd9Sstevel@tonic-gate */
177c478bd9Sstevel@tonic-gate #include "sqliteInt.h"
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate /*
207c478bd9Sstevel@tonic-gate ** Allocate a new Select structure and return a pointer to that
217c478bd9Sstevel@tonic-gate ** structure.
227c478bd9Sstevel@tonic-gate */
sqliteSelectNew(ExprList * pEList,SrcList * pSrc,Expr * pWhere,ExprList * pGroupBy,Expr * pHaving,ExprList * pOrderBy,int isDistinct,int nLimit,int nOffset)237c478bd9Sstevel@tonic-gate Select *sqliteSelectNew(
247c478bd9Sstevel@tonic-gate   ExprList *pEList,     /* which columns to include in the result */
257c478bd9Sstevel@tonic-gate   SrcList *pSrc,        /* the FROM clause -- which tables to scan */
267c478bd9Sstevel@tonic-gate   Expr *pWhere,         /* the WHERE clause */
277c478bd9Sstevel@tonic-gate   ExprList *pGroupBy,   /* the GROUP BY clause */
287c478bd9Sstevel@tonic-gate   Expr *pHaving,        /* the HAVING clause */
297c478bd9Sstevel@tonic-gate   ExprList *pOrderBy,   /* the ORDER BY clause */
307c478bd9Sstevel@tonic-gate   int isDistinct,       /* true if the DISTINCT keyword is present */
317c478bd9Sstevel@tonic-gate   int nLimit,           /* LIMIT value.  -1 means not used */
327c478bd9Sstevel@tonic-gate   int nOffset           /* OFFSET value.  0 means no offset */
337c478bd9Sstevel@tonic-gate ){
347c478bd9Sstevel@tonic-gate   Select *pNew;
357c478bd9Sstevel@tonic-gate   pNew = sqliteMalloc( sizeof(*pNew) );
367c478bd9Sstevel@tonic-gate   if( pNew==0 ){
377c478bd9Sstevel@tonic-gate     sqliteExprListDelete(pEList);
387c478bd9Sstevel@tonic-gate     sqliteSrcListDelete(pSrc);
397c478bd9Sstevel@tonic-gate     sqliteExprDelete(pWhere);
407c478bd9Sstevel@tonic-gate     sqliteExprListDelete(pGroupBy);
417c478bd9Sstevel@tonic-gate     sqliteExprDelete(pHaving);
427c478bd9Sstevel@tonic-gate     sqliteExprListDelete(pOrderBy);
437c478bd9Sstevel@tonic-gate   }else{
447c478bd9Sstevel@tonic-gate     if( pEList==0 ){
457c478bd9Sstevel@tonic-gate       pEList = sqliteExprListAppend(0, sqliteExpr(TK_ALL,0,0,0), 0);
467c478bd9Sstevel@tonic-gate     }
477c478bd9Sstevel@tonic-gate     pNew->pEList = pEList;
487c478bd9Sstevel@tonic-gate     pNew->pSrc = pSrc;
497c478bd9Sstevel@tonic-gate     pNew->pWhere = pWhere;
507c478bd9Sstevel@tonic-gate     pNew->pGroupBy = pGroupBy;
517c478bd9Sstevel@tonic-gate     pNew->pHaving = pHaving;
527c478bd9Sstevel@tonic-gate     pNew->pOrderBy = pOrderBy;
537c478bd9Sstevel@tonic-gate     pNew->isDistinct = isDistinct;
547c478bd9Sstevel@tonic-gate     pNew->op = TK_SELECT;
557c478bd9Sstevel@tonic-gate     pNew->nLimit = nLimit;
567c478bd9Sstevel@tonic-gate     pNew->nOffset = nOffset;
577c478bd9Sstevel@tonic-gate     pNew->iLimit = -1;
587c478bd9Sstevel@tonic-gate     pNew->iOffset = -1;
597c478bd9Sstevel@tonic-gate   }
607c478bd9Sstevel@tonic-gate   return pNew;
617c478bd9Sstevel@tonic-gate }
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /*
647c478bd9Sstevel@tonic-gate ** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
657c478bd9Sstevel@tonic-gate ** type of join.  Return an integer constant that expresses that type
667c478bd9Sstevel@tonic-gate ** in terms of the following bit values:
677c478bd9Sstevel@tonic-gate **
687c478bd9Sstevel@tonic-gate **     JT_INNER
697c478bd9Sstevel@tonic-gate **     JT_OUTER
707c478bd9Sstevel@tonic-gate **     JT_NATURAL
717c478bd9Sstevel@tonic-gate **     JT_LEFT
727c478bd9Sstevel@tonic-gate **     JT_RIGHT
737c478bd9Sstevel@tonic-gate **
747c478bd9Sstevel@tonic-gate ** A full outer join is the combination of JT_LEFT and JT_RIGHT.
757c478bd9Sstevel@tonic-gate **
767c478bd9Sstevel@tonic-gate ** If an illegal or unsupported join type is seen, then still return
777c478bd9Sstevel@tonic-gate ** a join type, but put an error in the pParse structure.
787c478bd9Sstevel@tonic-gate */
sqliteJoinType(Parse * pParse,Token * pA,Token * pB,Token * pC)797c478bd9Sstevel@tonic-gate int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
807c478bd9Sstevel@tonic-gate   int jointype = 0;
817c478bd9Sstevel@tonic-gate   Token *apAll[3];
827c478bd9Sstevel@tonic-gate   Token *p;
837c478bd9Sstevel@tonic-gate   static struct {
847c478bd9Sstevel@tonic-gate     const char *zKeyword;
857c478bd9Sstevel@tonic-gate     int nChar;
867c478bd9Sstevel@tonic-gate     int code;
877c478bd9Sstevel@tonic-gate   } keywords[] = {
887c478bd9Sstevel@tonic-gate     { "natural", 7, JT_NATURAL },
897c478bd9Sstevel@tonic-gate     { "left",    4, JT_LEFT|JT_OUTER },
907c478bd9Sstevel@tonic-gate     { "right",   5, JT_RIGHT|JT_OUTER },
917c478bd9Sstevel@tonic-gate     { "full",    4, JT_LEFT|JT_RIGHT|JT_OUTER },
927c478bd9Sstevel@tonic-gate     { "outer",   5, JT_OUTER },
937c478bd9Sstevel@tonic-gate     { "inner",   5, JT_INNER },
947c478bd9Sstevel@tonic-gate     { "cross",   5, JT_INNER },
957c478bd9Sstevel@tonic-gate   };
967c478bd9Sstevel@tonic-gate   int i, j;
977c478bd9Sstevel@tonic-gate   apAll[0] = pA;
987c478bd9Sstevel@tonic-gate   apAll[1] = pB;
997c478bd9Sstevel@tonic-gate   apAll[2] = pC;
1007c478bd9Sstevel@tonic-gate   for(i=0; i<3 && apAll[i]; i++){
1017c478bd9Sstevel@tonic-gate     p = apAll[i];
1027c478bd9Sstevel@tonic-gate     for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
103*55fea89dSDan Cross       if( p->n==keywords[j].nChar
1047c478bd9Sstevel@tonic-gate           && sqliteStrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
1057c478bd9Sstevel@tonic-gate         jointype |= keywords[j].code;
1067c478bd9Sstevel@tonic-gate         break;
1077c478bd9Sstevel@tonic-gate       }
1087c478bd9Sstevel@tonic-gate     }
1097c478bd9Sstevel@tonic-gate     if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
1107c478bd9Sstevel@tonic-gate       jointype |= JT_ERROR;
1117c478bd9Sstevel@tonic-gate       break;
1127c478bd9Sstevel@tonic-gate     }
1137c478bd9Sstevel@tonic-gate   }
1147c478bd9Sstevel@tonic-gate   if(
1157c478bd9Sstevel@tonic-gate      (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
1167c478bd9Sstevel@tonic-gate      (jointype & JT_ERROR)!=0
1177c478bd9Sstevel@tonic-gate   ){
1187c478bd9Sstevel@tonic-gate     static Token dummy = { 0, 0 };
1197c478bd9Sstevel@tonic-gate     char *zSp1 = " ", *zSp2 = " ";
1207c478bd9Sstevel@tonic-gate     if( pB==0 ){ pB = &dummy; zSp1 = 0; }
1217c478bd9Sstevel@tonic-gate     if( pC==0 ){ pC = &dummy; zSp2 = 0; }
1227c478bd9Sstevel@tonic-gate     sqliteSetNString(&pParse->zErrMsg, "unknown or unsupported join type: ", 0,
1237c478bd9Sstevel@tonic-gate        pA->z, pA->n, zSp1, 1, pB->z, pB->n, zSp2, 1, pC->z, pC->n, 0);
1247c478bd9Sstevel@tonic-gate     pParse->nErr++;
1257c478bd9Sstevel@tonic-gate     jointype = JT_INNER;
1267c478bd9Sstevel@tonic-gate   }else if( jointype & JT_RIGHT ){
127*55fea89dSDan Cross     sqliteErrorMsg(pParse,
1287c478bd9Sstevel@tonic-gate       "RIGHT and FULL OUTER JOINs are not currently supported");
1297c478bd9Sstevel@tonic-gate     jointype = JT_INNER;
1307c478bd9Sstevel@tonic-gate   }
1317c478bd9Sstevel@tonic-gate   return jointype;
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate /*
1357c478bd9Sstevel@tonic-gate ** Return the index of a column in a table.  Return -1 if the column
1367c478bd9Sstevel@tonic-gate ** is not contained in the table.
1377c478bd9Sstevel@tonic-gate */
columnIndex(Table * pTab,const char * zCol)1387c478bd9Sstevel@tonic-gate static int columnIndex(Table *pTab, const char *zCol){
1397c478bd9Sstevel@tonic-gate   int i;
1407c478bd9Sstevel@tonic-gate   for(i=0; i<pTab->nCol; i++){
1417c478bd9Sstevel@tonic-gate     if( sqliteStrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
1427c478bd9Sstevel@tonic-gate   }
1437c478bd9Sstevel@tonic-gate   return -1;
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /*
1477c478bd9Sstevel@tonic-gate ** Add a term to the WHERE expression in *ppExpr that requires the
1487c478bd9Sstevel@tonic-gate ** zCol column to be equal in the two tables pTab1 and pTab2.
1497c478bd9Sstevel@tonic-gate */
addWhereTerm(const char * zCol,const Table * pTab1,const Table * pTab2,Expr ** ppExpr)1507c478bd9Sstevel@tonic-gate static void addWhereTerm(
1517c478bd9Sstevel@tonic-gate   const char *zCol,        /* Name of the column */
1527c478bd9Sstevel@tonic-gate   const Table *pTab1,      /* First table */
1537c478bd9Sstevel@tonic-gate   const Table *pTab2,      /* Second table */
1547c478bd9Sstevel@tonic-gate   Expr **ppExpr            /* Add the equality term to this expression */
1557c478bd9Sstevel@tonic-gate ){
1567c478bd9Sstevel@tonic-gate   Token dummy;
1577c478bd9Sstevel@tonic-gate   Expr *pE1a, *pE1b, *pE1c;
1587c478bd9Sstevel@tonic-gate   Expr *pE2a, *pE2b, *pE2c;
1597c478bd9Sstevel@tonic-gate   Expr *pE;
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate   dummy.z = zCol;
1627c478bd9Sstevel@tonic-gate   dummy.n = strlen(zCol);
1637c478bd9Sstevel@tonic-gate   dummy.dyn = 0;
1647c478bd9Sstevel@tonic-gate   pE1a = sqliteExpr(TK_ID, 0, 0, &dummy);
1657c478bd9Sstevel@tonic-gate   pE2a = sqliteExpr(TK_ID, 0, 0, &dummy);
1667c478bd9Sstevel@tonic-gate   dummy.z = pTab1->zName;
1677c478bd9Sstevel@tonic-gate   dummy.n = strlen(dummy.z);
1687c478bd9Sstevel@tonic-gate   pE1b = sqliteExpr(TK_ID, 0, 0, &dummy);
1697c478bd9Sstevel@tonic-gate   dummy.z = pTab2->zName;
1707c478bd9Sstevel@tonic-gate   dummy.n = strlen(dummy.z);
1717c478bd9Sstevel@tonic-gate   pE2b = sqliteExpr(TK_ID, 0, 0, &dummy);
1727c478bd9Sstevel@tonic-gate   pE1c = sqliteExpr(TK_DOT, pE1b, pE1a, 0);
1737c478bd9Sstevel@tonic-gate   pE2c = sqliteExpr(TK_DOT, pE2b, pE2a, 0);
1747c478bd9Sstevel@tonic-gate   pE = sqliteExpr(TK_EQ, pE1c, pE2c, 0);
1757c478bd9Sstevel@tonic-gate   ExprSetProperty(pE, EP_FromJoin);
1767c478bd9Sstevel@tonic-gate   if( *ppExpr ){
1777c478bd9Sstevel@tonic-gate     *ppExpr = sqliteExpr(TK_AND, *ppExpr, pE, 0);
1787c478bd9Sstevel@tonic-gate   }else{
1797c478bd9Sstevel@tonic-gate     *ppExpr = pE;
1807c478bd9Sstevel@tonic-gate   }
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate /*
1847c478bd9Sstevel@tonic-gate ** Set the EP_FromJoin property on all terms of the given expression.
1857c478bd9Sstevel@tonic-gate **
1867c478bd9Sstevel@tonic-gate ** The EP_FromJoin property is used on terms of an expression to tell
1877c478bd9Sstevel@tonic-gate ** the LEFT OUTER JOIN processing logic that this term is part of the
1887c478bd9Sstevel@tonic-gate ** join restriction specified in the ON or USING clause and not a part
1897c478bd9Sstevel@tonic-gate ** of the more general WHERE clause.  These terms are moved over to the
1907c478bd9Sstevel@tonic-gate ** WHERE clause during join processing but we need to remember that they
1917c478bd9Sstevel@tonic-gate ** originated in the ON or USING clause.
1927c478bd9Sstevel@tonic-gate */
setJoinExpr(Expr * p)1937c478bd9Sstevel@tonic-gate static void setJoinExpr(Expr *p){
1947c478bd9Sstevel@tonic-gate   while( p ){
1957c478bd9Sstevel@tonic-gate     ExprSetProperty(p, EP_FromJoin);
1967c478bd9Sstevel@tonic-gate     setJoinExpr(p->pLeft);
1977c478bd9Sstevel@tonic-gate     p = p->pRight;
198*55fea89dSDan Cross   }
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate /*
2027c478bd9Sstevel@tonic-gate ** This routine processes the join information for a SELECT statement.
2037c478bd9Sstevel@tonic-gate ** ON and USING clauses are converted into extra terms of the WHERE clause.
2047c478bd9Sstevel@tonic-gate ** NATURAL joins also create extra WHERE clause terms.
2057c478bd9Sstevel@tonic-gate **
2067c478bd9Sstevel@tonic-gate ** This routine returns the number of errors encountered.
2077c478bd9Sstevel@tonic-gate */
sqliteProcessJoin(Parse * pParse,Select * p)2087c478bd9Sstevel@tonic-gate static int sqliteProcessJoin(Parse *pParse, Select *p){
2097c478bd9Sstevel@tonic-gate   SrcList *pSrc;
2107c478bd9Sstevel@tonic-gate   int i, j;
2117c478bd9Sstevel@tonic-gate   pSrc = p->pSrc;
2127c478bd9Sstevel@tonic-gate   for(i=0; i<pSrc->nSrc-1; i++){
2137c478bd9Sstevel@tonic-gate     struct SrcList_item *pTerm = &pSrc->a[i];
2147c478bd9Sstevel@tonic-gate     struct SrcList_item *pOther = &pSrc->a[i+1];
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate     if( pTerm->pTab==0 || pOther->pTab==0 ) continue;
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate     /* When the NATURAL keyword is present, add WHERE clause terms for
2197c478bd9Sstevel@tonic-gate     ** every column that the two tables have in common.
2207c478bd9Sstevel@tonic-gate     */
2217c478bd9Sstevel@tonic-gate     if( pTerm->jointype & JT_NATURAL ){
2227c478bd9Sstevel@tonic-gate       Table *pTab;
2237c478bd9Sstevel@tonic-gate       if( pTerm->pOn || pTerm->pUsing ){
2247c478bd9Sstevel@tonic-gate         sqliteErrorMsg(pParse, "a NATURAL join may not have "
2257c478bd9Sstevel@tonic-gate            "an ON or USING clause", 0);
2267c478bd9Sstevel@tonic-gate         return 1;
2277c478bd9Sstevel@tonic-gate       }
2287c478bd9Sstevel@tonic-gate       pTab = pTerm->pTab;
2297c478bd9Sstevel@tonic-gate       for(j=0; j<pTab->nCol; j++){
2307c478bd9Sstevel@tonic-gate         if( columnIndex(pOther->pTab, pTab->aCol[j].zName)>=0 ){
2317c478bd9Sstevel@tonic-gate           addWhereTerm(pTab->aCol[j].zName, pTab, pOther->pTab, &p->pWhere);
2327c478bd9Sstevel@tonic-gate         }
2337c478bd9Sstevel@tonic-gate       }
2347c478bd9Sstevel@tonic-gate     }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate     /* Disallow both ON and USING clauses in the same join
2377c478bd9Sstevel@tonic-gate     */
2387c478bd9Sstevel@tonic-gate     if( pTerm->pOn && pTerm->pUsing ){
2397c478bd9Sstevel@tonic-gate       sqliteErrorMsg(pParse, "cannot have both ON and USING "
2407c478bd9Sstevel@tonic-gate         "clauses in the same join");
2417c478bd9Sstevel@tonic-gate       return 1;
2427c478bd9Sstevel@tonic-gate     }
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate     /* Add the ON clause to the end of the WHERE clause, connected by
2457c478bd9Sstevel@tonic-gate     ** and AND operator.
2467c478bd9Sstevel@tonic-gate     */
2477c478bd9Sstevel@tonic-gate     if( pTerm->pOn ){
2487c478bd9Sstevel@tonic-gate       setJoinExpr(pTerm->pOn);
2497c478bd9Sstevel@tonic-gate       if( p->pWhere==0 ){
2507c478bd9Sstevel@tonic-gate         p->pWhere = pTerm->pOn;
2517c478bd9Sstevel@tonic-gate       }else{
2527c478bd9Sstevel@tonic-gate         p->pWhere = sqliteExpr(TK_AND, p->pWhere, pTerm->pOn, 0);
2537c478bd9Sstevel@tonic-gate       }
2547c478bd9Sstevel@tonic-gate       pTerm->pOn = 0;
2557c478bd9Sstevel@tonic-gate     }
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate     /* Create extra terms on the WHERE clause for each column named
258*55fea89dSDan Cross     ** in the USING clause.  Example: If the two tables to be joined are
2597c478bd9Sstevel@tonic-gate     ** A and B and the USING clause names X, Y, and Z, then add this
2607c478bd9Sstevel@tonic-gate     ** to the WHERE clause:    A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
2617c478bd9Sstevel@tonic-gate     ** Report an error if any column mentioned in the USING clause is
2627c478bd9Sstevel@tonic-gate     ** not contained in both tables to be joined.
2637c478bd9Sstevel@tonic-gate     */
2647c478bd9Sstevel@tonic-gate     if( pTerm->pUsing ){
2657c478bd9Sstevel@tonic-gate       IdList *pList;
2667c478bd9Sstevel@tonic-gate       int j;
2677c478bd9Sstevel@tonic-gate       assert( i<pSrc->nSrc-1 );
2687c478bd9Sstevel@tonic-gate       pList = pTerm->pUsing;
2697c478bd9Sstevel@tonic-gate       for(j=0; j<pList->nId; j++){
2707c478bd9Sstevel@tonic-gate         if( columnIndex(pTerm->pTab, pList->a[j].zName)<0 ||
2717c478bd9Sstevel@tonic-gate             columnIndex(pOther->pTab, pList->a[j].zName)<0 ){
2727c478bd9Sstevel@tonic-gate           sqliteErrorMsg(pParse, "cannot join using column %s - column "
2737c478bd9Sstevel@tonic-gate             "not present in both tables", pList->a[j].zName);
2747c478bd9Sstevel@tonic-gate           return 1;
2757c478bd9Sstevel@tonic-gate         }
2767c478bd9Sstevel@tonic-gate         addWhereTerm(pList->a[j].zName, pTerm->pTab, pOther->pTab, &p->pWhere);
2777c478bd9Sstevel@tonic-gate       }
2787c478bd9Sstevel@tonic-gate     }
2797c478bd9Sstevel@tonic-gate   }
2807c478bd9Sstevel@tonic-gate   return 0;
2817c478bd9Sstevel@tonic-gate }
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate /*
2847c478bd9Sstevel@tonic-gate ** Delete the given Select structure and all of its substructures.
2857c478bd9Sstevel@tonic-gate */
sqliteSelectDelete(Select * p)2867c478bd9Sstevel@tonic-gate void sqliteSelectDelete(Select *p){
2877c478bd9Sstevel@tonic-gate   if( p==0 ) return;
2887c478bd9Sstevel@tonic-gate   sqliteExprListDelete(p->pEList);
2897c478bd9Sstevel@tonic-gate   sqliteSrcListDelete(p->pSrc);
2907c478bd9Sstevel@tonic-gate   sqliteExprDelete(p->pWhere);
2917c478bd9Sstevel@tonic-gate   sqliteExprListDelete(p->pGroupBy);
2927c478bd9Sstevel@tonic-gate   sqliteExprDelete(p->pHaving);
2937c478bd9Sstevel@tonic-gate   sqliteExprListDelete(p->pOrderBy);
2947c478bd9Sstevel@tonic-gate   sqliteSelectDelete(p->pPrior);
2957c478bd9Sstevel@tonic-gate   sqliteFree(p->zSelect);
2967c478bd9Sstevel@tonic-gate   sqliteFree(p);
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate /*
3007c478bd9Sstevel@tonic-gate ** Delete the aggregate information from the parse structure.
3017c478bd9Sstevel@tonic-gate */
sqliteAggregateInfoReset(Parse * pParse)3027c478bd9Sstevel@tonic-gate static void sqliteAggregateInfoReset(Parse *pParse){
3037c478bd9Sstevel@tonic-gate   sqliteFree(pParse->aAgg);
3047c478bd9Sstevel@tonic-gate   pParse->aAgg = 0;
3057c478bd9Sstevel@tonic-gate   pParse->nAgg = 0;
3067c478bd9Sstevel@tonic-gate   pParse->useAgg = 0;
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate /*
3107c478bd9Sstevel@tonic-gate ** Insert code into "v" that will push the record on the top of the
3117c478bd9Sstevel@tonic-gate ** stack into the sorter.
3127c478bd9Sstevel@tonic-gate */
pushOntoSorter(Parse * pParse,Vdbe * v,ExprList * pOrderBy)3137c478bd9Sstevel@tonic-gate static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
3147c478bd9Sstevel@tonic-gate   char *zSortOrder;
3157c478bd9Sstevel@tonic-gate   int i;
3167c478bd9Sstevel@tonic-gate   zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
3177c478bd9Sstevel@tonic-gate   if( zSortOrder==0 ) return;
3187c478bd9Sstevel@tonic-gate   for(i=0; i<pOrderBy->nExpr; i++){
3197c478bd9Sstevel@tonic-gate     int order = pOrderBy->a[i].sortOrder;
3207c478bd9Sstevel@tonic-gate     int type;
3217c478bd9Sstevel@tonic-gate     int c;
3227c478bd9Sstevel@tonic-gate     if( (order & SQLITE_SO_TYPEMASK)==SQLITE_SO_TEXT ){
3237c478bd9Sstevel@tonic-gate       type = SQLITE_SO_TEXT;
3247c478bd9Sstevel@tonic-gate     }else if( (order & SQLITE_SO_TYPEMASK)==SQLITE_SO_NUM ){
3257c478bd9Sstevel@tonic-gate       type = SQLITE_SO_NUM;
3267c478bd9Sstevel@tonic-gate     }else if( pParse->db->file_format>=4 ){
3277c478bd9Sstevel@tonic-gate       type = sqliteExprType(pOrderBy->a[i].pExpr);
3287c478bd9Sstevel@tonic-gate     }else{
3297c478bd9Sstevel@tonic-gate       type = SQLITE_SO_NUM;
3307c478bd9Sstevel@tonic-gate     }
3317c478bd9Sstevel@tonic-gate     if( (order & SQLITE_SO_DIRMASK)==SQLITE_SO_ASC ){
3327c478bd9Sstevel@tonic-gate       c = type==SQLITE_SO_TEXT ? 'A' : '+';
3337c478bd9Sstevel@tonic-gate     }else{
3347c478bd9Sstevel@tonic-gate       c = type==SQLITE_SO_TEXT ? 'D' : '-';
3357c478bd9Sstevel@tonic-gate     }
3367c478bd9Sstevel@tonic-gate     zSortOrder[i] = c;
3377c478bd9Sstevel@tonic-gate     sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
3387c478bd9Sstevel@tonic-gate   }
3397c478bd9Sstevel@tonic-gate   zSortOrder[pOrderBy->nExpr] = 0;
3407c478bd9Sstevel@tonic-gate   sqliteVdbeOp3(v, OP_SortMakeKey, pOrderBy->nExpr, 0, zSortOrder, P3_DYNAMIC);
3417c478bd9Sstevel@tonic-gate   sqliteVdbeAddOp(v, OP_SortPut, 0, 0);
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate /*
3457c478bd9Sstevel@tonic-gate ** This routine adds a P3 argument to the last VDBE opcode that was
346*55fea89dSDan Cross ** inserted. The P3 argument added is a string suitable for the
3477c478bd9Sstevel@tonic-gate ** OP_MakeKey or OP_MakeIdxKey opcodes.  The string consists of
3487c478bd9Sstevel@tonic-gate ** characters 't' or 'n' depending on whether or not the various
3497c478bd9Sstevel@tonic-gate ** fields of the key to be generated should be treated as numeric
3507c478bd9Sstevel@tonic-gate ** or as text.  See the OP_MakeKey and OP_MakeIdxKey opcode
3517c478bd9Sstevel@tonic-gate ** documentation for additional information about the P3 string.
3527c478bd9Sstevel@tonic-gate ** See also the sqliteAddIdxKeyType() routine.
3537c478bd9Sstevel@tonic-gate */
sqliteAddKeyType(Vdbe * v,ExprList * pEList)3547c478bd9Sstevel@tonic-gate void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
3557c478bd9Sstevel@tonic-gate   int nColumn = pEList->nExpr;
3567c478bd9Sstevel@tonic-gate   char *zType = sqliteMalloc( nColumn+1 );
3577c478bd9Sstevel@tonic-gate   int i;
3587c478bd9Sstevel@tonic-gate   if( zType==0 ) return;
3597c478bd9Sstevel@tonic-gate   for(i=0; i<nColumn; i++){
3607c478bd9Sstevel@tonic-gate     zType[i] = sqliteExprType(pEList->a[i].pExpr)==SQLITE_SO_NUM ? 'n' : 't';
3617c478bd9Sstevel@tonic-gate   }
3627c478bd9Sstevel@tonic-gate   zType[i] = 0;
3637c478bd9Sstevel@tonic-gate   sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate /*
3677c478bd9Sstevel@tonic-gate ** Add code to implement the OFFSET and LIMIT
3687c478bd9Sstevel@tonic-gate */
codeLimiter(Vdbe * v,Select * p,int iContinue,int iBreak,int nPop)3697c478bd9Sstevel@tonic-gate static void codeLimiter(
3707c478bd9Sstevel@tonic-gate   Vdbe *v,          /* Generate code into this VM */
3717c478bd9Sstevel@tonic-gate   Select *p,        /* The SELECT statement being coded */
3727c478bd9Sstevel@tonic-gate   int iContinue,    /* Jump here to skip the current record */
3737c478bd9Sstevel@tonic-gate   int iBreak,       /* Jump here to end the loop */
3747c478bd9Sstevel@tonic-gate   int nPop          /* Number of times to pop stack when jumping */
3757c478bd9Sstevel@tonic-gate ){
3767c478bd9Sstevel@tonic-gate   if( p->iOffset>=0 ){
3777c478bd9Sstevel@tonic-gate     int addr = sqliteVdbeCurrentAddr(v) + 2;
3787c478bd9Sstevel@tonic-gate     if( nPop>0 ) addr++;
3797c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr);
3807c478bd9Sstevel@tonic-gate     if( nPop>0 ){
3817c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, nPop, 0);
3827c478bd9Sstevel@tonic-gate     }
3837c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
3847c478bd9Sstevel@tonic-gate   }
3857c478bd9Sstevel@tonic-gate   if( p->iLimit>=0 ){
3867c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
3877c478bd9Sstevel@tonic-gate   }
3887c478bd9Sstevel@tonic-gate }
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate /*
3917c478bd9Sstevel@tonic-gate ** This routine generates the code for the inside of the inner loop
3927c478bd9Sstevel@tonic-gate ** of a SELECT.
3937c478bd9Sstevel@tonic-gate **
3947c478bd9Sstevel@tonic-gate ** If srcTab and nColumn are both zero, then the pEList expressions
3957c478bd9Sstevel@tonic-gate ** are evaluated in order to get the data for this row.  If nColumn>0
3967c478bd9Sstevel@tonic-gate ** then data is pulled from srcTab and pEList is used only to get the
3977c478bd9Sstevel@tonic-gate ** datatypes for each column.
3987c478bd9Sstevel@tonic-gate */
selectInnerLoop(Parse * pParse,Select * p,ExprList * pEList,int srcTab,int nColumn,ExprList * pOrderBy,int distinct,int eDest,int iParm,int iContinue,int iBreak)3997c478bd9Sstevel@tonic-gate static int selectInnerLoop(
4007c478bd9Sstevel@tonic-gate   Parse *pParse,          /* The parser context */
4017c478bd9Sstevel@tonic-gate   Select *p,              /* The complete select statement being coded */
4027c478bd9Sstevel@tonic-gate   ExprList *pEList,       /* List of values being extracted */
4037c478bd9Sstevel@tonic-gate   int srcTab,             /* Pull data from this table */
4047c478bd9Sstevel@tonic-gate   int nColumn,            /* Number of columns in the source table */
4057c478bd9Sstevel@tonic-gate   ExprList *pOrderBy,     /* If not NULL, sort results using this key */
4067c478bd9Sstevel@tonic-gate   int distinct,           /* If >=0, make sure results are distinct */
4077c478bd9Sstevel@tonic-gate   int eDest,              /* How to dispose of the results */
4087c478bd9Sstevel@tonic-gate   int iParm,              /* An argument to the disposal method */
4097c478bd9Sstevel@tonic-gate   int iContinue,          /* Jump here to continue with next row */
4107c478bd9Sstevel@tonic-gate   int iBreak              /* Jump here to break out of the inner loop */
4117c478bd9Sstevel@tonic-gate ){
4127c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
4137c478bd9Sstevel@tonic-gate   int i;
4147c478bd9Sstevel@tonic-gate   int hasDistinct;        /* True if the DISTINCT keyword is present */
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate   if( v==0 ) return 0;
4177c478bd9Sstevel@tonic-gate   assert( pEList!=0 );
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate   /* If there was a LIMIT clause on the SELECT statement, then do the check
4207c478bd9Sstevel@tonic-gate   ** to see if this row should be output.
4217c478bd9Sstevel@tonic-gate   */
4227c478bd9Sstevel@tonic-gate   hasDistinct = distinct>=0 && pEList && pEList->nExpr>0;
4237c478bd9Sstevel@tonic-gate   if( pOrderBy==0 && !hasDistinct ){
4247c478bd9Sstevel@tonic-gate     codeLimiter(v, p, iContinue, iBreak, 0);
4257c478bd9Sstevel@tonic-gate   }
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate   /* Pull the requested columns.
4287c478bd9Sstevel@tonic-gate   */
4297c478bd9Sstevel@tonic-gate   if( nColumn>0 ){
4307c478bd9Sstevel@tonic-gate     for(i=0; i<nColumn; i++){
4317c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Column, srcTab, i);
4327c478bd9Sstevel@tonic-gate     }
4337c478bd9Sstevel@tonic-gate   }else{
4347c478bd9Sstevel@tonic-gate     nColumn = pEList->nExpr;
4357c478bd9Sstevel@tonic-gate     for(i=0; i<pEList->nExpr; i++){
4367c478bd9Sstevel@tonic-gate       sqliteExprCode(pParse, pEList->a[i].pExpr);
4377c478bd9Sstevel@tonic-gate     }
4387c478bd9Sstevel@tonic-gate   }
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate   /* If the DISTINCT keyword was present on the SELECT statement
4417c478bd9Sstevel@tonic-gate   ** and this row has been seen before, then do not make this row
4427c478bd9Sstevel@tonic-gate   ** part of the result.
4437c478bd9Sstevel@tonic-gate   */
4447c478bd9Sstevel@tonic-gate   if( hasDistinct ){
4457c478bd9Sstevel@tonic-gate #if NULL_ALWAYS_DISTINCT
4467c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
4477c478bd9Sstevel@tonic-gate #endif
4487c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
4497c478bd9Sstevel@tonic-gate     if( pParse->db->file_format>=4 ) sqliteAddKeyType(v, pEList);
4507c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Distinct, distinct, sqliteVdbeCurrentAddr(v)+3);
4517c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
4527c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
4537c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_String, 0, 0);
4547c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
4557c478bd9Sstevel@tonic-gate     if( pOrderBy==0 ){
4567c478bd9Sstevel@tonic-gate       codeLimiter(v, p, iContinue, iBreak, nColumn);
4577c478bd9Sstevel@tonic-gate     }
4587c478bd9Sstevel@tonic-gate   }
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate   switch( eDest ){
4617c478bd9Sstevel@tonic-gate     /* In this mode, write each query result to the key of the temporary
4627c478bd9Sstevel@tonic-gate     ** table iParm.
4637c478bd9Sstevel@tonic-gate     */
4647c478bd9Sstevel@tonic-gate     case SRT_Union: {
4657c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
4667c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_String, 0, 0);
4677c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
4687c478bd9Sstevel@tonic-gate       break;
4697c478bd9Sstevel@tonic-gate     }
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate     /* Store the result as data using a unique key.
4727c478bd9Sstevel@tonic-gate     */
4737c478bd9Sstevel@tonic-gate     case SRT_Table:
4747c478bd9Sstevel@tonic-gate     case SRT_TempTable: {
4757c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
4767c478bd9Sstevel@tonic-gate       if( pOrderBy ){
4777c478bd9Sstevel@tonic-gate         pushOntoSorter(pParse, v, pOrderBy);
4787c478bd9Sstevel@tonic-gate       }else{
4797c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
4807c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Pull, 1, 0);
4817c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
4827c478bd9Sstevel@tonic-gate       }
4837c478bd9Sstevel@tonic-gate       break;
4847c478bd9Sstevel@tonic-gate     }
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate     /* Construct a record from the query result, but instead of
4877c478bd9Sstevel@tonic-gate     ** saving that record, use it as a key to delete elements from
4887c478bd9Sstevel@tonic-gate     ** the temporary table iParm.
4897c478bd9Sstevel@tonic-gate     */
4907c478bd9Sstevel@tonic-gate     case SRT_Except: {
4917c478bd9Sstevel@tonic-gate       int addr;
4927c478bd9Sstevel@tonic-gate       addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
4937c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3);
4947c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Delete, iParm, 0);
4957c478bd9Sstevel@tonic-gate       break;
4967c478bd9Sstevel@tonic-gate     }
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate     /* If we are creating a set for an "expr IN (SELECT ...)" construct,
4997c478bd9Sstevel@tonic-gate     ** then there should be a single item on the stack.  Write this
5007c478bd9Sstevel@tonic-gate     ** item into the set table with bogus data.
5017c478bd9Sstevel@tonic-gate     */
5027c478bd9Sstevel@tonic-gate     case SRT_Set: {
5037c478bd9Sstevel@tonic-gate       int addr1 = sqliteVdbeCurrentAddr(v);
5047c478bd9Sstevel@tonic-gate       int addr2;
5057c478bd9Sstevel@tonic-gate       assert( nColumn==1 );
5067c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotNull, -1, addr1+3);
5077c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
5087c478bd9Sstevel@tonic-gate       addr2 = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
5097c478bd9Sstevel@tonic-gate       if( pOrderBy ){
5107c478bd9Sstevel@tonic-gate         pushOntoSorter(pParse, v, pOrderBy);
5117c478bd9Sstevel@tonic-gate       }else{
5127c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_String, 0, 0);
5137c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
5147c478bd9Sstevel@tonic-gate       }
5157c478bd9Sstevel@tonic-gate       sqliteVdbeChangeP2(v, addr2, sqliteVdbeCurrentAddr(v));
5167c478bd9Sstevel@tonic-gate       break;
5177c478bd9Sstevel@tonic-gate     }
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate     /* If this is a scalar select that is part of an expression, then
5207c478bd9Sstevel@tonic-gate     ** store the results in the appropriate memory cell and break out
5217c478bd9Sstevel@tonic-gate     ** of the scan loop.
5227c478bd9Sstevel@tonic-gate     */
5237c478bd9Sstevel@tonic-gate     case SRT_Mem: {
5247c478bd9Sstevel@tonic-gate       assert( nColumn==1 );
5257c478bd9Sstevel@tonic-gate       if( pOrderBy ){
5267c478bd9Sstevel@tonic-gate         pushOntoSorter(pParse, v, pOrderBy);
5277c478bd9Sstevel@tonic-gate       }else{
5287c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
5297c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Goto, 0, iBreak);
5307c478bd9Sstevel@tonic-gate       }
5317c478bd9Sstevel@tonic-gate       break;
5327c478bd9Sstevel@tonic-gate     }
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate     /* Send the data to the callback function.
5357c478bd9Sstevel@tonic-gate     */
5367c478bd9Sstevel@tonic-gate     case SRT_Callback:
5377c478bd9Sstevel@tonic-gate     case SRT_Sorter: {
5387c478bd9Sstevel@tonic-gate       if( pOrderBy ){
5397c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
5407c478bd9Sstevel@tonic-gate         pushOntoSorter(pParse, v, pOrderBy);
5417c478bd9Sstevel@tonic-gate       }else{
5427c478bd9Sstevel@tonic-gate         assert( eDest==SRT_Callback );
5437c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
5447c478bd9Sstevel@tonic-gate       }
5457c478bd9Sstevel@tonic-gate       break;
5467c478bd9Sstevel@tonic-gate     }
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate     /* Invoke a subroutine to handle the results.  The subroutine itself
5497c478bd9Sstevel@tonic-gate     ** is responsible for popping the results off of the stack.
5507c478bd9Sstevel@tonic-gate     */
5517c478bd9Sstevel@tonic-gate     case SRT_Subroutine: {
5527c478bd9Sstevel@tonic-gate       if( pOrderBy ){
5537c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
5547c478bd9Sstevel@tonic-gate         pushOntoSorter(pParse, v, pOrderBy);
5557c478bd9Sstevel@tonic-gate       }else{
5567c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Gosub, 0, iParm);
5577c478bd9Sstevel@tonic-gate       }
5587c478bd9Sstevel@tonic-gate       break;
5597c478bd9Sstevel@tonic-gate     }
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate     /* Discard the results.  This is used for SELECT statements inside
5627c478bd9Sstevel@tonic-gate     ** the body of a TRIGGER.  The purpose of such selects is to call
5637c478bd9Sstevel@tonic-gate     ** user-defined functions that have side effects.  We do not care
5647c478bd9Sstevel@tonic-gate     ** about the actual results of the select.
5657c478bd9Sstevel@tonic-gate     */
5667c478bd9Sstevel@tonic-gate     default: {
5677c478bd9Sstevel@tonic-gate       assert( eDest==SRT_Discard );
5687c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
5697c478bd9Sstevel@tonic-gate       break;
5707c478bd9Sstevel@tonic-gate     }
5717c478bd9Sstevel@tonic-gate   }
5727c478bd9Sstevel@tonic-gate   return 0;
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate /*
5767c478bd9Sstevel@tonic-gate ** If the inner loop was generated using a non-null pOrderBy argument,
5777c478bd9Sstevel@tonic-gate ** then the results were placed in a sorter.  After the loop is terminated
5787c478bd9Sstevel@tonic-gate ** we need to run the sorter and output the results.  The following
5797c478bd9Sstevel@tonic-gate ** routine generates the code needed to do that.
5807c478bd9Sstevel@tonic-gate */
generateSortTail(Select * p,Vdbe * v,int nColumn,int eDest,int iParm)5817c478bd9Sstevel@tonic-gate static void generateSortTail(
5827c478bd9Sstevel@tonic-gate   Select *p,       /* The SELECT statement */
5837c478bd9Sstevel@tonic-gate   Vdbe *v,         /* Generate code into this VDBE */
5847c478bd9Sstevel@tonic-gate   int nColumn,     /* Number of columns of data */
5857c478bd9Sstevel@tonic-gate   int eDest,       /* Write the sorted results here */
5867c478bd9Sstevel@tonic-gate   int iParm        /* Optional parameter associated with eDest */
5877c478bd9Sstevel@tonic-gate ){
5887c478bd9Sstevel@tonic-gate   int end1 = sqliteVdbeMakeLabel(v);
5897c478bd9Sstevel@tonic-gate   int end2 = sqliteVdbeMakeLabel(v);
5907c478bd9Sstevel@tonic-gate   int addr;
5917c478bd9Sstevel@tonic-gate   if( eDest==SRT_Sorter ) return;
5927c478bd9Sstevel@tonic-gate   sqliteVdbeAddOp(v, OP_Sort, 0, 0);
5937c478bd9Sstevel@tonic-gate   addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
5947c478bd9Sstevel@tonic-gate   codeLimiter(v, p, addr, end2, 1);
5957c478bd9Sstevel@tonic-gate   switch( eDest ){
5967c478bd9Sstevel@tonic-gate     case SRT_Callback: {
5977c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
5987c478bd9Sstevel@tonic-gate       break;
5997c478bd9Sstevel@tonic-gate     }
6007c478bd9Sstevel@tonic-gate     case SRT_Table:
6017c478bd9Sstevel@tonic-gate     case SRT_TempTable: {
6027c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
6037c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pull, 1, 0);
6047c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
6057c478bd9Sstevel@tonic-gate       break;
6067c478bd9Sstevel@tonic-gate     }
6077c478bd9Sstevel@tonic-gate     case SRT_Set: {
6087c478bd9Sstevel@tonic-gate       assert( nColumn==1 );
6097c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
6107c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
6117c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Goto, 0, sqliteVdbeCurrentAddr(v)+3);
6127c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_String, 0, 0);
6137c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
6147c478bd9Sstevel@tonic-gate       break;
6157c478bd9Sstevel@tonic-gate     }
6167c478bd9Sstevel@tonic-gate     case SRT_Mem: {
6177c478bd9Sstevel@tonic-gate       assert( nColumn==1 );
6187c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
6197c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Goto, 0, end1);
6207c478bd9Sstevel@tonic-gate       break;
6217c478bd9Sstevel@tonic-gate     }
6227c478bd9Sstevel@tonic-gate     case SRT_Subroutine: {
6237c478bd9Sstevel@tonic-gate       int i;
6247c478bd9Sstevel@tonic-gate       for(i=0; i<nColumn; i++){
6257c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Column, -1-i, i);
6267c478bd9Sstevel@tonic-gate       }
6277c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Gosub, 0, iParm);
6287c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Pop, 1, 0);
6297c478bd9Sstevel@tonic-gate       break;
6307c478bd9Sstevel@tonic-gate     }
6317c478bd9Sstevel@tonic-gate     default: {
6327c478bd9Sstevel@tonic-gate       /* Do nothing */
6337c478bd9Sstevel@tonic-gate       break;
6347c478bd9Sstevel@tonic-gate     }
6357c478bd9Sstevel@tonic-gate   }
6367c478bd9Sstevel@tonic-gate   sqliteVdbeAddOp(v, OP_Goto, 0, addr);
6377c478bd9Sstevel@tonic-gate   sqliteVdbeResolveLabel(v, end2);
6387c478bd9Sstevel@tonic-gate   sqliteVdbeAddOp(v, OP_Pop, 1, 0);
6397c478bd9Sstevel@tonic-gate   sqliteVdbeResolveLabel(v, end1);
6407c478bd9Sstevel@tonic-gate   sqliteVdbeAddOp(v, OP_SortReset, 0, 0);
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate /*
6447c478bd9Sstevel@tonic-gate ** Generate code that will tell the VDBE the datatypes of
6457c478bd9Sstevel@tonic-gate ** columns in the result set.
6467c478bd9Sstevel@tonic-gate **
6477c478bd9Sstevel@tonic-gate ** This routine only generates code if the "PRAGMA show_datatypes=on"
6487c478bd9Sstevel@tonic-gate ** has been executed.  The datatypes are reported out in the azCol
6497c478bd9Sstevel@tonic-gate ** parameter to the callback function.  The first N azCol[] entries
6507c478bd9Sstevel@tonic-gate ** are the names of the columns, and the second N entries are the
6517c478bd9Sstevel@tonic-gate ** datatypes for the columns.
6527c478bd9Sstevel@tonic-gate **
6537c478bd9Sstevel@tonic-gate ** The "datatype" for a result that is a column of a type is the
6547c478bd9Sstevel@tonic-gate ** datatype definition extracted from the CREATE TABLE statement.
6557c478bd9Sstevel@tonic-gate ** The datatype for an expression is either TEXT or NUMERIC.  The
6567c478bd9Sstevel@tonic-gate ** datatype for a ROWID field is INTEGER.
6577c478bd9Sstevel@tonic-gate */
generateColumnTypes(Parse * pParse,SrcList * pTabList,ExprList * pEList)6587c478bd9Sstevel@tonic-gate static void generateColumnTypes(
6597c478bd9Sstevel@tonic-gate   Parse *pParse,      /* Parser context */
6607c478bd9Sstevel@tonic-gate   SrcList *pTabList,  /* List of tables */
6617c478bd9Sstevel@tonic-gate   ExprList *pEList    /* Expressions defining the result set */
6627c478bd9Sstevel@tonic-gate ){
6637c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
6647c478bd9Sstevel@tonic-gate   int i, j;
6657c478bd9Sstevel@tonic-gate   for(i=0; i<pEList->nExpr; i++){
6667c478bd9Sstevel@tonic-gate     Expr *p = pEList->a[i].pExpr;
6677c478bd9Sstevel@tonic-gate     char *zType = 0;
6687c478bd9Sstevel@tonic-gate     if( p==0 ) continue;
6697c478bd9Sstevel@tonic-gate     if( p->op==TK_COLUMN && pTabList ){
6707c478bd9Sstevel@tonic-gate       Table *pTab;
6717c478bd9Sstevel@tonic-gate       int iCol = p->iColumn;
6727c478bd9Sstevel@tonic-gate       for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
6737c478bd9Sstevel@tonic-gate       assert( j<pTabList->nSrc );
6747c478bd9Sstevel@tonic-gate       pTab = pTabList->a[j].pTab;
6757c478bd9Sstevel@tonic-gate       if( iCol<0 ) iCol = pTab->iPKey;
6767c478bd9Sstevel@tonic-gate       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
6777c478bd9Sstevel@tonic-gate       if( iCol<0 ){
6787c478bd9Sstevel@tonic-gate         zType = "INTEGER";
6797c478bd9Sstevel@tonic-gate       }else{
6807c478bd9Sstevel@tonic-gate         zType = pTab->aCol[iCol].zType;
6817c478bd9Sstevel@tonic-gate       }
6827c478bd9Sstevel@tonic-gate     }else{
6837c478bd9Sstevel@tonic-gate       if( sqliteExprType(p)==SQLITE_SO_TEXT ){
6847c478bd9Sstevel@tonic-gate         zType = "TEXT";
6857c478bd9Sstevel@tonic-gate       }else{
6867c478bd9Sstevel@tonic-gate         zType = "NUMERIC";
6877c478bd9Sstevel@tonic-gate       }
6887c478bd9Sstevel@tonic-gate     }
6897c478bd9Sstevel@tonic-gate     sqliteVdbeOp3(v, OP_ColumnName, i + pEList->nExpr, 0, zType, 0);
6907c478bd9Sstevel@tonic-gate   }
6917c478bd9Sstevel@tonic-gate }
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate /*
6947c478bd9Sstevel@tonic-gate ** Generate code that will tell the VDBE the names of columns
6957c478bd9Sstevel@tonic-gate ** in the result set.  This information is used to provide the
6967c478bd9Sstevel@tonic-gate ** azCol[] values in the callback.
6977c478bd9Sstevel@tonic-gate */
generateColumnNames(Parse * pParse,SrcList * pTabList,ExprList * pEList)6987c478bd9Sstevel@tonic-gate static void generateColumnNames(
6997c478bd9Sstevel@tonic-gate   Parse *pParse,      /* Parser context */
7007c478bd9Sstevel@tonic-gate   SrcList *pTabList,  /* List of tables */
7017c478bd9Sstevel@tonic-gate   ExprList *pEList    /* Expressions defining the result set */
7027c478bd9Sstevel@tonic-gate ){
7037c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
7047c478bd9Sstevel@tonic-gate   int i, j;
7057c478bd9Sstevel@tonic-gate   sqlite *db = pParse->db;
7067c478bd9Sstevel@tonic-gate   int fullNames, shortNames;
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate   assert( v!=0 );
7097c478bd9Sstevel@tonic-gate   if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
7107c478bd9Sstevel@tonic-gate   pParse->colNamesSet = 1;
7117c478bd9Sstevel@tonic-gate   fullNames = (db->flags & SQLITE_FullColNames)!=0;
7127c478bd9Sstevel@tonic-gate   shortNames = (db->flags & SQLITE_ShortColNames)!=0;
7137c478bd9Sstevel@tonic-gate   for(i=0; i<pEList->nExpr; i++){
7147c478bd9Sstevel@tonic-gate     Expr *p;
7157c478bd9Sstevel@tonic-gate     int p2 = i==pEList->nExpr-1;
7167c478bd9Sstevel@tonic-gate     p = pEList->a[i].pExpr;
7177c478bd9Sstevel@tonic-gate     if( p==0 ) continue;
7187c478bd9Sstevel@tonic-gate     if( pEList->a[i].zName ){
7197c478bd9Sstevel@tonic-gate       char *zName = pEList->a[i].zName;
7207c478bd9Sstevel@tonic-gate       sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
7217c478bd9Sstevel@tonic-gate       continue;
7227c478bd9Sstevel@tonic-gate     }
7237c478bd9Sstevel@tonic-gate     if( p->op==TK_COLUMN && pTabList ){
7247c478bd9Sstevel@tonic-gate       Table *pTab;
7257c478bd9Sstevel@tonic-gate       char *zCol;
7267c478bd9Sstevel@tonic-gate       int iCol = p->iColumn;
7277c478bd9Sstevel@tonic-gate       for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
7287c478bd9Sstevel@tonic-gate       assert( j<pTabList->nSrc );
7297c478bd9Sstevel@tonic-gate       pTab = pTabList->a[j].pTab;
7307c478bd9Sstevel@tonic-gate       if( iCol<0 ) iCol = pTab->iPKey;
7317c478bd9Sstevel@tonic-gate       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
7327c478bd9Sstevel@tonic-gate       if( iCol<0 ){
7337c478bd9Sstevel@tonic-gate         zCol = "_ROWID_";
7347c478bd9Sstevel@tonic-gate       }else{
7357c478bd9Sstevel@tonic-gate         zCol = pTab->aCol[iCol].zName;
7367c478bd9Sstevel@tonic-gate       }
7377c478bd9Sstevel@tonic-gate       if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
7387c478bd9Sstevel@tonic-gate         int addr = sqliteVdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
7397c478bd9Sstevel@tonic-gate         sqliteVdbeCompressSpace(v, addr);
7407c478bd9Sstevel@tonic-gate       }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
7417c478bd9Sstevel@tonic-gate         char *zName = 0;
7427c478bd9Sstevel@tonic-gate         char *zTab;
743*55fea89dSDan Cross 
7447c478bd9Sstevel@tonic-gate         zTab = pTabList->a[j].zAlias;
7457c478bd9Sstevel@tonic-gate         if( fullNames || zTab==0 ) zTab = pTab->zName;
7467c478bd9Sstevel@tonic-gate         sqliteSetString(&zName, zTab, ".", zCol, 0);
7477c478bd9Sstevel@tonic-gate         sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, P3_DYNAMIC);
7487c478bd9Sstevel@tonic-gate       }else{
7497c478bd9Sstevel@tonic-gate         sqliteVdbeOp3(v, OP_ColumnName, i, p2, zCol, 0);
7507c478bd9Sstevel@tonic-gate       }
7517c478bd9Sstevel@tonic-gate     }else if( p->span.z && p->span.z[0] ){
7527c478bd9Sstevel@tonic-gate       int addr = sqliteVdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
7537c478bd9Sstevel@tonic-gate       sqliteVdbeCompressSpace(v, addr);
7547c478bd9Sstevel@tonic-gate     }else{
7557c478bd9Sstevel@tonic-gate       char zName[30];
7567c478bd9Sstevel@tonic-gate       assert( p->op!=TK_COLUMN || pTabList==0 );
7577c478bd9Sstevel@tonic-gate       sprintf(zName, "column%d", i+1);
7587c478bd9Sstevel@tonic-gate       sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
7597c478bd9Sstevel@tonic-gate     }
7607c478bd9Sstevel@tonic-gate   }
7617c478bd9Sstevel@tonic-gate }
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate /*
7647c478bd9Sstevel@tonic-gate ** Name of the connection operator, used for error messages.
7657c478bd9Sstevel@tonic-gate */
selectOpName(int id)7667c478bd9Sstevel@tonic-gate static const char *selectOpName(int id){
7677c478bd9Sstevel@tonic-gate   char *z;
7687c478bd9Sstevel@tonic-gate   switch( id ){
7697c478bd9Sstevel@tonic-gate     case TK_ALL:       z = "UNION ALL";   break;
7707c478bd9Sstevel@tonic-gate     case TK_INTERSECT: z = "INTERSECT";   break;
7717c478bd9Sstevel@tonic-gate     case TK_EXCEPT:    z = "EXCEPT";      break;
7727c478bd9Sstevel@tonic-gate     default:           z = "UNION";       break;
7737c478bd9Sstevel@tonic-gate   }
7747c478bd9Sstevel@tonic-gate   return z;
7757c478bd9Sstevel@tonic-gate }
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate /*
7787c478bd9Sstevel@tonic-gate ** Forward declaration
7797c478bd9Sstevel@tonic-gate */
7807c478bd9Sstevel@tonic-gate static int fillInColumnList(Parse*, Select*);
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate /*
7837c478bd9Sstevel@tonic-gate ** Given a SELECT statement, generate a Table structure that describes
7847c478bd9Sstevel@tonic-gate ** the result set of that SELECT.
7857c478bd9Sstevel@tonic-gate */
sqliteResultSetOfSelect(Parse * pParse,char * zTabName,Select * pSelect)7867c478bd9Sstevel@tonic-gate Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
7877c478bd9Sstevel@tonic-gate   Table *pTab;
7887c478bd9Sstevel@tonic-gate   int i, j;
7897c478bd9Sstevel@tonic-gate   ExprList *pEList;
7907c478bd9Sstevel@tonic-gate   Column *aCol;
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate   if( fillInColumnList(pParse, pSelect) ){
7937c478bd9Sstevel@tonic-gate     return 0;
7947c478bd9Sstevel@tonic-gate   }
7957c478bd9Sstevel@tonic-gate   pTab = sqliteMalloc( sizeof(Table) );
7967c478bd9Sstevel@tonic-gate   if( pTab==0 ){
7977c478bd9Sstevel@tonic-gate     return 0;
7987c478bd9Sstevel@tonic-gate   }
7997c478bd9Sstevel@tonic-gate   pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
8007c478bd9Sstevel@tonic-gate   pEList = pSelect->pEList;
8017c478bd9Sstevel@tonic-gate   pTab->nCol = pEList->nExpr;
8027c478bd9Sstevel@tonic-gate   assert( pTab->nCol>0 );
8037c478bd9Sstevel@tonic-gate   pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
8047c478bd9Sstevel@tonic-gate   for(i=0; i<pTab->nCol; i++){
8057c478bd9Sstevel@tonic-gate     Expr *p, *pR;
8067c478bd9Sstevel@tonic-gate     if( pEList->a[i].zName ){
8077c478bd9Sstevel@tonic-gate       aCol[i].zName = sqliteStrDup(pEList->a[i].zName);
808*55fea89dSDan Cross     }else if( (p=pEList->a[i].pExpr)->op==TK_DOT
8097c478bd9Sstevel@tonic-gate                && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
8107c478bd9Sstevel@tonic-gate       int cnt;
8117c478bd9Sstevel@tonic-gate       sqliteSetNString(&aCol[i].zName, pR->token.z, pR->token.n, 0);
8127c478bd9Sstevel@tonic-gate       for(j=cnt=0; j<i; j++){
8137c478bd9Sstevel@tonic-gate         if( sqliteStrICmp(aCol[j].zName, aCol[i].zName)==0 ){
8147c478bd9Sstevel@tonic-gate           int n;
8157c478bd9Sstevel@tonic-gate           char zBuf[30];
8167c478bd9Sstevel@tonic-gate           sprintf(zBuf,"_%d",++cnt);
8177c478bd9Sstevel@tonic-gate           n = strlen(zBuf);
8187c478bd9Sstevel@tonic-gate           sqliteSetNString(&aCol[i].zName, pR->token.z, pR->token.n, zBuf, n,0);
8197c478bd9Sstevel@tonic-gate           j = -1;
8207c478bd9Sstevel@tonic-gate         }
8217c478bd9Sstevel@tonic-gate       }
8227c478bd9Sstevel@tonic-gate     }else if( p->span.z && p->span.z[0] ){
8237c478bd9Sstevel@tonic-gate       sqliteSetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0);
8247c478bd9Sstevel@tonic-gate     }else{
8257c478bd9Sstevel@tonic-gate       char zBuf[30];
8267c478bd9Sstevel@tonic-gate       sprintf(zBuf, "column%d", i+1);
8277c478bd9Sstevel@tonic-gate       aCol[i].zName = sqliteStrDup(zBuf);
8287c478bd9Sstevel@tonic-gate     }
8297c478bd9Sstevel@tonic-gate     sqliteDequote(aCol[i].zName);
8307c478bd9Sstevel@tonic-gate   }
8317c478bd9Sstevel@tonic-gate   pTab->iPKey = -1;
8327c478bd9Sstevel@tonic-gate   return pTab;
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate /*
8367c478bd9Sstevel@tonic-gate ** For the given SELECT statement, do three things.
8377c478bd9Sstevel@tonic-gate **
838*55fea89dSDan Cross **    (1)  Fill in the pTabList->a[].pTab fields in the SrcList that
8397c478bd9Sstevel@tonic-gate **         defines the set of tables that should be scanned.  For views,
8407c478bd9Sstevel@tonic-gate **         fill pTabList->a[].pSelect with a copy of the SELECT statement
8417c478bd9Sstevel@tonic-gate **         that implements the view.  A copy is made of the view's SELECT
8427c478bd9Sstevel@tonic-gate **         statement so that we can freely modify or delete that statement
8437c478bd9Sstevel@tonic-gate **         without worrying about messing up the presistent representation
8447c478bd9Sstevel@tonic-gate **         of the view.
8457c478bd9Sstevel@tonic-gate **
8467c478bd9Sstevel@tonic-gate **    (2)  Add terms to the WHERE clause to accomodate the NATURAL keyword
8477c478bd9Sstevel@tonic-gate **         on joins and the ON and USING clause of joins.
8487c478bd9Sstevel@tonic-gate **
8497c478bd9Sstevel@tonic-gate **    (3)  Scan the list of columns in the result set (pEList) looking
8507c478bd9Sstevel@tonic-gate **         for instances of the "*" operator or the TABLE.* operator.
8517c478bd9Sstevel@tonic-gate **         If found, expand each "*" to be every column in every table
8527c478bd9Sstevel@tonic-gate **         and TABLE.* to be every column in TABLE.
8537c478bd9Sstevel@tonic-gate **
8547c478bd9Sstevel@tonic-gate ** Return 0 on success.  If there are problems, leave an error message
8557c478bd9Sstevel@tonic-gate ** in pParse and return non-zero.
8567c478bd9Sstevel@tonic-gate */
fillInColumnList(Parse * pParse,Select * p)8577c478bd9Sstevel@tonic-gate static int fillInColumnList(Parse *pParse, Select *p){
8587c478bd9Sstevel@tonic-gate   int i, j, k, rc;
8597c478bd9Sstevel@tonic-gate   SrcList *pTabList;
8607c478bd9Sstevel@tonic-gate   ExprList *pEList;
8617c478bd9Sstevel@tonic-gate   Table *pTab;
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate   if( p==0 || p->pSrc==0 ) return 1;
8647c478bd9Sstevel@tonic-gate   pTabList = p->pSrc;
8657c478bd9Sstevel@tonic-gate   pEList = p->pEList;
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate   /* Look up every table in the table list.
8687c478bd9Sstevel@tonic-gate   */
8697c478bd9Sstevel@tonic-gate   for(i=0; i<pTabList->nSrc; i++){
8707c478bd9Sstevel@tonic-gate     if( pTabList->a[i].pTab ){
8717c478bd9Sstevel@tonic-gate       /* This routine has run before!  No need to continue */
8727c478bd9Sstevel@tonic-gate       return 0;
8737c478bd9Sstevel@tonic-gate     }
8747c478bd9Sstevel@tonic-gate     if( pTabList->a[i].zName==0 ){
8757c478bd9Sstevel@tonic-gate       /* A sub-query in the FROM clause of a SELECT */
8767c478bd9Sstevel@tonic-gate       assert( pTabList->a[i].pSelect!=0 );
8777c478bd9Sstevel@tonic-gate       if( pTabList->a[i].zAlias==0 ){
8787c478bd9Sstevel@tonic-gate         char zFakeName[60];
8797c478bd9Sstevel@tonic-gate         sprintf(zFakeName, "sqlite_subquery_%p_",
8807c478bd9Sstevel@tonic-gate            (void*)pTabList->a[i].pSelect);
8817c478bd9Sstevel@tonic-gate         sqliteSetString(&pTabList->a[i].zAlias, zFakeName, 0);
8827c478bd9Sstevel@tonic-gate       }
883*55fea89dSDan Cross       pTabList->a[i].pTab = pTab =
8847c478bd9Sstevel@tonic-gate         sqliteResultSetOfSelect(pParse, pTabList->a[i].zAlias,
8857c478bd9Sstevel@tonic-gate                                         pTabList->a[i].pSelect);
8867c478bd9Sstevel@tonic-gate       if( pTab==0 ){
8877c478bd9Sstevel@tonic-gate         return 1;
8887c478bd9Sstevel@tonic-gate       }
8897c478bd9Sstevel@tonic-gate       /* The isTransient flag indicates that the Table structure has been
8907c478bd9Sstevel@tonic-gate       ** dynamically allocated and may be freed at any time.  In other words,
8917c478bd9Sstevel@tonic-gate       ** pTab is not pointing to a persistent table structure that defines
8927c478bd9Sstevel@tonic-gate       ** part of the schema. */
8937c478bd9Sstevel@tonic-gate       pTab->isTransient = 1;
8947c478bd9Sstevel@tonic-gate     }else{
8957c478bd9Sstevel@tonic-gate       /* An ordinary table or view name in the FROM clause */
896*55fea89dSDan Cross       pTabList->a[i].pTab = pTab =
8977c478bd9Sstevel@tonic-gate         sqliteLocateTable(pParse,pTabList->a[i].zName,pTabList->a[i].zDatabase);
8987c478bd9Sstevel@tonic-gate       if( pTab==0 ){
8997c478bd9Sstevel@tonic-gate         return 1;
9007c478bd9Sstevel@tonic-gate       }
9017c478bd9Sstevel@tonic-gate       if( pTab->pSelect ){
9027c478bd9Sstevel@tonic-gate         /* We reach here if the named table is a really a view */
9037c478bd9Sstevel@tonic-gate         if( sqliteViewGetColumnNames(pParse, pTab) ){
9047c478bd9Sstevel@tonic-gate           return 1;
9057c478bd9Sstevel@tonic-gate         }
9067c478bd9Sstevel@tonic-gate         /* If pTabList->a[i].pSelect!=0 it means we are dealing with a
9077c478bd9Sstevel@tonic-gate         ** view within a view.  The SELECT structure has already been
9087c478bd9Sstevel@tonic-gate         ** copied by the outer view so we can skip the copy step here
9097c478bd9Sstevel@tonic-gate         ** in the inner view.
9107c478bd9Sstevel@tonic-gate         */
9117c478bd9Sstevel@tonic-gate         if( pTabList->a[i].pSelect==0 ){
9127c478bd9Sstevel@tonic-gate           pTabList->a[i].pSelect = sqliteSelectDup(pTab->pSelect);
9137c478bd9Sstevel@tonic-gate         }
9147c478bd9Sstevel@tonic-gate       }
9157c478bd9Sstevel@tonic-gate     }
9167c478bd9Sstevel@tonic-gate   }
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate   /* Process NATURAL keywords, and ON and USING clauses of joins.
9197c478bd9Sstevel@tonic-gate   */
9207c478bd9Sstevel@tonic-gate   if( sqliteProcessJoin(pParse, p) ) return 1;
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate   /* For every "*" that occurs in the column list, insert the names of
9237c478bd9Sstevel@tonic-gate   ** all columns in all tables.  And for every TABLE.* insert the names
9247c478bd9Sstevel@tonic-gate   ** of all columns in TABLE.  The parser inserted a special expression
9257c478bd9Sstevel@tonic-gate   ** with the TK_ALL operator for each "*" that it found in the column list.
9267c478bd9Sstevel@tonic-gate   ** The following code just has to locate the TK_ALL expressions and expand
9277c478bd9Sstevel@tonic-gate   ** each one to the list of all columns in all tables.
9287c478bd9Sstevel@tonic-gate   **
9297c478bd9Sstevel@tonic-gate   ** The first loop just checks to see if there are any "*" operators
9307c478bd9Sstevel@tonic-gate   ** that need expanding.
9317c478bd9Sstevel@tonic-gate   */
9327c478bd9Sstevel@tonic-gate   for(k=0; k<pEList->nExpr; k++){
9337c478bd9Sstevel@tonic-gate     Expr *pE = pEList->a[k].pExpr;
9347c478bd9Sstevel@tonic-gate     if( pE->op==TK_ALL ) break;
9357c478bd9Sstevel@tonic-gate     if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
9367c478bd9Sstevel@tonic-gate          && pE->pLeft && pE->pLeft->op==TK_ID ) break;
9377c478bd9Sstevel@tonic-gate   }
9387c478bd9Sstevel@tonic-gate   rc = 0;
9397c478bd9Sstevel@tonic-gate   if( k<pEList->nExpr ){
9407c478bd9Sstevel@tonic-gate     /*
9417c478bd9Sstevel@tonic-gate     ** If we get here it means the result set contains one or more "*"
9427c478bd9Sstevel@tonic-gate     ** operators that need to be expanded.  Loop through each expression
9437c478bd9Sstevel@tonic-gate     ** in the result set and expand them one by one.
9447c478bd9Sstevel@tonic-gate     */
9457c478bd9Sstevel@tonic-gate     struct ExprList_item *a = pEList->a;
9467c478bd9Sstevel@tonic-gate     ExprList *pNew = 0;
9477c478bd9Sstevel@tonic-gate     for(k=0; k<pEList->nExpr; k++){
9487c478bd9Sstevel@tonic-gate       Expr *pE = a[k].pExpr;
9497c478bd9Sstevel@tonic-gate       if( pE->op!=TK_ALL &&
9507c478bd9Sstevel@tonic-gate            (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
9517c478bd9Sstevel@tonic-gate         /* This particular expression does not need to be expanded.
9527c478bd9Sstevel@tonic-gate         */
9537c478bd9Sstevel@tonic-gate         pNew = sqliteExprListAppend(pNew, a[k].pExpr, 0);
9547c478bd9Sstevel@tonic-gate         pNew->a[pNew->nExpr-1].zName = a[k].zName;
9557c478bd9Sstevel@tonic-gate         a[k].pExpr = 0;
9567c478bd9Sstevel@tonic-gate         a[k].zName = 0;
9577c478bd9Sstevel@tonic-gate       }else{
9587c478bd9Sstevel@tonic-gate         /* This expression is a "*" or a "TABLE.*" and needs to be
9597c478bd9Sstevel@tonic-gate         ** expanded. */
9607c478bd9Sstevel@tonic-gate         int tableSeen = 0;      /* Set to 1 when TABLE matches */
9617c478bd9Sstevel@tonic-gate         char *zTName;           /* text of name of TABLE */
9627c478bd9Sstevel@tonic-gate         if( pE->op==TK_DOT && pE->pLeft ){
9637c478bd9Sstevel@tonic-gate           zTName = sqliteTableNameFromToken(&pE->pLeft->token);
9647c478bd9Sstevel@tonic-gate         }else{
9657c478bd9Sstevel@tonic-gate           zTName = 0;
9667c478bd9Sstevel@tonic-gate         }
9677c478bd9Sstevel@tonic-gate         for(i=0; i<pTabList->nSrc; i++){
9687c478bd9Sstevel@tonic-gate           Table *pTab = pTabList->a[i].pTab;
9697c478bd9Sstevel@tonic-gate           char *zTabName = pTabList->a[i].zAlias;
970*55fea89dSDan Cross           if( zTabName==0 || zTabName[0]==0 ){
9717c478bd9Sstevel@tonic-gate             zTabName = pTab->zName;
9727c478bd9Sstevel@tonic-gate           }
973*55fea89dSDan Cross           if( zTName && (zTabName==0 || zTabName[0]==0 ||
9747c478bd9Sstevel@tonic-gate                  sqliteStrICmp(zTName, zTabName)!=0) ){
9757c478bd9Sstevel@tonic-gate             continue;
9767c478bd9Sstevel@tonic-gate           }
9777c478bd9Sstevel@tonic-gate           tableSeen = 1;
9787c478bd9Sstevel@tonic-gate           for(j=0; j<pTab->nCol; j++){
9797c478bd9Sstevel@tonic-gate             Expr *pExpr, *pLeft, *pRight;
9807c478bd9Sstevel@tonic-gate             char *zName = pTab->aCol[j].zName;
9817c478bd9Sstevel@tonic-gate 
9827c478bd9Sstevel@tonic-gate             if( i>0 && (pTabList->a[i-1].jointype & JT_NATURAL)!=0 &&
9837c478bd9Sstevel@tonic-gate                 columnIndex(pTabList->a[i-1].pTab, zName)>=0 ){
984*55fea89dSDan Cross               /* In a NATURAL join, omit the join columns from the
9857c478bd9Sstevel@tonic-gate               ** table on the right */
9867c478bd9Sstevel@tonic-gate               continue;
9877c478bd9Sstevel@tonic-gate             }
9887c478bd9Sstevel@tonic-gate             if( i>0 && sqliteIdListIndex(pTabList->a[i-1].pUsing, zName)>=0 ){
9897c478bd9Sstevel@tonic-gate               /* In a join with a USING clause, omit columns in the
9907c478bd9Sstevel@tonic-gate               ** using clause from the table on the right. */
9917c478bd9Sstevel@tonic-gate               continue;
9927c478bd9Sstevel@tonic-gate             }
9937c478bd9Sstevel@tonic-gate             pRight = sqliteExpr(TK_ID, 0, 0, 0);
9947c478bd9Sstevel@tonic-gate             if( pRight==0 ) break;
9957c478bd9Sstevel@tonic-gate             pRight->token.z = zName;
9967c478bd9Sstevel@tonic-gate             pRight->token.n = strlen(zName);
9977c478bd9Sstevel@tonic-gate             pRight->token.dyn = 0;
9987c478bd9Sstevel@tonic-gate             if( zTabName && pTabList->nSrc>1 ){
9997c478bd9Sstevel@tonic-gate               pLeft = sqliteExpr(TK_ID, 0, 0, 0);
10007c478bd9Sstevel@tonic-gate               pExpr = sqliteExpr(TK_DOT, pLeft, pRight, 0);
10017c478bd9Sstevel@tonic-gate               if( pExpr==0 ) break;
10027c478bd9Sstevel@tonic-gate               pLeft->token.z = zTabName;
10037c478bd9Sstevel@tonic-gate               pLeft->token.n = strlen(zTabName);
10047c478bd9Sstevel@tonic-gate               pLeft->token.dyn = 0;
10057c478bd9Sstevel@tonic-gate               sqliteSetString((char**)&pExpr->span.z, zTabName, ".", zName, 0);
10067c478bd9Sstevel@tonic-gate               pExpr->span.n = strlen(pExpr->span.z);
10077c478bd9Sstevel@tonic-gate               pExpr->span.dyn = 1;
10087c478bd9Sstevel@tonic-gate               pExpr->token.z = 0;
10097c478bd9Sstevel@tonic-gate               pExpr->token.n = 0;
10107c478bd9Sstevel@tonic-gate               pExpr->token.dyn = 0;
10117c478bd9Sstevel@tonic-gate             }else{
10127c478bd9Sstevel@tonic-gate               pExpr = pRight;
10137c478bd9Sstevel@tonic-gate               pExpr->span = pExpr->token;
10147c478bd9Sstevel@tonic-gate             }
10157c478bd9Sstevel@tonic-gate             pNew = sqliteExprListAppend(pNew, pExpr, 0);
10167c478bd9Sstevel@tonic-gate           }
10177c478bd9Sstevel@tonic-gate         }
10187c478bd9Sstevel@tonic-gate         if( !tableSeen ){
10197c478bd9Sstevel@tonic-gate           if( zTName ){
10207c478bd9Sstevel@tonic-gate             sqliteErrorMsg(pParse, "no such table: %s", zTName);
10217c478bd9Sstevel@tonic-gate           }else{
10227c478bd9Sstevel@tonic-gate             sqliteErrorMsg(pParse, "no tables specified");
10237c478bd9Sstevel@tonic-gate           }
10247c478bd9Sstevel@tonic-gate           rc = 1;
10257c478bd9Sstevel@tonic-gate         }
10267c478bd9Sstevel@tonic-gate         sqliteFree(zTName);
10277c478bd9Sstevel@tonic-gate       }
10287c478bd9Sstevel@tonic-gate     }
10297c478bd9Sstevel@tonic-gate     sqliteExprListDelete(pEList);
10307c478bd9Sstevel@tonic-gate     p->pEList = pNew;
10317c478bd9Sstevel@tonic-gate   }
10327c478bd9Sstevel@tonic-gate   return rc;
10337c478bd9Sstevel@tonic-gate }
10347c478bd9Sstevel@tonic-gate 
10357c478bd9Sstevel@tonic-gate /*
10367c478bd9Sstevel@tonic-gate ** This routine recursively unlinks the Select.pSrc.a[].pTab pointers
10377c478bd9Sstevel@tonic-gate ** in a select structure.  It just sets the pointers to NULL.  This
10387c478bd9Sstevel@tonic-gate ** routine is recursive in the sense that if the Select.pSrc.a[].pSelect
10397c478bd9Sstevel@tonic-gate ** pointer is not NULL, this routine is called recursively on that pointer.
10407c478bd9Sstevel@tonic-gate **
10417c478bd9Sstevel@tonic-gate ** This routine is called on the Select structure that defines a
10427c478bd9Sstevel@tonic-gate ** VIEW in order to undo any bindings to tables.  This is necessary
10437c478bd9Sstevel@tonic-gate ** because those tables might be DROPed by a subsequent SQL command.
10447c478bd9Sstevel@tonic-gate ** If the bindings are not removed, then the Select.pSrc->a[].pTab field
10457c478bd9Sstevel@tonic-gate ** will be left pointing to a deallocated Table structure after the
10467c478bd9Sstevel@tonic-gate ** DROP and a coredump will occur the next time the VIEW is used.
10477c478bd9Sstevel@tonic-gate */
sqliteSelectUnbind(Select * p)10487c478bd9Sstevel@tonic-gate void sqliteSelectUnbind(Select *p){
10497c478bd9Sstevel@tonic-gate   int i;
10507c478bd9Sstevel@tonic-gate   SrcList *pSrc = p->pSrc;
10517c478bd9Sstevel@tonic-gate   Table *pTab;
10527c478bd9Sstevel@tonic-gate   if( p==0 ) return;
10537c478bd9Sstevel@tonic-gate   for(i=0; i<pSrc->nSrc; i++){
10547c478bd9Sstevel@tonic-gate     if( (pTab = pSrc->a[i].pTab)!=0 ){
10557c478bd9Sstevel@tonic-gate       if( pTab->isTransient ){
10567c478bd9Sstevel@tonic-gate         sqliteDeleteTable(0, pTab);
10577c478bd9Sstevel@tonic-gate       }
10587c478bd9Sstevel@tonic-gate       pSrc->a[i].pTab = 0;
10597c478bd9Sstevel@tonic-gate       if( pSrc->a[i].pSelect ){
10607c478bd9Sstevel@tonic-gate         sqliteSelectUnbind(pSrc->a[i].pSelect);
10617c478bd9Sstevel@tonic-gate       }
10627c478bd9Sstevel@tonic-gate     }
10637c478bd9Sstevel@tonic-gate   }
10647c478bd9Sstevel@tonic-gate }
10657c478bd9Sstevel@tonic-gate 
10667c478bd9Sstevel@tonic-gate /*
10677c478bd9Sstevel@tonic-gate ** This routine associates entries in an ORDER BY expression list with
10687c478bd9Sstevel@tonic-gate ** columns in a result.  For each ORDER BY expression, the opcode of
10697c478bd9Sstevel@tonic-gate ** the top-level node is changed to TK_COLUMN and the iColumn value of
10707c478bd9Sstevel@tonic-gate ** the top-level node is filled in with column number and the iTable
10717c478bd9Sstevel@tonic-gate ** value of the top-level node is filled with iTable parameter.
10727c478bd9Sstevel@tonic-gate **
10737c478bd9Sstevel@tonic-gate ** If there are prior SELECT clauses, they are processed first.  A match
10747c478bd9Sstevel@tonic-gate ** in an earlier SELECT takes precedence over a later SELECT.
10757c478bd9Sstevel@tonic-gate **
10767c478bd9Sstevel@tonic-gate ** Any entry that does not match is flagged as an error.  The number
10777c478bd9Sstevel@tonic-gate ** of errors is returned.
10787c478bd9Sstevel@tonic-gate **
10797c478bd9Sstevel@tonic-gate ** This routine does NOT correctly initialize the Expr.dataType  field
10807c478bd9Sstevel@tonic-gate ** of the ORDER BY expressions.  The multiSelectSortOrder() routine
10817c478bd9Sstevel@tonic-gate ** must be called to do that after the individual select statements
10827c478bd9Sstevel@tonic-gate ** have all been analyzed.  This routine is unable to compute Expr.dataType
10837c478bd9Sstevel@tonic-gate ** because it must be called before the individual select statements
10847c478bd9Sstevel@tonic-gate ** have been analyzed.
10857c478bd9Sstevel@tonic-gate */
matchOrderbyToColumn(Parse * pParse,Select * pSelect,ExprList * pOrderBy,int iTable,int mustComplete)10867c478bd9Sstevel@tonic-gate static int matchOrderbyToColumn(
10877c478bd9Sstevel@tonic-gate   Parse *pParse,          /* A place to leave error messages */
10887c478bd9Sstevel@tonic-gate   Select *pSelect,        /* Match to result columns of this SELECT */
10897c478bd9Sstevel@tonic-gate   ExprList *pOrderBy,     /* The ORDER BY values to match against columns */
10907c478bd9Sstevel@tonic-gate   int iTable,             /* Insert this value in iTable */
10917c478bd9Sstevel@tonic-gate   int mustComplete        /* If TRUE all ORDER BYs must match */
10927c478bd9Sstevel@tonic-gate ){
10937c478bd9Sstevel@tonic-gate   int nErr = 0;
10947c478bd9Sstevel@tonic-gate   int i, j;
10957c478bd9Sstevel@tonic-gate   ExprList *pEList;
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate   if( pSelect==0 || pOrderBy==0 ) return 1;
10987c478bd9Sstevel@tonic-gate   if( mustComplete ){
10997c478bd9Sstevel@tonic-gate     for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; }
11007c478bd9Sstevel@tonic-gate   }
11017c478bd9Sstevel@tonic-gate   if( fillInColumnList(pParse, pSelect) ){
11027c478bd9Sstevel@tonic-gate     return 1;
11037c478bd9Sstevel@tonic-gate   }
11047c478bd9Sstevel@tonic-gate   if( pSelect->pPrior ){
11057c478bd9Sstevel@tonic-gate     if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){
11067c478bd9Sstevel@tonic-gate       return 1;
11077c478bd9Sstevel@tonic-gate     }
11087c478bd9Sstevel@tonic-gate   }
11097c478bd9Sstevel@tonic-gate   pEList = pSelect->pEList;
11107c478bd9Sstevel@tonic-gate   for(i=0; i<pOrderBy->nExpr; i++){
11117c478bd9Sstevel@tonic-gate     Expr *pE = pOrderBy->a[i].pExpr;
11127c478bd9Sstevel@tonic-gate     int iCol = -1;
11137c478bd9Sstevel@tonic-gate     if( pOrderBy->a[i].done ) continue;
11147c478bd9Sstevel@tonic-gate     if( sqliteExprIsInteger(pE, &iCol) ){
11157c478bd9Sstevel@tonic-gate       if( iCol<=0 || iCol>pEList->nExpr ){
11167c478bd9Sstevel@tonic-gate         sqliteErrorMsg(pParse,
11177c478bd9Sstevel@tonic-gate           "ORDER BY position %d should be between 1 and %d",
11187c478bd9Sstevel@tonic-gate           iCol, pEList->nExpr);
11197c478bd9Sstevel@tonic-gate         nErr++;
11207c478bd9Sstevel@tonic-gate         break;
11217c478bd9Sstevel@tonic-gate       }
11227c478bd9Sstevel@tonic-gate       if( !mustComplete ) continue;
11237c478bd9Sstevel@tonic-gate       iCol--;
11247c478bd9Sstevel@tonic-gate     }
11257c478bd9Sstevel@tonic-gate     for(j=0; iCol<0 && j<pEList->nExpr; j++){
11267c478bd9Sstevel@tonic-gate       if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
11277c478bd9Sstevel@tonic-gate         char *zName, *zLabel;
11287c478bd9Sstevel@tonic-gate         zName = pEList->a[j].zName;
11297c478bd9Sstevel@tonic-gate         assert( pE->token.z );
11307c478bd9Sstevel@tonic-gate         zLabel = sqliteStrNDup(pE->token.z, pE->token.n);
11317c478bd9Sstevel@tonic-gate         sqliteDequote(zLabel);
1132*55fea89dSDan Cross         if( sqliteStrICmp(zName, zLabel)==0 ){
11337c478bd9Sstevel@tonic-gate           iCol = j;
11347c478bd9Sstevel@tonic-gate         }
11357c478bd9Sstevel@tonic-gate         sqliteFree(zLabel);
11367c478bd9Sstevel@tonic-gate       }
11377c478bd9Sstevel@tonic-gate       if( iCol<0 && sqliteExprCompare(pE, pEList->a[j].pExpr) ){
11387c478bd9Sstevel@tonic-gate         iCol = j;
11397c478bd9Sstevel@tonic-gate       }
11407c478bd9Sstevel@tonic-gate     }
11417c478bd9Sstevel@tonic-gate     if( iCol>=0 ){
11427c478bd9Sstevel@tonic-gate       pE->op = TK_COLUMN;
11437c478bd9Sstevel@tonic-gate       pE->iColumn = iCol;
11447c478bd9Sstevel@tonic-gate       pE->iTable = iTable;
11457c478bd9Sstevel@tonic-gate       pOrderBy->a[i].done = 1;
11467c478bd9Sstevel@tonic-gate     }
11477c478bd9Sstevel@tonic-gate     if( iCol<0 && mustComplete ){
11487c478bd9Sstevel@tonic-gate       sqliteErrorMsg(pParse,
11497c478bd9Sstevel@tonic-gate         "ORDER BY term number %d does not match any result column", i+1);
11507c478bd9Sstevel@tonic-gate       nErr++;
11517c478bd9Sstevel@tonic-gate       break;
11527c478bd9Sstevel@tonic-gate     }
11537c478bd9Sstevel@tonic-gate   }
1154*55fea89dSDan Cross   return nErr;
11557c478bd9Sstevel@tonic-gate }
11567c478bd9Sstevel@tonic-gate 
11577c478bd9Sstevel@tonic-gate /*
11587c478bd9Sstevel@tonic-gate ** Get a VDBE for the given parser context.  Create a new one if necessary.
11597c478bd9Sstevel@tonic-gate ** If an error occurs, return NULL and leave a message in pParse.
11607c478bd9Sstevel@tonic-gate */
sqliteGetVdbe(Parse * pParse)11617c478bd9Sstevel@tonic-gate Vdbe *sqliteGetVdbe(Parse *pParse){
11627c478bd9Sstevel@tonic-gate   Vdbe *v = pParse->pVdbe;
11637c478bd9Sstevel@tonic-gate   if( v==0 ){
11647c478bd9Sstevel@tonic-gate     v = pParse->pVdbe = sqliteVdbeCreate(pParse->db);
11657c478bd9Sstevel@tonic-gate   }
11667c478bd9Sstevel@tonic-gate   return v;
11677c478bd9Sstevel@tonic-gate }
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate /*
11707c478bd9Sstevel@tonic-gate ** This routine sets the Expr.dataType field on all elements of
11717c478bd9Sstevel@tonic-gate ** the pOrderBy expression list.  The pOrderBy list will have been
11727c478bd9Sstevel@tonic-gate ** set up by matchOrderbyToColumn().  Hence each expression has
1173*55fea89dSDan Cross ** a TK_COLUMN as its root node.  The Expr.iColumn refers to a
11747c478bd9Sstevel@tonic-gate ** column in the result set.   The datatype is set to SQLITE_SO_TEXT
11757c478bd9Sstevel@tonic-gate ** if the corresponding column in p and every SELECT to the left of
11767c478bd9Sstevel@tonic-gate ** p has a datatype of SQLITE_SO_TEXT.  If the cooressponding column
11777c478bd9Sstevel@tonic-gate ** in p or any of the left SELECTs is SQLITE_SO_NUM, then the datatype
11787c478bd9Sstevel@tonic-gate ** of the order-by expression is set to SQLITE_SO_NUM.
11797c478bd9Sstevel@tonic-gate **
11807c478bd9Sstevel@tonic-gate ** Examples:
11817c478bd9Sstevel@tonic-gate **
11827c478bd9Sstevel@tonic-gate **     CREATE TABLE one(a INTEGER, b TEXT);
11837c478bd9Sstevel@tonic-gate **     CREATE TABLE two(c VARCHAR(5), d FLOAT);
11847c478bd9Sstevel@tonic-gate **
11857c478bd9Sstevel@tonic-gate **     SELECT b, b FROM one UNION SELECT d, c FROM two ORDER BY 1, 2;
11867c478bd9Sstevel@tonic-gate **
11877c478bd9Sstevel@tonic-gate ** The primary sort key will use SQLITE_SO_NUM because the "d" in
11887c478bd9Sstevel@tonic-gate ** the second SELECT is numeric.  The 1st column of the first SELECT
11897c478bd9Sstevel@tonic-gate ** is text but that does not matter because a numeric always overrides
11907c478bd9Sstevel@tonic-gate ** a text.
11917c478bd9Sstevel@tonic-gate **
11927c478bd9Sstevel@tonic-gate ** The secondary key will use the SQLITE_SO_TEXT sort order because
11937c478bd9Sstevel@tonic-gate ** both the (second) "b" in the first SELECT and the "c" in the second
11947c478bd9Sstevel@tonic-gate ** SELECT have a datatype of text.
1195*55fea89dSDan Cross */
multiSelectSortOrder(Select * p,ExprList * pOrderBy)11967c478bd9Sstevel@tonic-gate static void multiSelectSortOrder(Select *p, ExprList *pOrderBy){
11977c478bd9Sstevel@tonic-gate   int i;
11987c478bd9Sstevel@tonic-gate   ExprList *pEList;
11997c478bd9Sstevel@tonic-gate   if( pOrderBy==0 ) return;
12007c478bd9Sstevel@tonic-gate   if( p==0 ){
12017c478bd9Sstevel@tonic-gate     for(i=0; i<pOrderBy->nExpr; i++){
12027c478bd9Sstevel@tonic-gate       pOrderBy->a[i].pExpr->dataType = SQLITE_SO_TEXT;
12037c478bd9Sstevel@tonic-gate     }
12047c478bd9Sstevel@tonic-gate     return;
12057c478bd9Sstevel@tonic-gate   }
12067c478bd9Sstevel@tonic-gate   multiSelectSortOrder(p->pPrior, pOrderBy);
12077c478bd9Sstevel@tonic-gate   pEList = p->pEList;
12087c478bd9Sstevel@tonic-gate   for(i=0; i<pOrderBy->nExpr; i++){
12097c478bd9Sstevel@tonic-gate     Expr *pE = pOrderBy->a[i].pExpr;
12107c478bd9Sstevel@tonic-gate     if( pE->dataType==SQLITE_SO_NUM ) continue;
12117c478bd9Sstevel@tonic-gate     assert( pE->iColumn>=0 );
12127c478bd9Sstevel@tonic-gate     if( pEList->nExpr>pE->iColumn ){
12137c478bd9Sstevel@tonic-gate       pE->dataType = sqliteExprType(pEList->a[pE->iColumn].pExpr);
12147c478bd9Sstevel@tonic-gate     }
12157c478bd9Sstevel@tonic-gate   }
12167c478bd9Sstevel@tonic-gate }
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate /*
12197c478bd9Sstevel@tonic-gate ** Compute the iLimit and iOffset fields of the SELECT based on the
12207c478bd9Sstevel@tonic-gate ** nLimit and nOffset fields.  nLimit and nOffset hold the integers
12217c478bd9Sstevel@tonic-gate ** that appear in the original SQL statement after the LIMIT and OFFSET
12227c478bd9Sstevel@tonic-gate ** keywords.  Or that hold -1 and 0 if those keywords are omitted.
12237c478bd9Sstevel@tonic-gate ** iLimit and iOffset are the integer memory register numbers for
12247c478bd9Sstevel@tonic-gate ** counters used to compute the limit and offset.  If there is no
12257c478bd9Sstevel@tonic-gate ** limit and/or offset, then iLimit and iOffset are negative.
12267c478bd9Sstevel@tonic-gate **
12277c478bd9Sstevel@tonic-gate ** This routine changes the values if iLimit and iOffset only if
12287c478bd9Sstevel@tonic-gate ** a limit or offset is defined by nLimit and nOffset.  iLimit and
12297c478bd9Sstevel@tonic-gate ** iOffset should have been preset to appropriate default values
12307c478bd9Sstevel@tonic-gate ** (usually but not always -1) prior to calling this routine.
12317c478bd9Sstevel@tonic-gate ** Only if nLimit>=0 or nOffset>0 do the limit registers get
12327c478bd9Sstevel@tonic-gate ** redefined.  The UNION ALL operator uses this property to force
12337c478bd9Sstevel@tonic-gate ** the reuse of the same limit and offset registers across multiple
12347c478bd9Sstevel@tonic-gate ** SELECT statements.
12357c478bd9Sstevel@tonic-gate */
computeLimitRegisters(Parse * pParse,Select * p)12367c478bd9Sstevel@tonic-gate static void computeLimitRegisters(Parse *pParse, Select *p){
1237*55fea89dSDan Cross   /*
12387c478bd9Sstevel@tonic-gate   ** If the comparison is p->nLimit>0 then "LIMIT 0" shows
12397c478bd9Sstevel@tonic-gate   ** all rows.  It is the same as no limit. If the comparision is
12407c478bd9Sstevel@tonic-gate   ** p->nLimit>=0 then "LIMIT 0" show no rows at all.
12417c478bd9Sstevel@tonic-gate   ** "LIMIT -1" always shows all rows.  There is some
12427c478bd9Sstevel@tonic-gate   ** contraversy about what the correct behavior should be.
12437c478bd9Sstevel@tonic-gate   ** The current implementation interprets "LIMIT 0" to mean
12447c478bd9Sstevel@tonic-gate   ** no rows.
12457c478bd9Sstevel@tonic-gate   */
12467c478bd9Sstevel@tonic-gate   if( p->nLimit>=0 ){
12477c478bd9Sstevel@tonic-gate     int iMem = pParse->nMem++;
12487c478bd9Sstevel@tonic-gate     Vdbe *v = sqliteGetVdbe(pParse);
12497c478bd9Sstevel@tonic-gate     if( v==0 ) return;
12507c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Integer, -p->nLimit, 0);
12517c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MemStore, iMem, 1);
12527c478bd9Sstevel@tonic-gate     p->iLimit = iMem;
12537c478bd9Sstevel@tonic-gate   }
12547c478bd9Sstevel@tonic-gate   if( p->nOffset>0 ){
12557c478bd9Sstevel@tonic-gate     int iMem = pParse->nMem++;
12567c478bd9Sstevel@tonic-gate     Vdbe *v = sqliteGetVdbe(pParse);
12577c478bd9Sstevel@tonic-gate     if( v==0 ) return;
12587c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Integer, -p->nOffset, 0);
12597c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MemStore, iMem, 1);
12607c478bd9Sstevel@tonic-gate     p->iOffset = iMem;
12617c478bd9Sstevel@tonic-gate   }
12627c478bd9Sstevel@tonic-gate }
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate /*
12657c478bd9Sstevel@tonic-gate ** This routine is called to process a query that is really the union
12667c478bd9Sstevel@tonic-gate ** or intersection of two or more separate queries.
12677c478bd9Sstevel@tonic-gate **
12687c478bd9Sstevel@tonic-gate ** "p" points to the right-most of the two queries.  the query on the
12697c478bd9Sstevel@tonic-gate ** left is p->pPrior.  The left query could also be a compound query
1270*55fea89dSDan Cross ** in which case this routine will be called recursively.
12717c478bd9Sstevel@tonic-gate **
12727c478bd9Sstevel@tonic-gate ** The results of the total query are to be written into a destination
12737c478bd9Sstevel@tonic-gate ** of type eDest with parameter iParm.
12747c478bd9Sstevel@tonic-gate **
12757c478bd9Sstevel@tonic-gate ** Example 1:  Consider a three-way compound SQL statement.
12767c478bd9Sstevel@tonic-gate **
12777c478bd9Sstevel@tonic-gate **     SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
12787c478bd9Sstevel@tonic-gate **
12797c478bd9Sstevel@tonic-gate ** This statement is parsed up as follows:
12807c478bd9Sstevel@tonic-gate **
12817c478bd9Sstevel@tonic-gate **     SELECT c FROM t3
12827c478bd9Sstevel@tonic-gate **      |
12837c478bd9Sstevel@tonic-gate **      `----->  SELECT b FROM t2
12847c478bd9Sstevel@tonic-gate **                |
12857c478bd9Sstevel@tonic-gate **                `------>  SELECT a FROM t1
12867c478bd9Sstevel@tonic-gate **
12877c478bd9Sstevel@tonic-gate ** The arrows in the diagram above represent the Select.pPrior pointer.
12887c478bd9Sstevel@tonic-gate ** So if this routine is called with p equal to the t3 query, then
12897c478bd9Sstevel@tonic-gate ** pPrior will be the t2 query.  p->op will be TK_UNION in this case.
12907c478bd9Sstevel@tonic-gate **
12917c478bd9Sstevel@tonic-gate ** Notice that because of the way SQLite parses compound SELECTs, the
12927c478bd9Sstevel@tonic-gate ** individual selects always group from left to right.
12937c478bd9Sstevel@tonic-gate */
multiSelect(Parse * pParse,Select * p,int eDest,int iParm)12947c478bd9Sstevel@tonic-gate static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
12957c478bd9Sstevel@tonic-gate   int rc;             /* Success code from a subroutine */
12967c478bd9Sstevel@tonic-gate   Select *pPrior;     /* Another SELECT immediately to our left */
12977c478bd9Sstevel@tonic-gate   Vdbe *v;            /* Generate code to this VDBE */
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate   /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
13007c478bd9Sstevel@tonic-gate   ** the last SELECT in the series may have an ORDER BY or LIMIT.
13017c478bd9Sstevel@tonic-gate   */
13027c478bd9Sstevel@tonic-gate   if( p==0 || p->pPrior==0 ) return 1;
13037c478bd9Sstevel@tonic-gate   pPrior = p->pPrior;
13047c478bd9Sstevel@tonic-gate   if( pPrior->pOrderBy ){
13057c478bd9Sstevel@tonic-gate     sqliteErrorMsg(pParse,"ORDER BY clause should come after %s not before",
13067c478bd9Sstevel@tonic-gate       selectOpName(p->op));
13077c478bd9Sstevel@tonic-gate     return 1;
13087c478bd9Sstevel@tonic-gate   }
13097c478bd9Sstevel@tonic-gate   if( pPrior->nLimit>=0 || pPrior->nOffset>0 ){
13107c478bd9Sstevel@tonic-gate     sqliteErrorMsg(pParse,"LIMIT clause should come after %s not before",
13117c478bd9Sstevel@tonic-gate       selectOpName(p->op));
13127c478bd9Sstevel@tonic-gate     return 1;
13137c478bd9Sstevel@tonic-gate   }
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate   /* Make sure we have a valid query engine.  If not, create a new one.
13167c478bd9Sstevel@tonic-gate   */
13177c478bd9Sstevel@tonic-gate   v = sqliteGetVdbe(pParse);
13187c478bd9Sstevel@tonic-gate   if( v==0 ) return 1;
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate   /* Create the destination temporary table if necessary
13217c478bd9Sstevel@tonic-gate   */
13227c478bd9Sstevel@tonic-gate   if( eDest==SRT_TempTable ){
13237c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
13247c478bd9Sstevel@tonic-gate     eDest = SRT_Table;
13257c478bd9Sstevel@tonic-gate   }
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate   /* Generate code for the left and right SELECT statements.
13287c478bd9Sstevel@tonic-gate   */
13297c478bd9Sstevel@tonic-gate   switch( p->op ){
13307c478bd9Sstevel@tonic-gate     case TK_ALL: {
13317c478bd9Sstevel@tonic-gate       if( p->pOrderBy==0 ){
13327c478bd9Sstevel@tonic-gate         pPrior->nLimit = p->nLimit;
13337c478bd9Sstevel@tonic-gate         pPrior->nOffset = p->nOffset;
13347c478bd9Sstevel@tonic-gate         rc = sqliteSelect(pParse, pPrior, eDest, iParm, 0, 0, 0);
13357c478bd9Sstevel@tonic-gate         if( rc ) return rc;
13367c478bd9Sstevel@tonic-gate         p->pPrior = 0;
13377c478bd9Sstevel@tonic-gate         p->iLimit = pPrior->iLimit;
13387c478bd9Sstevel@tonic-gate         p->iOffset = pPrior->iOffset;
13397c478bd9Sstevel@tonic-gate         p->nLimit = -1;
13407c478bd9Sstevel@tonic-gate         p->nOffset = 0;
13417c478bd9Sstevel@tonic-gate         rc = sqliteSelect(pParse, p, eDest, iParm, 0, 0, 0);
13427c478bd9Sstevel@tonic-gate         p->pPrior = pPrior;
13437c478bd9Sstevel@tonic-gate         if( rc ) return rc;
13447c478bd9Sstevel@tonic-gate         break;
13457c478bd9Sstevel@tonic-gate       }
13467c478bd9Sstevel@tonic-gate     }
134788e1588bSToomas Soome     /* FALLTHROUGH */
13487c478bd9Sstevel@tonic-gate     case TK_EXCEPT:
13497c478bd9Sstevel@tonic-gate     case TK_UNION: {
13507c478bd9Sstevel@tonic-gate       int unionTab;    /* Cursor number of the temporary table holding result */
13517c478bd9Sstevel@tonic-gate       int op;          /* One of the SRT_ operations to apply to self */
13527c478bd9Sstevel@tonic-gate       int priorOp;     /* The SRT_ operation to apply to prior selects */
13537c478bd9Sstevel@tonic-gate       int nLimit, nOffset; /* Saved values of p->nLimit and p->nOffset */
13547c478bd9Sstevel@tonic-gate       ExprList *pOrderBy;  /* The ORDER BY clause for the right SELECT */
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate       priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
13577c478bd9Sstevel@tonic-gate       if( eDest==priorOp && p->pOrderBy==0 && p->nLimit<0 && p->nOffset==0 ){
13587c478bd9Sstevel@tonic-gate         /* We can reuse a temporary table generated by a SELECT to our
13597c478bd9Sstevel@tonic-gate         ** right.
13607c478bd9Sstevel@tonic-gate         */
13617c478bd9Sstevel@tonic-gate         unionTab = iParm;
13627c478bd9Sstevel@tonic-gate       }else{
13637c478bd9Sstevel@tonic-gate         /* We will need to create our own temporary table to hold the
13647c478bd9Sstevel@tonic-gate         ** intermediate results.
13657c478bd9Sstevel@tonic-gate         */
13667c478bd9Sstevel@tonic-gate         unionTab = pParse->nTab++;
1367*55fea89dSDan Cross         if( p->pOrderBy
13687c478bd9Sstevel@tonic-gate         && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){
13697c478bd9Sstevel@tonic-gate           return 1;
13707c478bd9Sstevel@tonic-gate         }
13717c478bd9Sstevel@tonic-gate         if( p->op!=TK_ALL ){
13727c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 1);
13737c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1);
13747c478bd9Sstevel@tonic-gate         }else{
13757c478bd9Sstevel@tonic-gate           sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0);
13767c478bd9Sstevel@tonic-gate         }
13777c478bd9Sstevel@tonic-gate       }
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate       /* Code the SELECT statements to our left
13807c478bd9Sstevel@tonic-gate       */
13817c478bd9Sstevel@tonic-gate       rc = sqliteSelect(pParse, pPrior, priorOp, unionTab, 0, 0, 0);
13827c478bd9Sstevel@tonic-gate       if( rc ) return rc;
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate       /* Code the current SELECT statement
13857c478bd9Sstevel@tonic-gate       */
13867c478bd9Sstevel@tonic-gate       switch( p->op ){
13877c478bd9Sstevel@tonic-gate          case TK_EXCEPT:  op = SRT_Except;   break;
13887c478bd9Sstevel@tonic-gate          case TK_UNION:   op = SRT_Union;    break;
13897c478bd9Sstevel@tonic-gate          case TK_ALL:     op = SRT_Table;    break;
13907c478bd9Sstevel@tonic-gate       }
13917c478bd9Sstevel@tonic-gate       p->pPrior = 0;
13927c478bd9Sstevel@tonic-gate       pOrderBy = p->pOrderBy;
13937c478bd9Sstevel@tonic-gate       p->pOrderBy = 0;
13947c478bd9Sstevel@tonic-gate       nLimit = p->nLimit;
13957c478bd9Sstevel@tonic-gate       p->nLimit = -1;
13967c478bd9Sstevel@tonic-gate       nOffset = p->nOffset;
13977c478bd9Sstevel@tonic-gate       p->nOffset = 0;
13987c478bd9Sstevel@tonic-gate       rc = sqliteSelect(pParse, p, op, unionTab, 0, 0, 0);
13997c478bd9Sstevel@tonic-gate       p->pPrior = pPrior;
14007c478bd9Sstevel@tonic-gate       p->pOrderBy = pOrderBy;
14017c478bd9Sstevel@tonic-gate       p->nLimit = nLimit;
14027c478bd9Sstevel@tonic-gate       p->nOffset = nOffset;
14037c478bd9Sstevel@tonic-gate       if( rc ) return rc;
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate       /* Convert the data in the temporary table into whatever form
14067c478bd9Sstevel@tonic-gate       ** it is that we currently need.
1407*55fea89dSDan Cross       */
14087c478bd9Sstevel@tonic-gate       if( eDest!=priorOp || unionTab!=iParm ){
14097c478bd9Sstevel@tonic-gate         int iCont, iBreak, iStart;
14107c478bd9Sstevel@tonic-gate         assert( p->pEList );
14117c478bd9Sstevel@tonic-gate         if( eDest==SRT_Callback ){
14127c478bd9Sstevel@tonic-gate           generateColumnNames(pParse, 0, p->pEList);
14137c478bd9Sstevel@tonic-gate           generateColumnTypes(pParse, p->pSrc, p->pEList);
14147c478bd9Sstevel@tonic-gate         }
14157c478bd9Sstevel@tonic-gate         iBreak = sqliteVdbeMakeLabel(v);
14167c478bd9Sstevel@tonic-gate         iCont = sqliteVdbeMakeLabel(v);
14177c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Rewind, unionTab, iBreak);
14187c478bd9Sstevel@tonic-gate         computeLimitRegisters(pParse, p);
14197c478bd9Sstevel@tonic-gate         iStart = sqliteVdbeCurrentAddr(v);
14207c478bd9Sstevel@tonic-gate         multiSelectSortOrder(p, p->pOrderBy);
14217c478bd9Sstevel@tonic-gate         rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
1422*55fea89dSDan Cross                              p->pOrderBy, -1, eDest, iParm,
14237c478bd9Sstevel@tonic-gate                              iCont, iBreak);
14247c478bd9Sstevel@tonic-gate         if( rc ) return 1;
14257c478bd9Sstevel@tonic-gate         sqliteVdbeResolveLabel(v, iCont);
14267c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Next, unionTab, iStart);
14277c478bd9Sstevel@tonic-gate         sqliteVdbeResolveLabel(v, iBreak);
14287c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_Close, unionTab, 0);
14297c478bd9Sstevel@tonic-gate         if( p->pOrderBy ){
14307c478bd9Sstevel@tonic-gate           generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
14317c478bd9Sstevel@tonic-gate         }
14327c478bd9Sstevel@tonic-gate       }
14337c478bd9Sstevel@tonic-gate       break;
14347c478bd9Sstevel@tonic-gate     }
14357c478bd9Sstevel@tonic-gate     case TK_INTERSECT: {
14367c478bd9Sstevel@tonic-gate       int tab1, tab2;
14377c478bd9Sstevel@tonic-gate       int iCont, iBreak, iStart;
14387c478bd9Sstevel@tonic-gate       int nLimit, nOffset;
14397c478bd9Sstevel@tonic-gate 
14407c478bd9Sstevel@tonic-gate       /* INTERSECT is different from the others since it requires
14417c478bd9Sstevel@tonic-gate       ** two temporary tables.  Hence it has its own case.  Begin
14427c478bd9Sstevel@tonic-gate       ** by allocating the tables we will need.
14437c478bd9Sstevel@tonic-gate       */
14447c478bd9Sstevel@tonic-gate       tab1 = pParse->nTab++;
14457c478bd9Sstevel@tonic-gate       tab2 = pParse->nTab++;
14467c478bd9Sstevel@tonic-gate       if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
14477c478bd9Sstevel@tonic-gate         return 1;
14487c478bd9Sstevel@tonic-gate       }
14497c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 1);
14507c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1);
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate       /* Code the SELECTs to our left into temporary table "tab1".
14537c478bd9Sstevel@tonic-gate       */
14547c478bd9Sstevel@tonic-gate       rc = sqliteSelect(pParse, pPrior, SRT_Union, tab1, 0, 0, 0);
14557c478bd9Sstevel@tonic-gate       if( rc ) return rc;
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate       /* Code the current SELECT into temporary table "tab2"
14587c478bd9Sstevel@tonic-gate       */
14597c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 1);
14607c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1);
14617c478bd9Sstevel@tonic-gate       p->pPrior = 0;
14627c478bd9Sstevel@tonic-gate       nLimit = p->nLimit;
14637c478bd9Sstevel@tonic-gate       p->nLimit = -1;
14647c478bd9Sstevel@tonic-gate       nOffset = p->nOffset;
14657c478bd9Sstevel@tonic-gate       p->nOffset = 0;
14667c478bd9Sstevel@tonic-gate       rc = sqliteSelect(pParse, p, SRT_Union, tab2, 0, 0, 0);
14677c478bd9Sstevel@tonic-gate       p->pPrior = pPrior;
14687c478bd9Sstevel@tonic-gate       p->nLimit = nLimit;
14697c478bd9Sstevel@tonic-gate       p->nOffset = nOffset;
14707c478bd9Sstevel@tonic-gate       if( rc ) return rc;
14717c478bd9Sstevel@tonic-gate 
14727c478bd9Sstevel@tonic-gate       /* Generate code to take the intersection of the two temporary
14737c478bd9Sstevel@tonic-gate       ** tables.
14747c478bd9Sstevel@tonic-gate       */
14757c478bd9Sstevel@tonic-gate       assert( p->pEList );
14767c478bd9Sstevel@tonic-gate       if( eDest==SRT_Callback ){
14777c478bd9Sstevel@tonic-gate         generateColumnNames(pParse, 0, p->pEList);
14787c478bd9Sstevel@tonic-gate         generateColumnTypes(pParse, p->pSrc, p->pEList);
14797c478bd9Sstevel@tonic-gate       }
14807c478bd9Sstevel@tonic-gate       iBreak = sqliteVdbeMakeLabel(v);
14817c478bd9Sstevel@tonic-gate       iCont = sqliteVdbeMakeLabel(v);
14827c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Rewind, tab1, iBreak);
14837c478bd9Sstevel@tonic-gate       computeLimitRegisters(pParse, p);
14847c478bd9Sstevel@tonic-gate       iStart = sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
14857c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
14867c478bd9Sstevel@tonic-gate       multiSelectSortOrder(p, p->pOrderBy);
14877c478bd9Sstevel@tonic-gate       rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
1488*55fea89dSDan Cross                              p->pOrderBy, -1, eDest, iParm,
14897c478bd9Sstevel@tonic-gate                              iCont, iBreak);
14907c478bd9Sstevel@tonic-gate       if( rc ) return 1;
14917c478bd9Sstevel@tonic-gate       sqliteVdbeResolveLabel(v, iCont);
14927c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Next, tab1, iStart);
14937c478bd9Sstevel@tonic-gate       sqliteVdbeResolveLabel(v, iBreak);
14947c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Close, tab2, 0);
14957c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Close, tab1, 0);
14967c478bd9Sstevel@tonic-gate       if( p->pOrderBy ){
14977c478bd9Sstevel@tonic-gate         generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
14987c478bd9Sstevel@tonic-gate       }
14997c478bd9Sstevel@tonic-gate       break;
15007c478bd9Sstevel@tonic-gate     }
15017c478bd9Sstevel@tonic-gate   }
15027c478bd9Sstevel@tonic-gate   assert( p->pEList && pPrior->pEList );
15037c478bd9Sstevel@tonic-gate   if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
15047c478bd9Sstevel@tonic-gate     sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
15057c478bd9Sstevel@tonic-gate       " do not have the same number of result columns", selectOpName(p->op));
15067c478bd9Sstevel@tonic-gate     return 1;
15077c478bd9Sstevel@tonic-gate   }
15087c478bd9Sstevel@tonic-gate   return 0;
15097c478bd9Sstevel@tonic-gate }
15107c478bd9Sstevel@tonic-gate 
15117c478bd9Sstevel@tonic-gate /*
15127c478bd9Sstevel@tonic-gate ** Scan through the expression pExpr.  Replace every reference to
15137c478bd9Sstevel@tonic-gate ** a column in table number iTable with a copy of the iColumn-th
1514*55fea89dSDan Cross ** entry in pEList.  (But leave references to the ROWID column
15157c478bd9Sstevel@tonic-gate ** unchanged.)
15167c478bd9Sstevel@tonic-gate **
15177c478bd9Sstevel@tonic-gate ** This routine is part of the flattening procedure.  A subquery
15187c478bd9Sstevel@tonic-gate ** whose result set is defined by pEList appears as entry in the
15197c478bd9Sstevel@tonic-gate ** FROM clause of a SELECT such that the VDBE cursor assigned to that
1520*55fea89dSDan Cross ** FORM clause entry is iTable.  This routine make the necessary
15217c478bd9Sstevel@tonic-gate ** changes to pExpr so that it refers directly to the source table
15227c478bd9Sstevel@tonic-gate ** of the subquery rather the result set of the subquery.
15237c478bd9Sstevel@tonic-gate */
15247c478bd9Sstevel@tonic-gate static void substExprList(ExprList*,int,ExprList*);  /* Forward Decl */
substExpr(Expr * pExpr,int iTable,ExprList * pEList)15257c478bd9Sstevel@tonic-gate static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){
15267c478bd9Sstevel@tonic-gate   if( pExpr==0 ) return;
15277c478bd9Sstevel@tonic-gate   if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
15287c478bd9Sstevel@tonic-gate     if( pExpr->iColumn<0 ){
15297c478bd9Sstevel@tonic-gate       pExpr->op = TK_NULL;
15307c478bd9Sstevel@tonic-gate     }else{
15317c478bd9Sstevel@tonic-gate       Expr *pNew;
15327c478bd9Sstevel@tonic-gate       assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
15337c478bd9Sstevel@tonic-gate       assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
15347c478bd9Sstevel@tonic-gate       pNew = pEList->a[pExpr->iColumn].pExpr;
15357c478bd9Sstevel@tonic-gate       assert( pNew!=0 );
15367c478bd9Sstevel@tonic-gate       pExpr->op = pNew->op;
15377c478bd9Sstevel@tonic-gate       pExpr->dataType = pNew->dataType;
15387c478bd9Sstevel@tonic-gate       assert( pExpr->pLeft==0 );
15397c478bd9Sstevel@tonic-gate       pExpr->pLeft = sqliteExprDup(pNew->pLeft);
15407c478bd9Sstevel@tonic-gate       assert( pExpr->pRight==0 );
15417c478bd9Sstevel@tonic-gate       pExpr->pRight = sqliteExprDup(pNew->pRight);
15427c478bd9Sstevel@tonic-gate       assert( pExpr->pList==0 );
15437c478bd9Sstevel@tonic-gate       pExpr->pList = sqliteExprListDup(pNew->pList);
15447c478bd9Sstevel@tonic-gate       pExpr->iTable = pNew->iTable;
15457c478bd9Sstevel@tonic-gate       pExpr->iColumn = pNew->iColumn;
15467c478bd9Sstevel@tonic-gate       pExpr->iAgg = pNew->iAgg;
15477c478bd9Sstevel@tonic-gate       sqliteTokenCopy(&pExpr->token, &pNew->token);
15487c478bd9Sstevel@tonic-gate       sqliteTokenCopy(&pExpr->span, &pNew->span);
15497c478bd9Sstevel@tonic-gate     }
15507c478bd9Sstevel@tonic-gate   }else{
15517c478bd9Sstevel@tonic-gate     substExpr(pExpr->pLeft, iTable, pEList);
15527c478bd9Sstevel@tonic-gate     substExpr(pExpr->pRight, iTable, pEList);
15537c478bd9Sstevel@tonic-gate     substExprList(pExpr->pList, iTable, pEList);
15547c478bd9Sstevel@tonic-gate   }
15557c478bd9Sstevel@tonic-gate }
1556*55fea89dSDan Cross static void
substExprList(ExprList * pList,int iTable,ExprList * pEList)15577c478bd9Sstevel@tonic-gate substExprList(ExprList *pList, int iTable, ExprList *pEList){
15587c478bd9Sstevel@tonic-gate   int i;
15597c478bd9Sstevel@tonic-gate   if( pList==0 ) return;
15607c478bd9Sstevel@tonic-gate   for(i=0; i<pList->nExpr; i++){
15617c478bd9Sstevel@tonic-gate     substExpr(pList->a[i].pExpr, iTable, pEList);
15627c478bd9Sstevel@tonic-gate   }
15637c478bd9Sstevel@tonic-gate }
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate /*
15667c478bd9Sstevel@tonic-gate ** This routine attempts to flatten subqueries in order to speed
15677c478bd9Sstevel@tonic-gate ** execution.  It returns 1 if it makes changes and 0 if no flattening
15687c478bd9Sstevel@tonic-gate ** occurs.
15697c478bd9Sstevel@tonic-gate **
15707c478bd9Sstevel@tonic-gate ** To understand the concept of flattening, consider the following
15717c478bd9Sstevel@tonic-gate ** query:
15727c478bd9Sstevel@tonic-gate **
15737c478bd9Sstevel@tonic-gate **     SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
15747c478bd9Sstevel@tonic-gate **
15757c478bd9Sstevel@tonic-gate ** The default way of implementing this query is to execute the
15767c478bd9Sstevel@tonic-gate ** subquery first and store the results in a temporary table, then
15777c478bd9Sstevel@tonic-gate ** run the outer query on that temporary table.  This requires two
15787c478bd9Sstevel@tonic-gate ** passes over the data.  Furthermore, because the temporary table
15797c478bd9Sstevel@tonic-gate ** has no indices, the WHERE clause on the outer query cannot be
15807c478bd9Sstevel@tonic-gate ** optimized.
15817c478bd9Sstevel@tonic-gate **
15827c478bd9Sstevel@tonic-gate ** This routine attempts to rewrite queries such as the above into
15837c478bd9Sstevel@tonic-gate ** a single flat select, like this:
15847c478bd9Sstevel@tonic-gate **
15857c478bd9Sstevel@tonic-gate **     SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
15867c478bd9Sstevel@tonic-gate **
15877c478bd9Sstevel@tonic-gate ** The code generated for this simpification gives the same result
1588*55fea89dSDan Cross ** but only has to scan the data once.  And because indices might
15897c478bd9Sstevel@tonic-gate ** exist on the table t1, a complete scan of the data might be
15907c478bd9Sstevel@tonic-gate ** avoided.
15917c478bd9Sstevel@tonic-gate **
15927c478bd9Sstevel@tonic-gate ** Flattening is only attempted if all of the following are true:
15937c478bd9Sstevel@tonic-gate **
15947c478bd9Sstevel@tonic-gate **   (1)  The subquery and the outer query do not both use aggregates.
15957c478bd9Sstevel@tonic-gate **
15967c478bd9Sstevel@tonic-gate **   (2)  The subquery is not an aggregate or the outer query is not a join.
15977c478bd9Sstevel@tonic-gate **
15987c478bd9Sstevel@tonic-gate **   (3)  The subquery is not the right operand of a left outer join, or
15997c478bd9Sstevel@tonic-gate **        the subquery is not itself a join.  (Ticket #306)
16007c478bd9Sstevel@tonic-gate **
16017c478bd9Sstevel@tonic-gate **   (4)  The subquery is not DISTINCT or the outer query is not a join.
16027c478bd9Sstevel@tonic-gate **
16037c478bd9Sstevel@tonic-gate **   (5)  The subquery is not DISTINCT or the outer query does not use
16047c478bd9Sstevel@tonic-gate **        aggregates.
16057c478bd9Sstevel@tonic-gate **
16067c478bd9Sstevel@tonic-gate **   (6)  The subquery does not use aggregates or the outer query is not
16077c478bd9Sstevel@tonic-gate **        DISTINCT.
16087c478bd9Sstevel@tonic-gate **
16097c478bd9Sstevel@tonic-gate **   (7)  The subquery has a FROM clause.
16107c478bd9Sstevel@tonic-gate **
16117c478bd9Sstevel@tonic-gate **   (8)  The subquery does not use LIMIT or the outer query is not a join.
16127c478bd9Sstevel@tonic-gate **
16137c478bd9Sstevel@tonic-gate **   (9)  The subquery does not use LIMIT or the outer query does not use
16147c478bd9Sstevel@tonic-gate **        aggregates.
16157c478bd9Sstevel@tonic-gate **
16167c478bd9Sstevel@tonic-gate **  (10)  The subquery does not use aggregates or the outer query does not
16177c478bd9Sstevel@tonic-gate **        use LIMIT.
16187c478bd9Sstevel@tonic-gate **
16197c478bd9Sstevel@tonic-gate **  (11)  The subquery and the outer query do not both have ORDER BY clauses.
16207c478bd9Sstevel@tonic-gate **
16217c478bd9Sstevel@tonic-gate **  (12)  The subquery is not the right term of a LEFT OUTER JOIN or the
16227c478bd9Sstevel@tonic-gate **        subquery has no WHERE clause.  (added by ticket #350)
16237c478bd9Sstevel@tonic-gate **
16247c478bd9Sstevel@tonic-gate ** In this routine, the "p" parameter is a pointer to the outer query.
16257c478bd9Sstevel@tonic-gate ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
16267c478bd9Sstevel@tonic-gate ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
16277c478bd9Sstevel@tonic-gate **
16287c478bd9Sstevel@tonic-gate ** If flattening is not attempted, this routine is a no-op and returns 0.
16297c478bd9Sstevel@tonic-gate ** If flattening is attempted this routine returns 1.
16307c478bd9Sstevel@tonic-gate **
16317c478bd9Sstevel@tonic-gate ** All of the expression analysis must occur on both the outer query and
16327c478bd9Sstevel@tonic-gate ** the subquery before this routine runs.
16337c478bd9Sstevel@tonic-gate */
flattenSubquery(Parse * pParse,Select * p,int iFrom,int isAgg,int subqueryIsAgg)16347c478bd9Sstevel@tonic-gate static int flattenSubquery(
16357c478bd9Sstevel@tonic-gate   Parse *pParse,       /* The parsing context */
16367c478bd9Sstevel@tonic-gate   Select *p,           /* The parent or outer SELECT statement */
16377c478bd9Sstevel@tonic-gate   int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
16387c478bd9Sstevel@tonic-gate   int isAgg,           /* True if outer SELECT uses aggregate functions */
16397c478bd9Sstevel@tonic-gate   int subqueryIsAgg    /* True if the subquery uses aggregate functions */
16407c478bd9Sstevel@tonic-gate ){
16417c478bd9Sstevel@tonic-gate   Select *pSub;       /* The inner query or "subquery" */
16427c478bd9Sstevel@tonic-gate   SrcList *pSrc;      /* The FROM clause of the outer query */
16437c478bd9Sstevel@tonic-gate   SrcList *pSubSrc;   /* The FROM clause of the subquery */
16447c478bd9Sstevel@tonic-gate   ExprList *pList;    /* The result set of the outer query */
16457c478bd9Sstevel@tonic-gate   int iParent;        /* VDBE cursor number of the pSub result set temp table */
16467c478bd9Sstevel@tonic-gate   int i;
16477c478bd9Sstevel@tonic-gate   Expr *pWhere;
16487c478bd9Sstevel@tonic-gate 
16497c478bd9Sstevel@tonic-gate   /* Check to see if flattening is permitted.  Return 0 if not.
16507c478bd9Sstevel@tonic-gate   */
16517c478bd9Sstevel@tonic-gate   if( p==0 ) return 0;
16527c478bd9Sstevel@tonic-gate   pSrc = p->pSrc;
16537c478bd9Sstevel@tonic-gate   assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
16547c478bd9Sstevel@tonic-gate   pSub = pSrc->a[iFrom].pSelect;
16557c478bd9Sstevel@tonic-gate   assert( pSub!=0 );
16567c478bd9Sstevel@tonic-gate   if( isAgg && subqueryIsAgg ) return 0;
16577c478bd9Sstevel@tonic-gate   if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
16587c478bd9Sstevel@tonic-gate   pSubSrc = pSub->pSrc;
16597c478bd9Sstevel@tonic-gate   assert( pSubSrc );
16607c478bd9Sstevel@tonic-gate   if( pSubSrc->nSrc==0 ) return 0;
16617c478bd9Sstevel@tonic-gate   if( (pSub->isDistinct || pSub->nLimit>=0) &&  (pSrc->nSrc>1 || isAgg) ){
16627c478bd9Sstevel@tonic-gate      return 0;
16637c478bd9Sstevel@tonic-gate   }
16647c478bd9Sstevel@tonic-gate   if( (p->isDistinct || p->nLimit>=0) && subqueryIsAgg ) return 0;
16657c478bd9Sstevel@tonic-gate   if( p->pOrderBy && pSub->pOrderBy ) return 0;
16667c478bd9Sstevel@tonic-gate 
1667*55fea89dSDan Cross   /* Restriction 3:  If the subquery is a join, make sure the subquery is
16687c478bd9Sstevel@tonic-gate   ** not used as the right operand of an outer join.  Examples of why this
16697c478bd9Sstevel@tonic-gate   ** is not allowed:
16707c478bd9Sstevel@tonic-gate   **
16717c478bd9Sstevel@tonic-gate   **         t1 LEFT OUTER JOIN (t2 JOIN t3)
16727c478bd9Sstevel@tonic-gate   **
16737c478bd9Sstevel@tonic-gate   ** If we flatten the above, we would get
16747c478bd9Sstevel@tonic-gate   **
16757c478bd9Sstevel@tonic-gate   **         (t1 LEFT OUTER JOIN t2) JOIN t3
16767c478bd9Sstevel@tonic-gate   **
16777c478bd9Sstevel@tonic-gate   ** which is not at all the same thing.
16787c478bd9Sstevel@tonic-gate   */
16797c478bd9Sstevel@tonic-gate   if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
16807c478bd9Sstevel@tonic-gate     return 0;
16817c478bd9Sstevel@tonic-gate   }
16827c478bd9Sstevel@tonic-gate 
16837c478bd9Sstevel@tonic-gate   /* Restriction 12:  If the subquery is the right operand of a left outer
16847c478bd9Sstevel@tonic-gate   ** join, make sure the subquery has no WHERE clause.
16857c478bd9Sstevel@tonic-gate   ** An examples of why this is not allowed:
16867c478bd9Sstevel@tonic-gate   **
16877c478bd9Sstevel@tonic-gate   **         t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
16887c478bd9Sstevel@tonic-gate   **
16897c478bd9Sstevel@tonic-gate   ** If we flatten the above, we would get
16907c478bd9Sstevel@tonic-gate   **
16917c478bd9Sstevel@tonic-gate   **         (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
16927c478bd9Sstevel@tonic-gate   **
16937c478bd9Sstevel@tonic-gate   ** But the t2.x>0 test will always fail on a NULL row of t2, which
16947c478bd9Sstevel@tonic-gate   ** effectively converts the OUTER JOIN into an INNER JOIN.
16957c478bd9Sstevel@tonic-gate   */
1696*55fea89dSDan Cross   if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0
16977c478bd9Sstevel@tonic-gate       && pSub->pWhere!=0 ){
16987c478bd9Sstevel@tonic-gate     return 0;
16997c478bd9Sstevel@tonic-gate   }
17007c478bd9Sstevel@tonic-gate 
17017c478bd9Sstevel@tonic-gate   /* If we reach this point, it means flattening is permitted for the
17027c478bd9Sstevel@tonic-gate   ** iFrom-th entry of the FROM clause in the outer query.
17037c478bd9Sstevel@tonic-gate   */
17047c478bd9Sstevel@tonic-gate 
17057c478bd9Sstevel@tonic-gate   /* Move all of the FROM elements of the subquery into the
17067c478bd9Sstevel@tonic-gate   ** the FROM clause of the outer query.  Before doing this, remember
17077c478bd9Sstevel@tonic-gate   ** the cursor number for the original outer query FROM element in
17087c478bd9Sstevel@tonic-gate   ** iParent.  The iParent cursor will never be used.  Subsequent code
17097c478bd9Sstevel@tonic-gate   ** will scan expressions looking for iParent references and replace
17107c478bd9Sstevel@tonic-gate   ** those references with expressions that resolve to the subquery FROM
17117c478bd9Sstevel@tonic-gate   ** elements we are now copying in.
17127c478bd9Sstevel@tonic-gate   */
17137c478bd9Sstevel@tonic-gate   iParent = pSrc->a[iFrom].iCursor;
17147c478bd9Sstevel@tonic-gate   {
17157c478bd9Sstevel@tonic-gate     int nSubSrc = pSubSrc->nSrc;
17167c478bd9Sstevel@tonic-gate     int jointype = pSrc->a[iFrom].jointype;
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate     if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
17197c478bd9Sstevel@tonic-gate       sqliteDeleteTable(0, pSrc->a[iFrom].pTab);
17207c478bd9Sstevel@tonic-gate     }
17217c478bd9Sstevel@tonic-gate     sqliteFree(pSrc->a[iFrom].zDatabase);
17227c478bd9Sstevel@tonic-gate     sqliteFree(pSrc->a[iFrom].zName);
17237c478bd9Sstevel@tonic-gate     sqliteFree(pSrc->a[iFrom].zAlias);
17247c478bd9Sstevel@tonic-gate     if( nSubSrc>1 ){
17257c478bd9Sstevel@tonic-gate       int extra = nSubSrc - 1;
17267c478bd9Sstevel@tonic-gate       for(i=1; i<nSubSrc; i++){
17277c478bd9Sstevel@tonic-gate         pSrc = sqliteSrcListAppend(pSrc, 0, 0);
17287c478bd9Sstevel@tonic-gate       }
17297c478bd9Sstevel@tonic-gate       p->pSrc = pSrc;
17307c478bd9Sstevel@tonic-gate       for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
17317c478bd9Sstevel@tonic-gate         pSrc->a[i] = pSrc->a[i-extra];
17327c478bd9Sstevel@tonic-gate       }
17337c478bd9Sstevel@tonic-gate     }
17347c478bd9Sstevel@tonic-gate     for(i=0; i<nSubSrc; i++){
17357c478bd9Sstevel@tonic-gate       pSrc->a[i+iFrom] = pSubSrc->a[i];
17367c478bd9Sstevel@tonic-gate       memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
17377c478bd9Sstevel@tonic-gate     }
17387c478bd9Sstevel@tonic-gate     pSrc->a[iFrom+nSubSrc-1].jointype = jointype;
17397c478bd9Sstevel@tonic-gate   }
17407c478bd9Sstevel@tonic-gate 
1741*55fea89dSDan Cross   /* Now begin substituting subquery result set expressions for
17427c478bd9Sstevel@tonic-gate   ** references to the iParent in the outer query.
1743*55fea89dSDan Cross   **
17447c478bd9Sstevel@tonic-gate   ** Example:
17457c478bd9Sstevel@tonic-gate   **
17467c478bd9Sstevel@tonic-gate   **   SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
17477c478bd9Sstevel@tonic-gate   **   \                     \_____________ subquery __________/          /
17487c478bd9Sstevel@tonic-gate   **    \_____________________ outer query ______________________________/
17497c478bd9Sstevel@tonic-gate   **
17507c478bd9Sstevel@tonic-gate   ** We look at every expression in the outer query and every place we see
17517c478bd9Sstevel@tonic-gate   ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
17527c478bd9Sstevel@tonic-gate   */
17537c478bd9Sstevel@tonic-gate   substExprList(p->pEList, iParent, pSub->pEList);
17547c478bd9Sstevel@tonic-gate   pList = p->pEList;
17557c478bd9Sstevel@tonic-gate   for(i=0; i<pList->nExpr; i++){
17567c478bd9Sstevel@tonic-gate     Expr *pExpr;
17577c478bd9Sstevel@tonic-gate     if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
17587c478bd9Sstevel@tonic-gate       pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
17597c478bd9Sstevel@tonic-gate     }
17607c478bd9Sstevel@tonic-gate   }
17617c478bd9Sstevel@tonic-gate   if( isAgg ){
17627c478bd9Sstevel@tonic-gate     substExprList(p->pGroupBy, iParent, pSub->pEList);
17637c478bd9Sstevel@tonic-gate     substExpr(p->pHaving, iParent, pSub->pEList);
17647c478bd9Sstevel@tonic-gate   }
17657c478bd9Sstevel@tonic-gate   if( pSub->pOrderBy ){
17667c478bd9Sstevel@tonic-gate     assert( p->pOrderBy==0 );
17677c478bd9Sstevel@tonic-gate     p->pOrderBy = pSub->pOrderBy;
17687c478bd9Sstevel@tonic-gate     pSub->pOrderBy = 0;
17697c478bd9Sstevel@tonic-gate   }else if( p->pOrderBy ){
17707c478bd9Sstevel@tonic-gate     substExprList(p->pOrderBy, iParent, pSub->pEList);
17717c478bd9Sstevel@tonic-gate   }
17727c478bd9Sstevel@tonic-gate   if( pSub->pWhere ){
17737c478bd9Sstevel@tonic-gate     pWhere = sqliteExprDup(pSub->pWhere);
17747c478bd9Sstevel@tonic-gate   }else{
17757c478bd9Sstevel@tonic-gate     pWhere = 0;
17767c478bd9Sstevel@tonic-gate   }
17777c478bd9Sstevel@tonic-gate   if( subqueryIsAgg ){
17787c478bd9Sstevel@tonic-gate     assert( p->pHaving==0 );
17797c478bd9Sstevel@tonic-gate     p->pHaving = p->pWhere;
17807c478bd9Sstevel@tonic-gate     p->pWhere = pWhere;
17817c478bd9Sstevel@tonic-gate     substExpr(p->pHaving, iParent, pSub->pEList);
17827c478bd9Sstevel@tonic-gate     if( pSub->pHaving ){
17837c478bd9Sstevel@tonic-gate       Expr *pHaving = sqliteExprDup(pSub->pHaving);
17847c478bd9Sstevel@tonic-gate       if( p->pHaving ){
17857c478bd9Sstevel@tonic-gate         p->pHaving = sqliteExpr(TK_AND, p->pHaving, pHaving, 0);
17867c478bd9Sstevel@tonic-gate       }else{
17877c478bd9Sstevel@tonic-gate         p->pHaving = pHaving;
17887c478bd9Sstevel@tonic-gate       }
17897c478bd9Sstevel@tonic-gate     }
17907c478bd9Sstevel@tonic-gate     assert( p->pGroupBy==0 );
17917c478bd9Sstevel@tonic-gate     p->pGroupBy = sqliteExprListDup(pSub->pGroupBy);
17927c478bd9Sstevel@tonic-gate   }else if( p->pWhere==0 ){
17937c478bd9Sstevel@tonic-gate     p->pWhere = pWhere;
17947c478bd9Sstevel@tonic-gate   }else{
17957c478bd9Sstevel@tonic-gate     substExpr(p->pWhere, iParent, pSub->pEList);
17967c478bd9Sstevel@tonic-gate     if( pWhere ){
17977c478bd9Sstevel@tonic-gate       p->pWhere = sqliteExpr(TK_AND, p->pWhere, pWhere, 0);
17987c478bd9Sstevel@tonic-gate     }
17997c478bd9Sstevel@tonic-gate   }
18007c478bd9Sstevel@tonic-gate 
18017c478bd9Sstevel@tonic-gate   /* The flattened query is distinct if either the inner or the
1802*55fea89dSDan Cross   ** outer query is distinct.
18037c478bd9Sstevel@tonic-gate   */
18047c478bd9Sstevel@tonic-gate   p->isDistinct = p->isDistinct || pSub->isDistinct;
18057c478bd9Sstevel@tonic-gate 
18067c478bd9Sstevel@tonic-gate   /* Transfer the limit expression from the subquery to the outer
18077c478bd9Sstevel@tonic-gate   ** query.
18087c478bd9Sstevel@tonic-gate   */
18097c478bd9Sstevel@tonic-gate   if( pSub->nLimit>=0 ){
18107c478bd9Sstevel@tonic-gate     if( p->nLimit<0 ){
18117c478bd9Sstevel@tonic-gate       p->nLimit = pSub->nLimit;
18127c478bd9Sstevel@tonic-gate     }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){
18137c478bd9Sstevel@tonic-gate       p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset;
18147c478bd9Sstevel@tonic-gate     }
18157c478bd9Sstevel@tonic-gate   }
18167c478bd9Sstevel@tonic-gate   p->nOffset += pSub->nOffset;
18177c478bd9Sstevel@tonic-gate 
18187c478bd9Sstevel@tonic-gate   /* Finially, delete what is left of the subquery and return
18197c478bd9Sstevel@tonic-gate   ** success.
18207c478bd9Sstevel@tonic-gate   */
18217c478bd9Sstevel@tonic-gate   sqliteSelectDelete(pSub);
18227c478bd9Sstevel@tonic-gate   return 1;
18237c478bd9Sstevel@tonic-gate }
18247c478bd9Sstevel@tonic-gate 
18257c478bd9Sstevel@tonic-gate /*
18267c478bd9Sstevel@tonic-gate ** Analyze the SELECT statement passed in as an argument to see if it
18277c478bd9Sstevel@tonic-gate ** is a simple min() or max() query.  If it is and this query can be
18287c478bd9Sstevel@tonic-gate ** satisfied using a single seek to the beginning or end of an index,
1829*55fea89dSDan Cross ** then generate the code for this SELECT and return 1.  If this is not a
18307c478bd9Sstevel@tonic-gate ** simple min() or max() query, then return 0;
18317c478bd9Sstevel@tonic-gate **
18327c478bd9Sstevel@tonic-gate ** A simply min() or max() query looks like this:
18337c478bd9Sstevel@tonic-gate **
18347c478bd9Sstevel@tonic-gate **    SELECT min(a) FROM table;
18357c478bd9Sstevel@tonic-gate **    SELECT max(a) FROM table;
18367c478bd9Sstevel@tonic-gate **
18377c478bd9Sstevel@tonic-gate ** The query may have only a single table in its FROM argument.  There
18387c478bd9Sstevel@tonic-gate ** can be no GROUP BY or HAVING or WHERE clauses.  The result set must
18397c478bd9Sstevel@tonic-gate ** be the min() or max() of a single column of the table.  The column
18407c478bd9Sstevel@tonic-gate ** in the min() or max() function must be indexed.
18417c478bd9Sstevel@tonic-gate **
18427c478bd9Sstevel@tonic-gate ** The parameters to this routine are the same as for sqliteSelect().
18437c478bd9Sstevel@tonic-gate ** See the header comment on that routine for additional information.
18447c478bd9Sstevel@tonic-gate */
simpleMinMaxQuery(Parse * pParse,Select * p,int eDest,int iParm)18457c478bd9Sstevel@tonic-gate static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
18467c478bd9Sstevel@tonic-gate   Expr *pExpr;
18477c478bd9Sstevel@tonic-gate   int iCol;
18487c478bd9Sstevel@tonic-gate   Table *pTab;
18497c478bd9Sstevel@tonic-gate   Index *pIdx;
18507c478bd9Sstevel@tonic-gate   int base;
18517c478bd9Sstevel@tonic-gate   Vdbe *v;
18527c478bd9Sstevel@tonic-gate   int seekOp;
18537c478bd9Sstevel@tonic-gate   int cont;
18547c478bd9Sstevel@tonic-gate   ExprList *pEList, *pList, eList;
18557c478bd9Sstevel@tonic-gate   struct ExprList_item eListItem;
18567c478bd9Sstevel@tonic-gate   SrcList *pSrc;
1857*55fea89dSDan Cross 
18587c478bd9Sstevel@tonic-gate 
18597c478bd9Sstevel@tonic-gate   /* Check to see if this query is a simple min() or max() query.  Return
18607c478bd9Sstevel@tonic-gate   ** zero if it is  not.
18617c478bd9Sstevel@tonic-gate   */
18627c478bd9Sstevel@tonic-gate   if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
18637c478bd9Sstevel@tonic-gate   pSrc = p->pSrc;
18647c478bd9Sstevel@tonic-gate   if( pSrc->nSrc!=1 ) return 0;
18657c478bd9Sstevel@tonic-gate   pEList = p->pEList;
18667c478bd9Sstevel@tonic-gate   if( pEList->nExpr!=1 ) return 0;
18677c478bd9Sstevel@tonic-gate   pExpr = pEList->a[0].pExpr;
18687c478bd9Sstevel@tonic-gate   if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
18697c478bd9Sstevel@tonic-gate   pList = pExpr->pList;
18707c478bd9Sstevel@tonic-gate   if( pList==0 || pList->nExpr!=1 ) return 0;
18717c478bd9Sstevel@tonic-gate   if( pExpr->token.n!=3 ) return 0;
18727c478bd9Sstevel@tonic-gate   if( sqliteStrNICmp(pExpr->token.z,"min",3)==0 ){
18737c478bd9Sstevel@tonic-gate     seekOp = OP_Rewind;
18747c478bd9Sstevel@tonic-gate   }else if( sqliteStrNICmp(pExpr->token.z,"max",3)==0 ){
18757c478bd9Sstevel@tonic-gate     seekOp = OP_Last;
18767c478bd9Sstevel@tonic-gate   }else{
18777c478bd9Sstevel@tonic-gate     return 0;
18787c478bd9Sstevel@tonic-gate   }
18797c478bd9Sstevel@tonic-gate   pExpr = pList->a[0].pExpr;
18807c478bd9Sstevel@tonic-gate   if( pExpr->op!=TK_COLUMN ) return 0;
18817c478bd9Sstevel@tonic-gate   iCol = pExpr->iColumn;
18827c478bd9Sstevel@tonic-gate   pTab = pSrc->a[0].pTab;
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate   /* If we get to here, it means the query is of the correct form.
18857c478bd9Sstevel@tonic-gate   ** Check to make sure we have an index and make pIdx point to the
18867c478bd9Sstevel@tonic-gate   ** appropriate index.  If the min() or max() is on an INTEGER PRIMARY
18877c478bd9Sstevel@tonic-gate   ** key column, no index is necessary so set pIdx to NULL.  If no
18887c478bd9Sstevel@tonic-gate   ** usable index is found, return 0.
18897c478bd9Sstevel@tonic-gate   */
18907c478bd9Sstevel@tonic-gate   if( iCol<0 ){
18917c478bd9Sstevel@tonic-gate     pIdx = 0;
18927c478bd9Sstevel@tonic-gate   }else{
18937c478bd9Sstevel@tonic-gate     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
18947c478bd9Sstevel@tonic-gate       assert( pIdx->nColumn>=1 );
18957c478bd9Sstevel@tonic-gate       if( pIdx->aiColumn[0]==iCol ) break;
18967c478bd9Sstevel@tonic-gate     }
18977c478bd9Sstevel@tonic-gate     if( pIdx==0 ) return 0;
18987c478bd9Sstevel@tonic-gate   }
18997c478bd9Sstevel@tonic-gate 
19007c478bd9Sstevel@tonic-gate   /* Identify column types if we will be using the callback.  This
19017c478bd9Sstevel@tonic-gate   ** step is skipped if the output is going to a table or a memory cell.
19027c478bd9Sstevel@tonic-gate   ** The column names have already been generated in the calling function.
19037c478bd9Sstevel@tonic-gate   */
19047c478bd9Sstevel@tonic-gate   v = sqliteGetVdbe(pParse);
19057c478bd9Sstevel@tonic-gate   if( v==0 ) return 0;
19067c478bd9Sstevel@tonic-gate   if( eDest==SRT_Callback ){
19077c478bd9Sstevel@tonic-gate     generateColumnTypes(pParse, p->pSrc, p->pEList);
19087c478bd9Sstevel@tonic-gate   }
19097c478bd9Sstevel@tonic-gate 
19107c478bd9Sstevel@tonic-gate   /* If the output is destined for a temporary table, open that table.
19117c478bd9Sstevel@tonic-gate   */
19127c478bd9Sstevel@tonic-gate   if( eDest==SRT_TempTable ){
19137c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
19147c478bd9Sstevel@tonic-gate   }
19157c478bd9Sstevel@tonic-gate 
19167c478bd9Sstevel@tonic-gate   /* Generating code to find the min or the max.  Basically all we have
19177c478bd9Sstevel@tonic-gate   ** to do is find the first or the last entry in the chosen index.  If
19187c478bd9Sstevel@tonic-gate   ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
19197c478bd9Sstevel@tonic-gate   ** or last entry in the main table.
19207c478bd9Sstevel@tonic-gate   */
19217c478bd9Sstevel@tonic-gate   sqliteCodeVerifySchema(pParse, pTab->iDb);
19227c478bd9Sstevel@tonic-gate   base = pSrc->a[0].iCursor;
19237c478bd9Sstevel@tonic-gate   computeLimitRegisters(pParse, p);
19247c478bd9Sstevel@tonic-gate   if( pSrc->a[0].pSelect==0 ){
19257c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
19267c478bd9Sstevel@tonic-gate     sqliteVdbeOp3(v, OP_OpenRead, base, pTab->tnum, pTab->zName, 0);
19277c478bd9Sstevel@tonic-gate   }
19287c478bd9Sstevel@tonic-gate   cont = sqliteVdbeMakeLabel(v);
19297c478bd9Sstevel@tonic-gate   if( pIdx==0 ){
19307c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, seekOp, base, 0);
19317c478bd9Sstevel@tonic-gate   }else{
19327c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
19337c478bd9Sstevel@tonic-gate     sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
19347c478bd9Sstevel@tonic-gate     if( seekOp==OP_Rewind ){
19357c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_String, 0, 0);
19367c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_MakeKey, 1, 0);
19377c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
19387c478bd9Sstevel@tonic-gate       seekOp = OP_MoveTo;
19397c478bd9Sstevel@tonic-gate     }
19407c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, seekOp, base+1, 0);
19417c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
19427c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Close, base+1, 0);
19437c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
19447c478bd9Sstevel@tonic-gate   }
19457c478bd9Sstevel@tonic-gate   eList.nExpr = 1;
19467c478bd9Sstevel@tonic-gate   memset(&eListItem, 0, sizeof(eListItem));
19477c478bd9Sstevel@tonic-gate   eList.a = &eListItem;
19487c478bd9Sstevel@tonic-gate   eList.a[0].pExpr = pExpr;
19497c478bd9Sstevel@tonic-gate   selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont);
19507c478bd9Sstevel@tonic-gate   sqliteVdbeResolveLabel(v, cont);
19517c478bd9Sstevel@tonic-gate   sqliteVdbeAddOp(v, OP_Close, base, 0);
1952*55fea89dSDan Cross 
19537c478bd9Sstevel@tonic-gate   return 1;
19547c478bd9Sstevel@tonic-gate }
19557c478bd9Sstevel@tonic-gate 
19567c478bd9Sstevel@tonic-gate /*
19577c478bd9Sstevel@tonic-gate ** Generate code for the given SELECT statement.
19587c478bd9Sstevel@tonic-gate **
19597c478bd9Sstevel@tonic-gate ** The results are distributed in various ways depending on the
19607c478bd9Sstevel@tonic-gate ** value of eDest and iParm.
19617c478bd9Sstevel@tonic-gate **
19627c478bd9Sstevel@tonic-gate **     eDest Value       Result
19637c478bd9Sstevel@tonic-gate **     ------------    -------------------------------------------
19647c478bd9Sstevel@tonic-gate **     SRT_Callback    Invoke the callback for each row of the result.
19657c478bd9Sstevel@tonic-gate **
19667c478bd9Sstevel@tonic-gate **     SRT_Mem         Store first result in memory cell iParm
19677c478bd9Sstevel@tonic-gate **
19687c478bd9Sstevel@tonic-gate **     SRT_Set         Store results as keys of a table with cursor iParm
19697c478bd9Sstevel@tonic-gate **
19707c478bd9Sstevel@tonic-gate **     SRT_Union       Store results as a key in a temporary table iParm
19717c478bd9Sstevel@tonic-gate **
19727c478bd9Sstevel@tonic-gate **     SRT_Except      Remove results from the temporary table iParm.
19737c478bd9Sstevel@tonic-gate **
19747c478bd9Sstevel@tonic-gate **     SRT_Table       Store results in temporary table iParm
19757c478bd9Sstevel@tonic-gate **
19767c478bd9Sstevel@tonic-gate ** The table above is incomplete.  Additional eDist value have be added
19777c478bd9Sstevel@tonic-gate ** since this comment was written.  See the selectInnerLoop() function for
19787c478bd9Sstevel@tonic-gate ** a complete listing of the allowed values of eDest and their meanings.
19797c478bd9Sstevel@tonic-gate **
19807c478bd9Sstevel@tonic-gate ** This routine returns the number of errors.  If any errors are
19817c478bd9Sstevel@tonic-gate ** encountered, then an appropriate error message is left in
19827c478bd9Sstevel@tonic-gate ** pParse->zErrMsg.
19837c478bd9Sstevel@tonic-gate **
19847c478bd9Sstevel@tonic-gate ** This routine does NOT free the Select structure passed in.  The
19857c478bd9Sstevel@tonic-gate ** calling function needs to do that.
19867c478bd9Sstevel@tonic-gate **
19877c478bd9Sstevel@tonic-gate ** The pParent, parentTab, and *pParentAgg fields are filled in if this
19887c478bd9Sstevel@tonic-gate ** SELECT is a subquery.  This routine may try to combine this SELECT
19897c478bd9Sstevel@tonic-gate ** with its parent to form a single flat query.  In so doing, it might
19907c478bd9Sstevel@tonic-gate ** change the parent query from a non-aggregate to an aggregate query.
19917c478bd9Sstevel@tonic-gate ** For that reason, the pParentAgg flag is passed as a pointer, so it
19927c478bd9Sstevel@tonic-gate ** can be changed.
19937c478bd9Sstevel@tonic-gate **
19947c478bd9Sstevel@tonic-gate ** Example 1:   The meaning of the pParent parameter.
19957c478bd9Sstevel@tonic-gate **
19967c478bd9Sstevel@tonic-gate **    SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3;
19977c478bd9Sstevel@tonic-gate **    \                      \_______ subquery _______/        /
19987c478bd9Sstevel@tonic-gate **     \                                                      /
19997c478bd9Sstevel@tonic-gate **      \____________________ outer query ___________________/
20007c478bd9Sstevel@tonic-gate **
20017c478bd9Sstevel@tonic-gate ** This routine is called for the outer query first.   For that call,
2002*55fea89dSDan Cross ** pParent will be NULL.  During the processing of the outer query, this
20037c478bd9Sstevel@tonic-gate ** routine is called recursively to handle the subquery.  For the recursive
20047c478bd9Sstevel@tonic-gate ** call, pParent will point to the outer query.  Because the subquery is
20057c478bd9Sstevel@tonic-gate ** the second element in a three-way join, the parentTab parameter will
20067c478bd9Sstevel@tonic-gate ** be 1 (the 2nd value of a 0-indexed array.)
20077c478bd9Sstevel@tonic-gate */
sqliteSelect(Parse * pParse,Select * p,int eDest,int iParm,Select * pParent,int parentTab,int * pParentAgg)20087c478bd9Sstevel@tonic-gate int sqliteSelect(
20097c478bd9Sstevel@tonic-gate   Parse *pParse,         /* The parser context */
20107c478bd9Sstevel@tonic-gate   Select *p,             /* The SELECT statement being coded. */
20117c478bd9Sstevel@tonic-gate   int eDest,             /* How to dispose of the results */
20127c478bd9Sstevel@tonic-gate   int iParm,             /* A parameter used by the eDest disposal method */
20137c478bd9Sstevel@tonic-gate   Select *pParent,       /* Another SELECT for which this is a sub-query */
20147c478bd9Sstevel@tonic-gate   int parentTab,         /* Index in pParent->pSrc of this query */
20157c478bd9Sstevel@tonic-gate   int *pParentAgg        /* True if pParent uses aggregate functions */
20167c478bd9Sstevel@tonic-gate ){
20177c478bd9Sstevel@tonic-gate   int i;
20187c478bd9Sstevel@tonic-gate   WhereInfo *pWInfo;
20197c478bd9Sstevel@tonic-gate   Vdbe *v;
20207c478bd9Sstevel@tonic-gate   int isAgg = 0;         /* True for select lists like "count(*)" */
20217c478bd9Sstevel@tonic-gate   ExprList *pEList;      /* List of columns to extract. */
20227c478bd9Sstevel@tonic-gate   SrcList *pTabList;     /* List of tables to select from */
20237c478bd9Sstevel@tonic-gate   Expr *pWhere;          /* The WHERE clause.  May be NULL */
20247c478bd9Sstevel@tonic-gate   ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
20257c478bd9Sstevel@tonic-gate   ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
20267c478bd9Sstevel@tonic-gate   Expr *pHaving;         /* The HAVING clause.  May be NULL */
20277c478bd9Sstevel@tonic-gate   int isDistinct;        /* True if the DISTINCT keyword is present */
20287c478bd9Sstevel@tonic-gate   int distinct;          /* Table to use for the distinct set */
20297c478bd9Sstevel@tonic-gate   int rc = 1;            /* Value to return from this function */
20307c478bd9Sstevel@tonic-gate 
20317c478bd9Sstevel@tonic-gate   if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1;
20327c478bd9Sstevel@tonic-gate   if( sqliteAuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate   /* If there is are a sequence of queries, do the earlier ones first.
20357c478bd9Sstevel@tonic-gate   */
20367c478bd9Sstevel@tonic-gate   if( p->pPrior ){
20377c478bd9Sstevel@tonic-gate     return multiSelect(pParse, p, eDest, iParm);
20387c478bd9Sstevel@tonic-gate   }
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate   /* Make local copies of the parameters for this query.
20417c478bd9Sstevel@tonic-gate   */
20427c478bd9Sstevel@tonic-gate   pTabList = p->pSrc;
20437c478bd9Sstevel@tonic-gate   pWhere = p->pWhere;
20447c478bd9Sstevel@tonic-gate   pOrderBy = p->pOrderBy;
20457c478bd9Sstevel@tonic-gate   pGroupBy = p->pGroupBy;
20467c478bd9Sstevel@tonic-gate   pHaving = p->pHaving;
20477c478bd9Sstevel@tonic-gate   isDistinct = p->isDistinct;
20487c478bd9Sstevel@tonic-gate 
20497c478bd9Sstevel@tonic-gate   /* Allocate VDBE cursors for each table in the FROM clause
20507c478bd9Sstevel@tonic-gate   */
20517c478bd9Sstevel@tonic-gate   sqliteSrcListAssignCursors(pParse, pTabList);
20527c478bd9Sstevel@tonic-gate 
2053*55fea89dSDan Cross   /*
20547c478bd9Sstevel@tonic-gate   ** Do not even attempt to generate any code if we have already seen
20557c478bd9Sstevel@tonic-gate   ** errors before this routine starts.
20567c478bd9Sstevel@tonic-gate   */
20577c478bd9Sstevel@tonic-gate   if( pParse->nErr>0 ) goto select_end;
20587c478bd9Sstevel@tonic-gate 
20597c478bd9Sstevel@tonic-gate   /* Expand any "*" terms in the result set.  (For example the "*" in
20607c478bd9Sstevel@tonic-gate   ** "SELECT * FROM t1")  The fillInColumnlist() routine also does some
20617c478bd9Sstevel@tonic-gate   ** other housekeeping - see the header comment for details.
20627c478bd9Sstevel@tonic-gate   */
20637c478bd9Sstevel@tonic-gate   if( fillInColumnList(pParse, p) ){
20647c478bd9Sstevel@tonic-gate     goto select_end;
20657c478bd9Sstevel@tonic-gate   }
20667c478bd9Sstevel@tonic-gate   pWhere = p->pWhere;
20677c478bd9Sstevel@tonic-gate   pEList = p->pEList;
20687c478bd9Sstevel@tonic-gate   if( pEList==0 ) goto select_end;
20697c478bd9Sstevel@tonic-gate 
20707c478bd9Sstevel@tonic-gate   /* If writing to memory or generating a set
20717c478bd9Sstevel@tonic-gate   ** only a single column may be output.
20727c478bd9Sstevel@tonic-gate   */
20737c478bd9Sstevel@tonic-gate   if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
20747c478bd9Sstevel@tonic-gate     sqliteErrorMsg(pParse, "only a single result allowed for "
20757c478bd9Sstevel@tonic-gate        "a SELECT that is part of an expression");
20767c478bd9Sstevel@tonic-gate     goto select_end;
20777c478bd9Sstevel@tonic-gate   }
20787c478bd9Sstevel@tonic-gate 
20797c478bd9Sstevel@tonic-gate   /* ORDER BY is ignored for some destinations.
20807c478bd9Sstevel@tonic-gate   */
20817c478bd9Sstevel@tonic-gate   switch( eDest ){
20827c478bd9Sstevel@tonic-gate     case SRT_Union:
20837c478bd9Sstevel@tonic-gate     case SRT_Except:
20847c478bd9Sstevel@tonic-gate     case SRT_Discard:
20857c478bd9Sstevel@tonic-gate       pOrderBy = 0;
20867c478bd9Sstevel@tonic-gate       break;
20877c478bd9Sstevel@tonic-gate     default:
20887c478bd9Sstevel@tonic-gate       break;
20897c478bd9Sstevel@tonic-gate   }
20907c478bd9Sstevel@tonic-gate 
20917c478bd9Sstevel@tonic-gate   /* At this point, we should have allocated all the cursors that we
2092*55fea89dSDan Cross   ** need to handle subquerys and temporary tables.
20937c478bd9Sstevel@tonic-gate   **
20947c478bd9Sstevel@tonic-gate   ** Resolve the column names and do a semantics check on all the expressions.
20957c478bd9Sstevel@tonic-gate   */
20967c478bd9Sstevel@tonic-gate   for(i=0; i<pEList->nExpr; i++){
20977c478bd9Sstevel@tonic-gate     if( sqliteExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){
20987c478bd9Sstevel@tonic-gate       goto select_end;
20997c478bd9Sstevel@tonic-gate     }
21007c478bd9Sstevel@tonic-gate     if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
21017c478bd9Sstevel@tonic-gate       goto select_end;
21027c478bd9Sstevel@tonic-gate     }
21037c478bd9Sstevel@tonic-gate   }
21047c478bd9Sstevel@tonic-gate   if( pWhere ){
21057c478bd9Sstevel@tonic-gate     if( sqliteExprResolveIds(pParse, pTabList, pEList, pWhere) ){
21067c478bd9Sstevel@tonic-gate       goto select_end;
21077c478bd9Sstevel@tonic-gate     }
21087c478bd9Sstevel@tonic-gate     if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
21097c478bd9Sstevel@tonic-gate       goto select_end;
21107c478bd9Sstevel@tonic-gate     }
21117c478bd9Sstevel@tonic-gate   }
21127c478bd9Sstevel@tonic-gate   if( pHaving ){
21137c478bd9Sstevel@tonic-gate     if( pGroupBy==0 ){
21147c478bd9Sstevel@tonic-gate       sqliteErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
21157c478bd9Sstevel@tonic-gate       goto select_end;
21167c478bd9Sstevel@tonic-gate     }
21177c478bd9Sstevel@tonic-gate     if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){
21187c478bd9Sstevel@tonic-gate       goto select_end;
21197c478bd9Sstevel@tonic-gate     }
21207c478bd9Sstevel@tonic-gate     if( sqliteExprCheck(pParse, pHaving, 1, &isAgg) ){
21217c478bd9Sstevel@tonic-gate       goto select_end;
21227c478bd9Sstevel@tonic-gate     }
21237c478bd9Sstevel@tonic-gate   }
21247c478bd9Sstevel@tonic-gate   if( pOrderBy ){
21257c478bd9Sstevel@tonic-gate     for(i=0; i<pOrderBy->nExpr; i++){
21267c478bd9Sstevel@tonic-gate       int iCol;
21277c478bd9Sstevel@tonic-gate       Expr *pE = pOrderBy->a[i].pExpr;
21287c478bd9Sstevel@tonic-gate       if( sqliteExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
21297c478bd9Sstevel@tonic-gate         sqliteExprDelete(pE);
21307c478bd9Sstevel@tonic-gate         pE = pOrderBy->a[i].pExpr = sqliteExprDup(pEList->a[iCol-1].pExpr);
21317c478bd9Sstevel@tonic-gate       }
21327c478bd9Sstevel@tonic-gate       if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
21337c478bd9Sstevel@tonic-gate         goto select_end;
21347c478bd9Sstevel@tonic-gate       }
21357c478bd9Sstevel@tonic-gate       if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
21367c478bd9Sstevel@tonic-gate         goto select_end;
21377c478bd9Sstevel@tonic-gate       }
21387c478bd9Sstevel@tonic-gate       if( sqliteExprIsConstant(pE) ){
21397c478bd9Sstevel@tonic-gate         if( sqliteExprIsInteger(pE, &iCol)==0 ){
21407c478bd9Sstevel@tonic-gate           sqliteErrorMsg(pParse,
21417c478bd9Sstevel@tonic-gate              "ORDER BY terms must not be non-integer constants");
21427c478bd9Sstevel@tonic-gate           goto select_end;
21437c478bd9Sstevel@tonic-gate         }else if( iCol<=0 || iCol>pEList->nExpr ){
2144*55fea89dSDan Cross           sqliteErrorMsg(pParse,
21457c478bd9Sstevel@tonic-gate              "ORDER BY column number %d out of range - should be "
21467c478bd9Sstevel@tonic-gate              "between 1 and %d", iCol, pEList->nExpr);
21477c478bd9Sstevel@tonic-gate           goto select_end;
21487c478bd9Sstevel@tonic-gate         }
21497c478bd9Sstevel@tonic-gate       }
21507c478bd9Sstevel@tonic-gate     }
21517c478bd9Sstevel@tonic-gate   }
21527c478bd9Sstevel@tonic-gate   if( pGroupBy ){
21537c478bd9Sstevel@tonic-gate     for(i=0; i<pGroupBy->nExpr; i++){
21547c478bd9Sstevel@tonic-gate       int iCol;
21557c478bd9Sstevel@tonic-gate       Expr *pE = pGroupBy->a[i].pExpr;
21567c478bd9Sstevel@tonic-gate       if( sqliteExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
21577c478bd9Sstevel@tonic-gate         sqliteExprDelete(pE);
21587c478bd9Sstevel@tonic-gate         pE = pGroupBy->a[i].pExpr = sqliteExprDup(pEList->a[iCol-1].pExpr);
21597c478bd9Sstevel@tonic-gate       }
21607c478bd9Sstevel@tonic-gate       if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
21617c478bd9Sstevel@tonic-gate         goto select_end;
21627c478bd9Sstevel@tonic-gate       }
21637c478bd9Sstevel@tonic-gate       if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
21647c478bd9Sstevel@tonic-gate         goto select_end;
21657c478bd9Sstevel@tonic-gate       }
21667c478bd9Sstevel@tonic-gate       if( sqliteExprIsConstant(pE) ){
21677c478bd9Sstevel@tonic-gate         if( sqliteExprIsInteger(pE, &iCol)==0 ){
21687c478bd9Sstevel@tonic-gate           sqliteErrorMsg(pParse,
21697c478bd9Sstevel@tonic-gate             "GROUP BY terms must not be non-integer constants");
21707c478bd9Sstevel@tonic-gate           goto select_end;
21717c478bd9Sstevel@tonic-gate         }else if( iCol<=0 || iCol>pEList->nExpr ){
21727c478bd9Sstevel@tonic-gate           sqliteErrorMsg(pParse,
21737c478bd9Sstevel@tonic-gate              "GROUP BY column number %d out of range - should be "
21747c478bd9Sstevel@tonic-gate              "between 1 and %d", iCol, pEList->nExpr);
21757c478bd9Sstevel@tonic-gate           goto select_end;
21767c478bd9Sstevel@tonic-gate         }
21777c478bd9Sstevel@tonic-gate       }
21787c478bd9Sstevel@tonic-gate     }
21797c478bd9Sstevel@tonic-gate   }
21807c478bd9Sstevel@tonic-gate 
21817c478bd9Sstevel@tonic-gate   /* Begin generating code.
21827c478bd9Sstevel@tonic-gate   */
21837c478bd9Sstevel@tonic-gate   v = sqliteGetVdbe(pParse);
21847c478bd9Sstevel@tonic-gate   if( v==0 ) goto select_end;
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate   /* Identify column names if we will be using them in a callback.  This
21877c478bd9Sstevel@tonic-gate   ** step is skipped if the output is going to some other destination.
21887c478bd9Sstevel@tonic-gate   */
21897c478bd9Sstevel@tonic-gate   if( eDest==SRT_Callback ){
21907c478bd9Sstevel@tonic-gate     generateColumnNames(pParse, pTabList, pEList);
21917c478bd9Sstevel@tonic-gate   }
21927c478bd9Sstevel@tonic-gate 
21937c478bd9Sstevel@tonic-gate   /* Generate code for all sub-queries in the FROM clause
21947c478bd9Sstevel@tonic-gate   */
21957c478bd9Sstevel@tonic-gate   for(i=0; i<pTabList->nSrc; i++){
21967c478bd9Sstevel@tonic-gate     const char *zSavedAuthContext;
21977c478bd9Sstevel@tonic-gate     int needRestoreContext;
21987c478bd9Sstevel@tonic-gate 
21997c478bd9Sstevel@tonic-gate     if( pTabList->a[i].pSelect==0 ) continue;
22007c478bd9Sstevel@tonic-gate     if( pTabList->a[i].zName!=0 ){
22017c478bd9Sstevel@tonic-gate       zSavedAuthContext = pParse->zAuthContext;
22027c478bd9Sstevel@tonic-gate       pParse->zAuthContext = pTabList->a[i].zName;
22037c478bd9Sstevel@tonic-gate       needRestoreContext = 1;
22047c478bd9Sstevel@tonic-gate     }else{
22057c478bd9Sstevel@tonic-gate       needRestoreContext = 0;
22067c478bd9Sstevel@tonic-gate     }
2207*55fea89dSDan Cross     sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_TempTable,
22087c478bd9Sstevel@tonic-gate                  pTabList->a[i].iCursor, p, i, &isAgg);
22097c478bd9Sstevel@tonic-gate     if( needRestoreContext ){
22107c478bd9Sstevel@tonic-gate       pParse->zAuthContext = zSavedAuthContext;
22117c478bd9Sstevel@tonic-gate     }
22127c478bd9Sstevel@tonic-gate     pTabList = p->pSrc;
22137c478bd9Sstevel@tonic-gate     pWhere = p->pWhere;
22147c478bd9Sstevel@tonic-gate     if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
22157c478bd9Sstevel@tonic-gate       pOrderBy = p->pOrderBy;
22167c478bd9Sstevel@tonic-gate     }
22177c478bd9Sstevel@tonic-gate     pGroupBy = p->pGroupBy;
22187c478bd9Sstevel@tonic-gate     pHaving = p->pHaving;
22197c478bd9Sstevel@tonic-gate     isDistinct = p->isDistinct;
22207c478bd9Sstevel@tonic-gate   }
22217c478bd9Sstevel@tonic-gate 
22227c478bd9Sstevel@tonic-gate   /* Check for the special case of a min() or max() function by itself
22237c478bd9Sstevel@tonic-gate   ** in the result set.
22247c478bd9Sstevel@tonic-gate   */
22257c478bd9Sstevel@tonic-gate   if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
22267c478bd9Sstevel@tonic-gate     rc = 0;
22277c478bd9Sstevel@tonic-gate     goto select_end;
22287c478bd9Sstevel@tonic-gate   }
22297c478bd9Sstevel@tonic-gate 
22307c478bd9Sstevel@tonic-gate   /* Check to see if this is a subquery that can be "flattened" into its parent.
2231*55fea89dSDan Cross   ** If flattening is a possiblity, do so and return immediately.
22327c478bd9Sstevel@tonic-gate   */
22337c478bd9Sstevel@tonic-gate   if( pParent && pParentAgg &&
22347c478bd9Sstevel@tonic-gate       flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
22357c478bd9Sstevel@tonic-gate     if( isAgg ) *pParentAgg = 1;
22367c478bd9Sstevel@tonic-gate     return rc;
22377c478bd9Sstevel@tonic-gate   }
22387c478bd9Sstevel@tonic-gate 
22397c478bd9Sstevel@tonic-gate   /* Set the limiter.
22407c478bd9Sstevel@tonic-gate   */
22417c478bd9Sstevel@tonic-gate   computeLimitRegisters(pParse, p);
22427c478bd9Sstevel@tonic-gate 
22437c478bd9Sstevel@tonic-gate   /* Identify column types if we will be using a callback.  This
22447c478bd9Sstevel@tonic-gate   ** step is skipped if the output is going to a destination other
22457c478bd9Sstevel@tonic-gate   ** than a callback.
22467c478bd9Sstevel@tonic-gate   **
22477c478bd9Sstevel@tonic-gate   ** We have to do this separately from the creation of column names
22487c478bd9Sstevel@tonic-gate   ** above because if the pTabList contains views then they will not
22497c478bd9Sstevel@tonic-gate   ** have been resolved and we will not know the column types until
22507c478bd9Sstevel@tonic-gate   ** now.
22517c478bd9Sstevel@tonic-gate   */
22527c478bd9Sstevel@tonic-gate   if( eDest==SRT_Callback ){
22537c478bd9Sstevel@tonic-gate     generateColumnTypes(pParse, pTabList, pEList);
22547c478bd9Sstevel@tonic-gate   }
22557c478bd9Sstevel@tonic-gate 
22567c478bd9Sstevel@tonic-gate   /* If the output is destined for a temporary table, open that table.
22577c478bd9Sstevel@tonic-gate   */
22587c478bd9Sstevel@tonic-gate   if( eDest==SRT_TempTable ){
22597c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
22607c478bd9Sstevel@tonic-gate   }
22617c478bd9Sstevel@tonic-gate 
22627c478bd9Sstevel@tonic-gate   /* Do an analysis of aggregate expressions.
22637c478bd9Sstevel@tonic-gate   */
22647c478bd9Sstevel@tonic-gate   sqliteAggregateInfoReset(pParse);
22657c478bd9Sstevel@tonic-gate   if( isAgg || pGroupBy ){
22667c478bd9Sstevel@tonic-gate     assert( pParse->nAgg==0 );
22677c478bd9Sstevel@tonic-gate     isAgg = 1;
22687c478bd9Sstevel@tonic-gate     for(i=0; i<pEList->nExpr; i++){
22697c478bd9Sstevel@tonic-gate       if( sqliteExprAnalyzeAggregates(pParse, pEList->a[i].pExpr) ){
22707c478bd9Sstevel@tonic-gate         goto select_end;
22717c478bd9Sstevel@tonic-gate       }
22727c478bd9Sstevel@tonic-gate     }
22737c478bd9Sstevel@tonic-gate     if( pGroupBy ){
22747c478bd9Sstevel@tonic-gate       for(i=0; i<pGroupBy->nExpr; i++){
22757c478bd9Sstevel@tonic-gate         if( sqliteExprAnalyzeAggregates(pParse, pGroupBy->a[i].pExpr) ){
22767c478bd9Sstevel@tonic-gate           goto select_end;
22777c478bd9Sstevel@tonic-gate         }
22787c478bd9Sstevel@tonic-gate       }
22797c478bd9Sstevel@tonic-gate     }
22807c478bd9Sstevel@tonic-gate     if( pHaving && sqliteExprAnalyzeAggregates(pParse, pHaving) ){
22817c478bd9Sstevel@tonic-gate       goto select_end;
22827c478bd9Sstevel@tonic-gate     }
22837c478bd9Sstevel@tonic-gate     if( pOrderBy ){
22847c478bd9Sstevel@tonic-gate       for(i=0; i<pOrderBy->nExpr; i++){
22857c478bd9Sstevel@tonic-gate         if( sqliteExprAnalyzeAggregates(pParse, pOrderBy->a[i].pExpr) ){
22867c478bd9Sstevel@tonic-gate           goto select_end;
22877c478bd9Sstevel@tonic-gate         }
22887c478bd9Sstevel@tonic-gate       }
22897c478bd9Sstevel@tonic-gate     }
22907c478bd9Sstevel@tonic-gate   }
22917c478bd9Sstevel@tonic-gate 
22927c478bd9Sstevel@tonic-gate   /* Reset the aggregator
22937c478bd9Sstevel@tonic-gate   */
22947c478bd9Sstevel@tonic-gate   if( isAgg ){
22957c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
22967c478bd9Sstevel@tonic-gate     for(i=0; i<pParse->nAgg; i++){
22977c478bd9Sstevel@tonic-gate       FuncDef *pFunc;
22987c478bd9Sstevel@tonic-gate       if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
22997c478bd9Sstevel@tonic-gate         sqliteVdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_POINTER);
23007c478bd9Sstevel@tonic-gate       }
23017c478bd9Sstevel@tonic-gate     }
23027c478bd9Sstevel@tonic-gate     if( pGroupBy==0 ){
23037c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_String, 0, 0);
23047c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_AggFocus, 0, 0);
23057c478bd9Sstevel@tonic-gate     }
23067c478bd9Sstevel@tonic-gate   }
23077c478bd9Sstevel@tonic-gate 
23087c478bd9Sstevel@tonic-gate   /* Initialize the memory cell to NULL
23097c478bd9Sstevel@tonic-gate   */
23107c478bd9Sstevel@tonic-gate   if( eDest==SRT_Mem ){
23117c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_String, 0, 0);
23127c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
23137c478bd9Sstevel@tonic-gate   }
23147c478bd9Sstevel@tonic-gate 
23157c478bd9Sstevel@tonic-gate   /* Open a temporary table to use for the distinct set.
23167c478bd9Sstevel@tonic-gate   */
23177c478bd9Sstevel@tonic-gate   if( isDistinct ){
23187c478bd9Sstevel@tonic-gate     distinct = pParse->nTab++;
23197c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 1);
23207c478bd9Sstevel@tonic-gate   }else{
23217c478bd9Sstevel@tonic-gate     distinct = -1;
23227c478bd9Sstevel@tonic-gate   }
23237c478bd9Sstevel@tonic-gate 
23247c478bd9Sstevel@tonic-gate   /* Begin the database scan
23257c478bd9Sstevel@tonic-gate   */
2326*55fea89dSDan Cross   pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0,
23277c478bd9Sstevel@tonic-gate                             pGroupBy ? 0 : &pOrderBy);
23287c478bd9Sstevel@tonic-gate   if( pWInfo==0 ) goto select_end;
23297c478bd9Sstevel@tonic-gate 
23307c478bd9Sstevel@tonic-gate   /* Use the standard inner loop if we are not dealing with
23317c478bd9Sstevel@tonic-gate   ** aggregates
23327c478bd9Sstevel@tonic-gate   */
23337c478bd9Sstevel@tonic-gate   if( !isAgg ){
23347c478bd9Sstevel@tonic-gate     if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
23357c478bd9Sstevel@tonic-gate                     iParm, pWInfo->iContinue, pWInfo->iBreak) ){
23367c478bd9Sstevel@tonic-gate        goto select_end;
23377c478bd9Sstevel@tonic-gate     }
23387c478bd9Sstevel@tonic-gate   }
23397c478bd9Sstevel@tonic-gate 
23407c478bd9Sstevel@tonic-gate   /* If we are dealing with aggregates, then do the special aggregate
2341*55fea89dSDan Cross   ** processing.
23427c478bd9Sstevel@tonic-gate   */
23437c478bd9Sstevel@tonic-gate   else{
23447c478bd9Sstevel@tonic-gate     AggExpr *pAgg;
23457c478bd9Sstevel@tonic-gate     if( pGroupBy ){
23467c478bd9Sstevel@tonic-gate       int lbl1;
23477c478bd9Sstevel@tonic-gate       for(i=0; i<pGroupBy->nExpr; i++){
23487c478bd9Sstevel@tonic-gate         sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
23497c478bd9Sstevel@tonic-gate       }
23507c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
23517c478bd9Sstevel@tonic-gate       if( pParse->db->file_format>=4 ) sqliteAddKeyType(v, pGroupBy);
23527c478bd9Sstevel@tonic-gate       lbl1 = sqliteVdbeMakeLabel(v);
23537c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1);
23547c478bd9Sstevel@tonic-gate       for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
23557c478bd9Sstevel@tonic-gate         if( pAgg->isAgg ) continue;
23567c478bd9Sstevel@tonic-gate         sqliteExprCode(pParse, pAgg->pExpr);
23577c478bd9Sstevel@tonic-gate         sqliteVdbeAddOp(v, OP_AggSet, 0, i);
23587c478bd9Sstevel@tonic-gate       }
23597c478bd9Sstevel@tonic-gate       sqliteVdbeResolveLabel(v, lbl1);
23607c478bd9Sstevel@tonic-gate     }
23617c478bd9Sstevel@tonic-gate     for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
23627c478bd9Sstevel@tonic-gate       Expr *pE;
23637c478bd9Sstevel@tonic-gate       int nExpr;
23647c478bd9Sstevel@tonic-gate       FuncDef *pDef;
23657c478bd9Sstevel@tonic-gate       if( !pAgg->isAgg ) continue;
23667c478bd9Sstevel@tonic-gate       assert( pAgg->pFunc!=0 );
23677c478bd9Sstevel@tonic-gate       assert( pAgg->pFunc->xStep!=0 );
23687c478bd9Sstevel@tonic-gate       pDef = pAgg->pFunc;
23697c478bd9Sstevel@tonic-gate       pE = pAgg->pExpr;
23707c478bd9Sstevel@tonic-gate       assert( pE!=0 );
23717c478bd9Sstevel@tonic-gate       assert( pE->op==TK_AGG_FUNCTION );
23727c478bd9Sstevel@tonic-gate       nExpr = sqliteExprCodeExprList(pParse, pE->pList, pDef->includeTypes);
23737c478bd9Sstevel@tonic-gate       sqliteVdbeAddOp(v, OP_Integer, i, 0);
23747c478bd9Sstevel@tonic-gate       sqliteVdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER);
23757c478bd9Sstevel@tonic-gate     }
23767c478bd9Sstevel@tonic-gate   }
23777c478bd9Sstevel@tonic-gate 
23787c478bd9Sstevel@tonic-gate   /* End the database scan loop.
23797c478bd9Sstevel@tonic-gate   */
23807c478bd9Sstevel@tonic-gate   sqliteWhereEnd(pWInfo);
23817c478bd9Sstevel@tonic-gate 
23827c478bd9Sstevel@tonic-gate   /* If we are processing aggregates, we need to set up a second loop
23837c478bd9Sstevel@tonic-gate   ** over all of the aggregate values and process them.
23847c478bd9Sstevel@tonic-gate   */
23857c478bd9Sstevel@tonic-gate   if( isAgg ){
23867c478bd9Sstevel@tonic-gate     int endagg = sqliteVdbeMakeLabel(v);
23877c478bd9Sstevel@tonic-gate     int startagg;
23887c478bd9Sstevel@tonic-gate     startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg);
23897c478bd9Sstevel@tonic-gate     pParse->useAgg = 1;
23907c478bd9Sstevel@tonic-gate     if( pHaving ){
23917c478bd9Sstevel@tonic-gate       sqliteExprIfFalse(pParse, pHaving, startagg, 1);
23927c478bd9Sstevel@tonic-gate     }
23937c478bd9Sstevel@tonic-gate     if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
23947c478bd9Sstevel@tonic-gate                     iParm, startagg, endagg) ){
23957c478bd9Sstevel@tonic-gate       goto select_end;
23967c478bd9Sstevel@tonic-gate     }
23977c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Goto, 0, startagg);
23987c478bd9Sstevel@tonic-gate     sqliteVdbeResolveLabel(v, endagg);
23997c478bd9Sstevel@tonic-gate     sqliteVdbeAddOp(v, OP_Noop, 0, 0);
24007c478bd9Sstevel@tonic-gate     pParse->useAgg = 0;
24017c478bd9Sstevel@tonic-gate   }
24027c478bd9Sstevel@tonic-gate 
24037c478bd9Sstevel@tonic-gate   /* If there is an ORDER BY clause, then we need to sort the results
24047c478bd9Sstevel@tonic-gate   ** and send them to the callback one by one.
24057c478bd9Sstevel@tonic-gate   */
24067c478bd9Sstevel@tonic-gate   if( pOrderBy ){
24077c478bd9Sstevel@tonic-gate     generateSortTail(p, v, pEList->nExpr, eDest, iParm);
24087c478bd9Sstevel@tonic-gate   }
24097c478bd9Sstevel@tonic-gate 
24107c478bd9Sstevel@tonic-gate   /* If this was a subquery, we have now converted the subquery into a
24117c478bd9Sstevel@tonic-gate   ** temporary table.  So delete the subquery structure from the parent
24127c478bd9Sstevel@tonic-gate   ** to prevent this subquery from being evaluated again and to force the
24137c478bd9Sstevel@tonic-gate   ** the use of the temporary table.
24147c478bd9Sstevel@tonic-gate   */
24157c478bd9Sstevel@tonic-gate   if( pParent ){
24167c478bd9Sstevel@tonic-gate     assert( pParent->pSrc->nSrc>parentTab );
24177c478bd9Sstevel@tonic-gate     assert( pParent->pSrc->a[parentTab].pSelect==p );
24187c478bd9Sstevel@tonic-gate     sqliteSelectDelete(p);
24197c478bd9Sstevel@tonic-gate     pParent->pSrc->a[parentTab].pSelect = 0;
24207c478bd9Sstevel@tonic-gate   }
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate   /* The SELECT was successfully coded.   Set the return code to 0
24237c478bd9Sstevel@tonic-gate   ** to indicate no errors.
24247c478bd9Sstevel@tonic-gate   */
24257c478bd9Sstevel@tonic-gate   rc = 0;
24267c478bd9Sstevel@tonic-gate 
24277c478bd9Sstevel@tonic-gate   /* Control jumps to here if an error is encountered above, or upon
24287c478bd9Sstevel@tonic-gate   ** successful coding of the SELECT.
24297c478bd9Sstevel@tonic-gate   */
24307c478bd9Sstevel@tonic-gate select_end:
24317c478bd9Sstevel@tonic-gate   sqliteAggregateInfoReset(pParse);
24327c478bd9Sstevel@tonic-gate   return rc;
24337c478bd9Sstevel@tonic-gate }
2434